diff --git a/src/app/features/project-editor/models/project-editor.model.ts b/src/app/features/project-editor/models/project-editor.model.ts index 39d4db3..18b34a2 100644 --- a/src/app/features/project-editor/models/project-editor.model.ts +++ b/src/app/features/project-editor/models/project-editor.model.ts @@ -29,7 +29,7 @@ export interface ProjectEditorState { export const EDITOR_SECTION_BOOTSTRAP_KEYS: Partial> = { general: ['tenant', 'seo'], branding: ['branding'], - theme: ['theme'], + theme: ['theme', 'layout'], header: ['header'], footer: ['footer', 'company'], homepage: ['pages'], diff --git a/src/app/features/project-editor/sections/features-section.component.html b/src/app/features/project-editor/sections/features-section.component.html index ddeaf1a..a57ca50 100644 --- a/src/app/features/project-editor/sections/features-section.component.html +++ b/src/app/features/project-editor/sections/features-section.component.html @@ -2,15 +2,27 @@

{{ 'builder.marketplaceFeatures' | translate }}

- - - - - - - - - + + + + + + + + + +
+
+
} diff --git a/src/app/features/project-editor/sections/features-section.component.ts b/src/app/features/project-editor/sections/features-section.component.ts index c793b04..c930b20 100644 --- a/src/app/features/project-editor/sections/features-section.component.ts +++ b/src/app/features/project-editor/sections/features-section.component.ts @@ -1,11 +1,18 @@ import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { ProjectEditorFacade } from '../facade/project-editor.facade'; import { TranslatePipe } from '../../../i18n/translate.pipe'; +export interface CatalogNavigationOption { + value: 'default' | 'left-category-navigation' | 'mega-category-layout' | 'top-category-carousel'; + labelKey: string; + descKey: string; +} + @Component({ selector: 'app-project-editor-features-section', standalone: true, - imports: [TranslatePipe], + imports: [FormsModule, TranslatePipe], templateUrl: './features-section.component.html', styleUrls: ['./section.shared.scss'], changeDetection: ChangeDetectionStrategy.OnPush @@ -14,6 +21,24 @@ export class ProjectEditorFeaturesSectionComponent { private readonly facade = inject(ProjectEditorFacade); readonly bootstrap = this.facade.bootstrap; + readonly catalogNavigationOptions: CatalogNavigationOption[] = [ + { value: 'default', labelKey: 'builder.catalogNavDefault', descKey: 'builder.catalogNavDefaultDesc' }, + { value: 'left-category-navigation', labelKey: 'builder.catalogNavLeftCategory', descKey: 'builder.catalogNavLeftCategoryDesc' }, + { value: 'mega-category-layout', labelKey: 'builder.catalogNavMegaCategory', descKey: 'builder.catalogNavMegaCategoryDesc' }, + { value: 'top-category-carousel', labelKey: 'builder.catalogNavTopCarousel', descKey: 'builder.catalogNavTopCarouselDesc' }, + ]; + + catalogNavigationDescKey(mode: string | undefined): string { + return this.catalogNavigationOptions.find(option => option.value === mode)?.descKey ?? ''; + } + + updateCatalogNavigationMode(mode: string): void { + this.facade.updateBootstrap(current => ({ + ...current, + catalog: { ...current.catalog, navigationMode: mode as CatalogNavigationOption['value'] } + })); + } + toggleFeature(key: string, checked: boolean): void { this.facade.updateBootstrap(current => ({ ...current, featureFlags: { ...current.featureFlags, [key]: checked } })); } diff --git a/src/app/features/project-editor/sections/footer-section.component.html b/src/app/features/project-editor/sections/footer-section.component.html index 7b1162f..988b2ad 100644 --- a/src/app/features/project-editor/sections/footer-section.component.html +++ b/src/app/features/project-editor/sections/footer-section.component.html @@ -2,14 +2,14 @@

{{ 'builder.footer' | translate }}

- - - - - - - - + + + + + + + +
} diff --git a/src/app/features/project-editor/sections/header-section.component.html b/src/app/features/project-editor/sections/header-section.component.html index 5b441f1..fe2ad0e 100644 --- a/src/app/features/project-editor/sections/header-section.component.html +++ b/src/app/features/project-editor/sections/header-section.component.html @@ -6,6 +6,7 @@ } diff --git a/src/app/features/project-editor/sections/header-section.component.ts b/src/app/features/project-editor/sections/header-section.component.ts index 5ec4562..043bfab 100644 --- a/src/app/features/project-editor/sections/header-section.component.ts +++ b/src/app/features/project-editor/sections/header-section.component.ts @@ -15,16 +15,16 @@ import { HeaderConfig } from '../../../shared/models/config'; export class ProjectEditorHeaderSectionComponent { private readonly facade = inject(ProjectEditorFacade); readonly bootstrap = this.facade.bootstrap; - readonly items: Array<{ key: keyof HeaderConfig; label: string }> = [ - { key: 'showLogo', label: 'builder.showLogo' }, - { key: 'showSearch', label: 'builder.showSearch' }, - { key: 'showCategories', label: 'builder.showCategories' }, - { key: 'showLanguages', label: 'builder.showLanguages' }, - { key: 'showCart', label: 'builder.showCart' }, - { key: 'showProfile', label: 'builder.showProfile' }, - { key: 'showWishlist', label: 'builder.showWishlist' }, - { key: 'showCompare', label: 'builder.showCompare' }, - { key: 'showRegion', label: 'builder.showRegion' }, + readonly items: Array<{ key: keyof HeaderConfig; label: string; descKey: string }> = [ + { key: 'showLogo', label: 'builder.showLogo', descKey: 'builder.showLogoDesc' }, + { key: 'showSearch', label: 'builder.showSearch', descKey: 'builder.showSearchDesc' }, + { key: 'showCategories', label: 'builder.showCategories', descKey: 'builder.showCategoriesDesc' }, + { key: 'showLanguages', label: 'builder.showLanguages', descKey: 'builder.showLanguagesDesc' }, + { key: 'showCart', label: 'builder.showCart', descKey: 'builder.showCartDesc' }, + { key: 'showProfile', label: 'builder.showProfile', descKey: 'builder.showProfileDesc' }, + { key: 'showWishlist', label: 'builder.showWishlist', descKey: 'builder.showWishlistDesc' }, + { key: 'showCompare', label: 'builder.showCompare', descKey: 'builder.showCompareDesc' }, + { key: 'showRegion', label: 'builder.showRegion', descKey: 'builder.showRegionDesc' }, ]; toggle(key: keyof HeaderConfig, checked: boolean): void { diff --git a/src/app/features/project-editor/sections/homepage-section.component.html b/src/app/features/project-editor/sections/homepage-section.component.html index 9866977..d5c32d5 100644 --- a/src/app/features/project-editor/sections/homepage-section.component.html +++ b/src/app/features/project-editor/sections/homepage-section.component.html @@ -6,9 +6,26 @@
{{ section.id }} - - - + + +
} diff --git a/src/app/features/project-editor/sections/homepage-section.component.ts b/src/app/features/project-editor/sections/homepage-section.component.ts index 9c6e087..40225f2 100644 --- a/src/app/features/project-editor/sections/homepage-section.component.ts +++ b/src/app/features/project-editor/sections/homepage-section.component.ts @@ -4,6 +4,12 @@ import { FormsModule } from '@angular/forms'; import { ProjectEditorFacade } from '../facade/project-editor.facade'; import { TranslatePipe } from '../../../i18n/translate.pipe'; +export interface LayoutStrategyOption { + value: 'stack' | 'grid' | 'hero' | 'carousel' | 'split'; + labelKey: string; + descKey: string; +} + @Component({ selector: 'app-project-editor-homepage-section', standalone: true, @@ -17,6 +23,18 @@ export class ProjectEditorHomepageSectionComponent { readonly homePage = this.facade.homepagePage; readonly sections = computed(() => [...(this.homePage()?.sections ?? [])].sort((a, b) => a.order - b.order)); + readonly layoutStrategyOptions: LayoutStrategyOption[] = [ + { value: 'stack', labelKey: 'builder.layoutStrategyStack', descKey: 'builder.layoutStrategyStackDesc' }, + { value: 'grid', labelKey: 'builder.layoutStrategyGrid', descKey: 'builder.layoutStrategyGridDesc' }, + { value: 'hero', labelKey: 'builder.layoutStrategyHero', descKey: 'builder.layoutStrategyHeroDesc' }, + { value: 'carousel', labelKey: 'builder.layoutStrategyCarousel', descKey: 'builder.layoutStrategyCarouselDesc' }, + { value: 'split', labelKey: 'builder.layoutStrategySplit', descKey: 'builder.layoutStrategySplitDesc' }, + ]; + + layoutStrategyDescKey(strategy: string | undefined): string { + return this.layoutStrategyOptions.find(option => option.value === strategy)?.descKey ?? ''; + } + drop(event: CdkDragDrop): void { const sections = [...this.sections()]; moveItemInArray(sections, event.previousIndex, event.currentIndex); diff --git a/src/app/features/project-editor/sections/languages-section.component.html b/src/app/features/project-editor/sections/languages-section.component.html index a31b5a0..57e317a 100644 --- a/src/app/features/project-editor/sections/languages-section.component.html +++ b/src/app/features/project-editor/sections/languages-section.component.html @@ -2,6 +2,7 @@

{{ 'builder.languagesTab' | translate }}

+ {{ 'builder.languagesTabDesc' | translate }}
+ {{ 'builder.newLanguageDesc' | translate }}
@for (code of locales(); track code) { diff --git a/src/app/features/project-editor/sections/navigation-section.component.html b/src/app/features/project-editor/sections/navigation-section.component.html index c589e55..51011c3 100644 --- a/src/app/features/project-editor/sections/navigation-section.component.html +++ b/src/app/features/project-editor/sections/navigation-section.component.html @@ -16,9 +16,9 @@
- - - + + +
} @@ -44,9 +44,9 @@
- - - + + +
} diff --git a/src/app/features/project-editor/sections/theme-section.component.html b/src/app/features/project-editor/sections/theme-section.component.html index 93e4fba..8632ef6 100644 --- a/src/app/features/project-editor/sections/theme-section.component.html +++ b/src/app/features/project-editor/sections/theme-section.component.html @@ -2,14 +2,34 @@

{{ 'builder.theme' | translate }}

- - - - - - - - + + + + + + + + + +
} diff --git a/src/app/features/project-editor/sections/theme-section.component.ts b/src/app/features/project-editor/sections/theme-section.component.ts index 3d92a44..b087948 100644 --- a/src/app/features/project-editor/sections/theme-section.component.ts +++ b/src/app/features/project-editor/sections/theme-section.component.ts @@ -2,7 +2,19 @@ import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ProjectEditorFacade } from '../facade/project-editor.facade'; import { TranslatePipe } from '../../../i18n/translate.pipe'; -import { ThemePaletteConfig } from '../../../shared/models/config'; +import { PlatformLayoutType, ThemePaletteConfig } from '../../../shared/models/config'; + +export interface ThemeModeOption { + value: 'light' | 'dark' | 'system'; + labelKey: string; + descKey: string; +} + +export interface SiteLayoutOption { + value: PlatformLayoutType; + labelKey: string; + descKey: string; +} @Component({ selector: 'app-project-editor-theme-section', @@ -16,10 +28,45 @@ export class ProjectEditorThemeSectionComponent { private readonly facade = inject(ProjectEditorFacade); readonly bootstrap = this.facade.bootstrap; + readonly themeModeOptions: ThemeModeOption[] = [ + { value: 'light', labelKey: 'builder.themeModeLight', descKey: 'builder.themeModeLightDesc' }, + { value: 'dark', labelKey: 'builder.themeModeDark', descKey: 'builder.themeModeDarkDesc' }, + { value: 'system', labelKey: 'builder.themeModeSystem', descKey: 'builder.themeModeSystemDesc' }, + ]; + + readonly siteLayoutOptions: SiteLayoutOption[] = [ + { value: 'default', labelKey: 'builder.siteLayoutDefault', descKey: 'builder.siteLayoutDefaultDesc' }, + { value: 'sidebar-left', labelKey: 'builder.siteLayoutSidebarLeft', descKey: 'builder.siteLayoutSidebarLeftDesc' }, + { value: 'carousel-home', labelKey: 'builder.siteLayoutCarouselHome', descKey: 'builder.siteLayoutCarouselHomeDesc' }, + { value: 'minimal', labelKey: 'builder.siteLayoutMinimal', descKey: 'builder.siteLayoutMinimalDesc' }, + ]; + updatePalette(key: K, value: string): void { this.facade.updateBootstrap(current => ({ ...current, theme: { ...current.theme, palette: { ...current.theme.palette, [key]: value } } })); } + + updateThemeMode(mode: string): void { + this.facade.updateBootstrap(current => ({ + ...current, + theme: { ...current.theme, mode: mode as 'light' | 'dark' | 'system' } + })); + } + + updateSiteLayout(type: string): void { + this.facade.updateBootstrap(current => ({ + ...current, + layout: { ...current.layout, type: type as PlatformLayoutType } + })); + } + + themeModeDescKey(mode: string): string { + return this.themeModeOptions.find(option => option.value === mode)?.descKey ?? ''; + } + + siteLayoutDescKey(type: string): string { + return this.siteLayoutOptions.find(option => option.value === type)?.descKey ?? ''; + } } diff --git a/src/app/features/project-editor/sections/widgets-section.component.html b/src/app/features/project-editor/sections/widgets-section.component.html index 406501c..992f361 100644 --- a/src/app/features/project-editor/sections/widgets-section.component.html +++ b/src/app/features/project-editor/sections/widgets-section.component.html @@ -8,31 +8,32 @@ @switch (entry.widget.type) { @case ('hero') {
- - - - + + + +
} @case ('categories') {
- - + +
} @case ('product-collection') {
- - - - - - + + + + + +
} @default { }