import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ProjectEditorFacade } from '../facade/project-editor.facade'; import { TranslatePipe } from '../../../i18n/translate.pipe'; import { TranslateService } from '../../../i18n/translate.service'; import { InputComponent } from '../../../shared/ui/input/input.component'; import { FormFieldComponent } from '../../../shared/ui/form-field/form-field.component'; import { SectionCardComponent } from '../../../shared/ui/section-card/section-card.component'; import { KeyValueEditorComponent } from '../../../shared/ui/key-value-editor/key-value-editor.component'; import { ImageFieldComponent } from '../../../shared/ui/image-field/image-field.component'; import { FooterPaymentIconConfig, FooterSocialLinkConfig } from '../../../shared/models/config'; import { isValidHttpUrl } from '../schema/validators/primitives'; @Component({ selector: 'app-project-editor-footer-section', standalone: true, imports: [ FormsModule, TranslatePipe, InputComponent, FormFieldComponent, SectionCardComponent, KeyValueEditorComponent, ImageFieldComponent ], templateUrl: './footer-section.component.html', styleUrls: ['./section.shared.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ProjectEditorFooterSectionComponent { private readonly facade = inject(ProjectEditorFacade); private readonly translate = inject(TranslateService); readonly bootstrap = this.facade.bootstrap; readonly fieldError = (key: string): string | null => { const messageKey = this.facade.fieldError(key); return messageKey ? this.translate.t(messageKey) : null; }; readonly staticPagesValue = computed(() => (this.bootstrap()?.footer?.staticPageKeys ?? this.bootstrap()?.footer?.legalPageKeys ?? []).join(', ')); readonly copyrightValue = computed(() => { const value = this.bootstrap()?.footer?.copyrightText; return typeof value === 'string' ? value : ''; }); readonly paymentIconRows = computed(() => this.bootstrap()?.footer?.paymentIcons ?? []); readonly socialLinkRows = computed(() => this.bootstrap()?.footer?.socialLinks ?? []); readonly createPaymentIconRow = (): FooterPaymentIconConfig => ({ src: '', alt: '' }); readonly createSocialLinkRow = (): FooterSocialLinkConfig => { const index = (this.bootstrap()?.footer?.socialLinks?.length ?? 0) + 1; return { id: `social-${index}`, label: '', url: '' }; }; updateCompanyName(value: string): void { this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, companyName: value } })); } updateAddress(value: string): void { this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, address: { ...current.company.address, street: value } } })); } updatePhone(value: string): void { this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, contacts: { ...current.company.contacts, phone: value } }, branding: { ...current.branding, supportPhone: value } })); } updateEmail(value: string): void { this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, contacts: { ...current.company.contacts, email: value } }, branding: { ...current.branding, supportEmail: value } })); } updateCopyright(value: string): void { this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, copyrightText: value } })); } updateStaticPages(value: string): void { const staticPageKeys = value.split(',').map(item => item.trim()).filter(Boolean); this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, staticPageKeys, legalPageKeys: staticPageKeys } })); } updateLogo(value: string): void { this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, logoUrl: value } })); } onPaymentIconsChange(rows: FooterPaymentIconConfig[]): void { this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, paymentIcons: rows } })); } updatePaymentIconSrc(index: number, src: string): void { const rows = this.paymentIconRows().map((row, i) => (i === index ? { ...row, src } : row)); this.onPaymentIconsChange(rows); } updatePaymentIconAlt(index: number, alt: string): void { const rows = this.paymentIconRows().map((row, i) => (i === index ? { ...row, alt } : row)); this.onPaymentIconsChange(rows); } onSocialLinksChange(rows: FooterSocialLinkConfig[]): void { this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, socialLinks: rows } })); } updateSocialLinkLabel(index: number, label: string): void { const rows = this.socialLinkRows().map((row, i) => (i === index ? { ...row, label } : row)); this.onSocialLinksChange(rows); } updateSocialLinkUrl(index: number, url: string): void { const rows = this.socialLinkRows().map((row, i) => (i === index ? { ...row, url } : row)); this.onSocialLinksChange(rows); } isValidUrl(url: string): boolean { return !url || isValidHttpUrl(url); } }