From fc4784d54e1dda8b23334be4e59df492d6459fc2 Mon Sep 17 00:00:00 2001 From: arolleaguekeng Date: Mon, 26 Jan 2026 02:16:03 +0100 Subject: [PATCH 1/5] refactor typography selection UI to remove preview panel and popular list components, add formatted display for project summary fields, and upgrade Gemini model to 3-flash-preview Remove typography-preview-panel and popular-typography-list components. Refactor typography-custom-creator to full-height layout with integrated search and remove custom typography list display. Update project-summary to use computed properties for formatting object-based fields (type, scope, budget, targets) with fall --- .../services/BandIdentity/branding.service.ts | 6 +- .../project-summary/project-summary.html | 8 +- .../project-summary/project-summary.ts | 42 ++++++ .../popular-typography-list.css | 0 .../popular-typography-list.html | 9 -- .../popular-typography-list.ts | 41 ----- .../typography-custom-creator.html | 115 ++++++-------- .../typography-custom-creator.ts | 18 --- .../typography-generated-list.ts | 3 +- .../typography-preview-panel.css | 1 - .../typography-preview-panel.html | 49 ------ .../typography-preview-panel.ts | 26 ---- .../typography-preview.html | 126 ++++++++-------- .../typography-selection.html | 27 +--- .../typography-selection.ts | 140 ++++++++---------- .../typography-tabs/typography-tabs.ts | 2 +- .../pages/create-project/create-project.html | 2 +- 17 files changed, 231 insertions(+), 384 deletions(-) delete mode 100644 apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.css delete mode 100644 apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.html delete mode 100644 apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.ts delete mode 100644 apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.css delete mode 100644 apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.html delete mode 100644 apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.ts diff --git a/apps/api/api/services/BandIdentity/branding.service.ts b/apps/api/api/services/BandIdentity/branding.service.ts index bfa4cb955..d0d6269a1 100644 --- a/apps/api/api/services/BandIdentity/branding.service.ts +++ b/apps/api/api/services/BandIdentity/branding.service.ts @@ -37,7 +37,7 @@ export class BrandingService extends GenericService { // Temperature modérée pour équilibrer créativité et cohérence private static readonly LOGO_LLM_CONFIG = { provider: LLMProvider.GEMINI, - modelName: 'gemini-2.0-flash', + modelName: 'gemini-3-flash-preview', llmOptions: { maxOutputTokens: 3500, temperature: 0.4, // Équilibre entre créativité et cohérence @@ -1744,7 +1744,7 @@ export class BrandingService extends GenericService { */ private generateReadmeContent(project: any, extension: string, fileCount: number): string { return `Logo Package - ${project.name} - + Project: ${project.name} Description: ${project.description || 'No description available'} Format: ${extension.toUpperCase()} @@ -1775,7 +1775,7 @@ Features: Variations: - light-background: Optimized for light backgrounds -- dark-background: Optimized for dark backgrounds +- dark-background: Optimized for dark backgrounds - monochrome: Single color version ${ diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/project-summary/project-summary.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/project-summary/project-summary.html index e36369ddd..e018a611a 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/project-summary/project-summary.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/project-summary/project-summary.html @@ -36,7 +36,7 @@

{{ 'dashboard.projectSummary.fields.type' | translate }}: - {{ project().type }} + {{ formattedProjectType() }}

@@ -55,19 +55,19 @@

{{ 'dashboard.projectSummary.fields.scope' | translate }}: - {{ project().scope }} + {{ formattedScope() }}

{{ 'dashboard.projectSummary.fields.budget' | translate }}: - {{ project().budgetIntervals }} + {{ formattedBudget() }}

{{ 'dashboard.projectSummary.fields.target' | translate }}: - {{ project().targets }} + {{ formattedTargets() }}

diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/project-summary/project-summary.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/project-summary/project-summary.ts index ebae28f8f..722462881 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/project-summary/project-summary.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/project-summary/project-summary.ts @@ -54,6 +54,48 @@ export class ProjectSummaryComponent { return requiredPolicies && betaRequired; }); + // Computed properties for formatted display + protected readonly formattedProjectType = computed(() => { + const type = this.project().type; + if (typeof type === 'object' && type !== null) { + return (type as any).name || JSON.stringify(type); + } + return type || 'Non spécifié'; + }); + + protected readonly formattedScope = computed(() => { + const scope = this.project().scope; + if (typeof scope === 'object' && scope !== null) { + return (scope as any).name || JSON.stringify(scope); + } + return scope || 'Non spécifié'; + }); + + protected readonly formattedTargets = computed(() => { + const targets = this.project().targets; + if (typeof targets === 'object' && targets !== null) { + if (Array.isArray(targets)) { + return targets + .map((t) => (typeof t === 'object' ? (t as any).name || JSON.stringify(t) : t)) + .join(', '); + } + return (targets as any).name || JSON.stringify(targets); + } + return targets || 'Non spécifié'; + }); + + protected readonly formattedBudget = computed(() => { + const budget = this.project().budgetIntervals; + if (typeof budget === 'object' && budget !== null) { + const budgetObj = budget as any; + if (budgetObj.min && budgetObj.max) { + return `${budgetObj.min} - ${budgetObj.max}`; + } + return budgetObj.name || JSON.stringify(budget); + } + return budget || 'Non spécifié'; + }); + protected getSelectedLogo(): LogoModel | undefined { const logo = this.logos().find((logo) => logo.id === this.selectedLogo()); console.log('Selected logo', logo); diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.css b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.html deleted file mode 100644 index 84a84ed10..000000000 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.html +++ /dev/null @@ -1,9 +0,0 @@ -
- @for (typography of typographies; track trackTypography($index, typography)) { - - } -
diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.ts deleted file mode 100644 index 01b54c6c6..000000000 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/popular-typography-list/popular-typography-list.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Component, Input, Output, EventEmitter } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { TypographyModel } from '../../../../../models/brand-identity.model'; -import { TypographyPreview } from '../../../../../../../shared/services/typography.service'; -import { TypographyCardComponent } from '../typography-card/typography-card'; - -@Component({ - selector: 'app-popular-typography-list', - standalone: true, - imports: [CommonModule, TypographyCardComponent], - templateUrl: './popular-typography-list.html', - styleUrls: ['./popular-typography-list.css'], -}) -export class PopularTypographyListComponent { - @Input() typographies: TypographyPreview[] = []; - @Input() selectedTypographyId: string | null = null; - @Output() typographySelected = new EventEmitter(); - - onTypographySelected(typography: TypographyModel | TypographyPreview): void { - // Convert TypographyModel to TypographyPreview if needed - if ('category' in typography && 'isLoaded' in typography) { - // It's already a TypographyPreview - this.typographySelected.emit(typography as TypographyPreview); - } else { - // It's a TypographyModel, convert to TypographyPreview - const typographyPreview: TypographyPreview = { - id: typography.id, - name: typography.name, - primaryFont: typography.primaryFont, - secondaryFont: typography.secondaryFont, - category: 'popular', - isLoaded: true, - }; - this.typographySelected.emit(typographyPreview); - } - } - - trackTypography(index: number, typography: TypographyPreview): string { - return typography.id; - } -} diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-custom-creator/typography-custom-creator.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-custom-creator/typography-custom-creator.html index a4eaf4d3c..3a4eb4e4e 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-custom-creator/typography-custom-creator.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-custom-creator/typography-custom-creator.html @@ -1,36 +1,9 @@ -
- - @if (customTypographies.length > 0) { -
-

- {{ 'dashboard.typographySelection.custom.title' | translate }} -

-
- @for (typography of customTypographies; track trackCustomTypography($index, typography)) { -
-
-
- {{ typography.primaryFont }} -
-
+ {{ typography.secondaryFont }}
-
-
-
- } -
-
- } - +
-
-

+
+

{{ 'dashboard.typographySelection.custom.createNew' | translate }}

- - - - -
-
-
+ +
+ +
+
{{ 'dashboard.typographySelection.custom.primaryFont' | translate }}
-
+
{{ selectedPrimaryFont || ('dashboard.typographySelection.custom.notSelected' | translate) }}
-
-
+ + +
+
{{ 'dashboard.typographySelection.custom.secondaryFont' | translate }}
-
+
{{ selectedSecondaryFont || ('dashboard.typographySelection.custom.notSelected' | translate) @@ -81,26 +66,16 @@

- - + +
+
Search and select fonts to apply:
+ +
diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-custom-creator/typography-custom-creator.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-custom-creator/typography-custom-creator.ts index 8cf8744f3..426d7fd25 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-custom-creator/typography-custom-creator.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-custom-creator/typography-custom-creator.ts @@ -1,7 +1,6 @@ import { Component, Input, Output, EventEmitter } from '@angular/core'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; -import { TypographyModel } from '../../../../../models/brand-identity.model'; import { TypographyPreview, GoogleFont, @@ -16,22 +15,13 @@ import { TypographySearchComponent } from '../typography-search/typography-searc styleUrls: ['./typography-custom-creator.css'], }) export class TypographyCustomCreatorComponent { - @Input() customTypographies: TypographyPreview[] = []; - @Input() selectedCustomTypography: TypographyPreview | null = null; @Input() selectedPrimaryFont = ''; @Input() selectedSecondaryFont = ''; @Input() searchResults: GoogleFont[] = []; @Input() isSearching = false; - @Input() canCreateCustom = false; - @Output() customTypographySelected = new EventEmitter(); @Output() searchInput = new EventEmitter(); @Output() fontSelected = new EventEmitter<{ font: GoogleFont; type: 'primary' | 'secondary' }>(); - @Output() customTypographyCreated = new EventEmitter(); - - onCustomTypographySelected(typography: TypographyPreview): void { - this.customTypographySelected.emit(typography); - } onSearchInput(query: string): void { this.searchInput.emit(query); @@ -40,12 +30,4 @@ export class TypographyCustomCreatorComponent { onFontSelected(event: { font: GoogleFont; type: 'primary' | 'secondary' }): void { this.fontSelected.emit(event); } - - onCreateCustomTypography(): void { - this.customTypographyCreated.emit(); - } - - trackCustomTypography(index: number, typography: TypographyPreview): string { - return typography.id; - } } diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-generated-list/typography-generated-list.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-generated-list/typography-generated-list.ts index fef76ec7e..9fecfada0 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-generated-list/typography-generated-list.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-generated-list/typography-generated-list.ts @@ -2,13 +2,12 @@ import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges } from import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { TypographyModel } from '../../../../../models/brand-identity.model'; -import { CarouselComponent } from '../../../../../../../shared/components/carousel/carousel.component'; import { TypographyCardComponent } from '../typography-card/typography-card'; @Component({ selector: 'app-typography-generated-list', standalone: true, - imports: [CommonModule, TranslateModule, CarouselComponent, TypographyCardComponent], + imports: [CommonModule, TranslateModule, TypographyCardComponent], templateUrl: './typography-generated-list.html', styleUrls: ['./typography-generated-list.css'], }) diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.css b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.css deleted file mode 100644 index a94507019..000000000 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.css +++ /dev/null @@ -1 +0,0 @@ -/* Typography Preview Panel Component Styles */ diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.html deleted file mode 100644 index 756051bd8..000000000 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.html +++ /dev/null @@ -1,49 +0,0 @@ -
-
- -
-
- -
-

- {{ previewText() }} -

-

- {{ 'dashboard.typographySelection.preview.heroSubtitle' | translate }} -

-
- - -
- - - -
- "{{ 'dashboard.typographySelection.preview.quote' | translate }}" -
- - — {{ 'dashboard.typographySelection.preview.author' | translate }} - -
-
-
-
-
diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.ts deleted file mode 100644 index 96605f350..000000000 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview-panel/typography-preview-panel.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Component, Input, signal } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { TranslateModule } from '@ngx-translate/core'; -import { TypographyModel } from '../../../../../models/brand-identity.model'; - -@Component({ - selector: 'app-typography-preview-panel', - standalone: true, - imports: [CommonModule, TranslateModule], - templateUrl: './typography-preview-panel.html', - styleUrls: ['./typography-preview-panel.css'], -}) -export class TypographyPreviewPanelComponent { - @Input() typography: TypographyModel | null = null; - @Input() previewText = signal('Your Brand Name'); - @Input() selectedPrimaryFont = ''; - @Input() selectedSecondaryFont = ''; - - get primaryFont(): string { - return this.typography?.primaryFont || this.selectedPrimaryFont || 'inherit'; - } - - get secondaryFont(): string { - return this.typography?.secondaryFont || this.selectedSecondaryFont || 'inherit'; - } -} diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview/typography-preview.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview/typography-preview.html index b339c679e..64d1d3198 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview/typography-preview.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-preview/typography-preview.html @@ -1,67 +1,71 @@ -@if (typography) { +
-
- -
-

- {{ previewText() }} -

-

- {{ 'dashboard.typographySelection.preview.heroSubtitle' | translate }} -

-
- - -
- - - -
- "{{ 'dashboard.typographySelection.preview.quote' | translate }}" -
- - — {{ 'dashboard.typographySelection.preview.author' | translate }} - -
-
-
-} @else { -
-
+ @if (typography) {
- - - +
+ +
+

+ {{ previewText() }} +

+

+ {{ 'dashboard.typographySelection.preview.heroSubtitle' | translate }} +

+
+ + +
+ + + +
+ "{{ 'dashboard.typographySelection.preview.quote' | translate }}" +
+ + — {{ 'dashboard.typographySelection.preview.author' | translate }} + +
+
+
+ } @else { +
+
+
+ + + +
+

+ {{ 'dashboard.typographySelection.selectToPreview' | translate }} +

+

Select fonts to see the preview

+
-

- {{ 'dashboard.typographySelection.selectToPreview' | translate }} -

-

- Click any font card on the left to see the magic happen -

-
+ }
-} +
diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.html index 7e47f6036..f1fb09b7e 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.html @@ -102,42 +102,25 @@

(typographySelected)="onTypographySelected($event)" (regenerateRequest)="onRegenerateTypographies()" > - } - @else if (activeTab() === 'custom') { + } @else if (activeTab() === 'custom') { }

- @if (activeTab() === 'generated' || activeTab() === 'popular') { - - - } @else if (activeTab() === 'custom') { - - - } +
diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.ts index ec1e2d58d..3fd1ac91b 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.ts @@ -22,7 +22,6 @@ import { ProjectService } from '../../../../services/project.service'; import { debounceTime, distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators'; import { Subject, of } from 'rxjs'; import { TypographyPreviewComponent } from './typography-preview/typography-preview'; -import { PopularTypographyListComponent } from './popular-typography-list/popular-typography-list'; import { ProjectModel } from '../../../../models/project.model'; import { BrandingService } from '../../../../services/ai-agents/branding.service'; @@ -30,7 +29,6 @@ import { BrandingService } from '../../../../services/ai-agents/branding.service import { TypographyTabsComponent, TypographyTab } from './typography-tabs/typography-tabs'; import { TypographyGeneratedListComponent } from './typography-generated-list/typography-generated-list'; import { TypographyCustomCreatorComponent } from './typography-custom-creator/typography-custom-creator'; -import { TypographyPreviewPanelComponent } from './typography-preview-panel/typography-preview-panel'; @Component({ selector: 'app-typography-selection', @@ -40,11 +38,9 @@ import { TypographyPreviewPanelComponent } from './typography-preview-panel/typo FormsModule, TranslateModule, TypographyPreviewComponent, - PopularTypographyListComponent, TypographyTabsComponent, TypographyGeneratedListComponent, TypographyCustomCreatorComponent, - TypographyPreviewPanelComponent, ], templateUrl: './typography-selection.html', styleUrls: ['./typography-selection.css'], @@ -73,11 +69,12 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { protected isGenerating = signal(false); protected typographyModels = signal([]); protected selectedTypographyId = signal(null); - protected popularTypographies = signal([]); - protected customTypographies = signal([]); - protected selectedCustomTypography = signal(null); + + // Custom Selection Signals protected selectedPrimaryFont = signal(''); protected selectedSecondaryFont = signal(''); + + // Search Signals protected searchResults = signal([]); protected isSearching = signal(false); protected searchQuery = signal(''); @@ -86,43 +83,43 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { // Computed properties protected hasGeneratedTypographies = computed(() => this.typographyModels().length > 0); - protected canCreateCustom = computed( - () => this.selectedPrimaryFont().length > 0 && this.selectedSecondaryFont().length > 0, - ); + protected canContinue = computed(() => { - return ( - this.selectedTypographyId() !== null || - this.selectedCustomTypography() !== null || - (this.selectedPrimaryFont() && this.selectedSecondaryFont()) - ); + if (this.activeTab() === 'generated') { + return this.selectedTypographyId() !== null; + } + // For custom tab, we need both fonts selected + return this.selectedPrimaryFont().length > 0 && this.selectedSecondaryFont().length > 0; }); - protected currentSelectedTypography = computed(() => - this.typographyModels().find((t) => t.id === this.selectedTypographyId()), - ); - protected customPreviewTypography = computed(() => { - if (this.selectedCustomTypography()) { + protected currentSelectedTypography = computed(() => { + if (this.activeTab() === 'generated') { + return this.typographyModels().find( + (t: TypographyModel) => t.id === this.selectedTypographyId(), + ); + } + + // For custom tab, return a live preview object + if (this.selectedPrimaryFont() || this.selectedSecondaryFont()) { return { - id: this.selectedCustomTypography()!.id, - name: this.selectedCustomTypography()!.name, - primaryFont: this.selectedCustomTypography()!.primaryFont, - secondaryFont: this.selectedCustomTypography()!.secondaryFont, - description: '', + id: 'custom-preview', + name: 'Custom Selection', + primaryFont: this.selectedPrimaryFont() || 'Inter', // Fallback for preview + secondaryFont: this.selectedSecondaryFont() || 'Inter', // Fallback for preview + description: 'Your custom font combination', } as TypographyModel; } - return { - id: 'preview', - name: 'Custom Preview', - primaryFont: this.selectedPrimaryFont(), - secondaryFont: this.selectedSecondaryFont(), - description: 'Preview of your custom selection', - } as TypographyModel; + return null; }); // Event handlers for new template protected onTabChanged(tab: TypographyTab): void { this.activeTab.set(tab); + // If switching to generated, ensure something is selected if possible + if (tab === 'generated' && !this.selectedTypographyId() && this.typographyModels().length > 0) { + this.selectedTypographyId.set(this.typographyModels()[0].id); + } } protected onTypographySelected(typography: TypographyModel): void { @@ -130,18 +127,6 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { this.typographySelected.emit(typography); } - protected onPopularTypographySelected(typography: TypographyPreview): void { - const typographyModel: TypographyModel = { - id: typography.id, - name: typography.name, - primaryFont: typography.primaryFont, - secondaryFont: typography.secondaryFont, - description: `Popular typography: ${typography.name}`, - }; - this.selectedTypographyId.set(typography.id); - this.typographySelected.emit(typographyModel); - } - protected onRegenerateTypographies(): void { this.regenerateTypographies(); } @@ -157,7 +142,9 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { } protected saveAsDraft(): void { - const selectedTypography = this.currentSelectedTypography() || this.customPreviewTypography(); + const selectedTypography = this.currentSelectedTypography(); + if (!selectedTypography) return; + const draftData: Partial = { analysisResultModel: { ...this.project.analysisResultModel, @@ -172,13 +159,40 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { protected continueToNext(): void { if (this.canContinue()) { - const selectedTypography = this.currentSelectedTypography() || this.customPreviewTypography(); + const selectedTypography = this.currentSelectedTypography(); + if (!selectedTypography) return; + + // For custom typography, add it to the generatedTypography list so it can be found in project-summary + let updatedGeneratedTypography = + this.project.analysisResultModel?.branding?.generatedTypography || []; + + if (this.activeTab() === 'custom' && selectedTypography.id === 'custom-preview') { + // Create a proper custom typography with unique ID + const customTypography: TypographyModel = { + ...selectedTypography, + id: `custom-${Date.now()}`, // Unique ID for custom typography + }; + + // Add custom typography to the list if not already present + const existingCustomIndex = updatedGeneratedTypography.findIndex((t) => + t.id.startsWith('custom-'), + ); + if (existingCustomIndex >= 0) { + updatedGeneratedTypography[existingCustomIndex] = customTypography; + } else { + updatedGeneratedTypography = [...updatedGeneratedTypography, customTypography]; + } + + selectedTypography.id = customTypography.id; // Update the selected typography ID + } + const projectData: Partial = { analysisResultModel: { ...this.project.analysisResultModel, branding: { ...this.project.analysisResultModel?.branding, typography: selectedTypography, + generatedTypography: updatedGeneratedTypography, }, }, }; @@ -187,11 +201,6 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { } } - protected selectCustomTypography(typography: TypographyPreview): void { - this.selectedCustomTypography.set(typography); - this.selectedTypographyId.set(null); - } - protected onSearchInput(query: string): void { this.searchQuery.set(query); this.searchSubject.next(query); @@ -207,29 +216,9 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { this.typographyService.loadGoogleFont(font.family); } - protected createCustomTypography(): void { - if (!this.canCreateCustom()) return; - - const customTypography: TypographyPreview = { - id: `custom-${Date.now()}`, - name: `${this.selectedPrimaryFont()} + ${this.selectedSecondaryFont()}`, - primaryFont: this.selectedPrimaryFont(), - secondaryFont: this.selectedSecondaryFont(), - category: 'custom', - isLoaded: true, - }; - - const current = this.customTypographies(); - this.customTypographies.set([...current, customTypography]); - this.selectedCustomTypography.set(customTypography); - this.selectedPrimaryFont.set(''); - this.selectedSecondaryFont.set(''); - } - ngOnInit(): void { this.initializeTypographies(); this.setupSearch(); - this.loadPopularTypographies(); } ngOnDestroy(): void { @@ -281,14 +270,13 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { this.typographyModels.set(mockTypographies); this.isGenerating.set(false); + // Auto-select first item + if (mockTypographies.length > 0) { + this.selectedTypographyId.set(mockTypographies[0].id); + } }, 2000); } - private loadPopularTypographies(): void { - const popular = this.typographyService.getPopularTypographies(); - this.popularTypographies.set(popular); - } - private setupSearch(): void { this.searchSubject .pipe( diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-tabs/typography-tabs.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-tabs/typography-tabs.ts index de3d0d02e..e9387fe00 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-tabs/typography-tabs.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-tabs/typography-tabs.ts @@ -2,7 +2,7 @@ import { Component, Input, Output, EventEmitter } from '@angular/core'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; -export type TypographyTab = 'generated' | 'popular' | 'custom'; +export type TypographyTab = 'generated' | 'custom'; @Component({ selector: 'app-typography-tabs', diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.html index 01673fd34..8b80c874a 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.html @@ -86,7 +86,7 @@

[project]="project()" [selectedLogo]="project().analysisResultModel.branding.logo.id || ''" [selectedColor]="project().analysisResultModel.branding.colors.id || ''" - [selectedTypography]="project().analysisResultModel.branding.typography.id || ''" + [selectedTypography]="project().analysisResultModel?.branding?.typography?.id || ''" [logos]="project().analysisResultModel.branding.generatedLogos || []" [colorPalettes]="project().analysisResultModel.branding.generatedColors || []" [typographyOptions]="project().analysisResultModel.branding.generatedTypography || []" From d65d9ddc121913bd6cf4913def7c42d524975800 Mon Sep 17 00:00:00 2001 From: arolleaguekeng Date: Mon, 26 Jan 2026 02:35:40 +0100 Subject: [PATCH 2/5] reduce Gemini token limit from 3500 to 1500, remove deprecated SVG icon extractor service, and refactor logo variations UI to auto-select all 3 generated variations with success state Remove svgIconExtractor.service.ts as icon extraction is now handled directly by AI. Update branding.service.ts to reduce maxOutputTokens from 3500 to 1500. Refactor logo-variations component to eliminate manual selection - automatically select all 3 generated variations (lightBackground, darkBackground, monochrome --- .../services/BandIdentity/branding.service.ts | 2 +- .../BandIdentity/svgIconExtractor.service.ts | 136 ------------ .../logo-variations/logo-variations.html | 203 +++++++++--------- .../logo-variations/logo-variations.ts | 181 ++++------------ .../typography-selection.html | 47 ---- .../typography-selection.ts | 94 ++++---- .../pages/create-project/create-project.html | 3 +- .../pages/create-project/create-project.ts | 26 ++- 8 files changed, 208 insertions(+), 484 deletions(-) delete mode 100644 apps/api/api/services/BandIdentity/svgIconExtractor.service.ts diff --git a/apps/api/api/services/BandIdentity/branding.service.ts b/apps/api/api/services/BandIdentity/branding.service.ts index d0d6269a1..5f4baf647 100644 --- a/apps/api/api/services/BandIdentity/branding.service.ts +++ b/apps/api/api/services/BandIdentity/branding.service.ts @@ -39,7 +39,7 @@ export class BrandingService extends GenericService { provider: LLMProvider.GEMINI, modelName: 'gemini-3-flash-preview', llmOptions: { - maxOutputTokens: 3500, + maxOutputTokens: 1500, temperature: 0.4, // Équilibre entre créativité et cohérence topP: 0.9, topK: 55, diff --git a/apps/api/api/services/BandIdentity/svgIconExtractor.service.ts b/apps/api/api/services/BandIdentity/svgIconExtractor.service.ts deleted file mode 100644 index a2d574e04..000000000 --- a/apps/api/api/services/BandIdentity/svgIconExtractor.service.ts +++ /dev/null @@ -1,136 +0,0 @@ -import logger from '../../config/logger'; - -/** - * Service pour traiter les logos et variations SVG - * Maintenant que l'IA génère directement les icônes séparément, ce service se concentre sur les variations - */ -export class SvgIconExtractorService { - /** - * @deprecated Cette méthode n'est plus nécessaire car l'IA génère directement les icônes - * Conservée pour compatibilité descendante - */ - static extractIcon(logoSvg: string): { - fullLogo: string; - iconOnly: string; - } { - logger.warn('extractIcon is deprecated - AI now generates icons directly'); - return { - fullLogo: logoSvg, - iconOnly: logoSvg, - }; - } - - /** - * @deprecated Cette méthode n'est plus nécessaire car l'IA génère directement les icônes - * Conservée pour compatibilité descendante - */ - static extractIconsFromLogos(logos: any[]): any[] { - logger.warn('extractIconsFromLogos is deprecated - AI now generates icons directly'); - return logos; - } - - /** - * Génère les variations d'un logo avec et sans texte - * @param logoSvg - SVG du logo complet - * @param variations - Variations générées par l'IA - * @returns Variations avec texte et sans texte - */ - static generateVariationsWithText( - logoSvg: string, - variations: { - lightBackground?: string; - darkBackground?: string; - monochrome?: string; - } - ): { - withText: { - lightBackground?: string; - darkBackground?: string; - monochrome?: string; - }; - iconOnly: { - lightBackground?: string; - darkBackground?: string; - monochrome?: string; - }; - } { - logger.info('Generating variations with and without text'); - - const result = { - withText: {} as any, - iconOnly: {} as any, - }; - - // Pour chaque variation, créer une version avec texte et une sans texte - Object.entries(variations).forEach(([key, variationSvg]) => { - if (variationSvg) { - // Version avec texte : adapter le logo complet aux couleurs de la variation - result.withText[key] = this.adaptLogoColors(logoSvg, variationSvg); - // Version sans texte : utiliser la variation telle quelle (déjà sans texte) - result.iconOnly[key] = variationSvg; - } - }); - - return result; - } - - /** - * Adapte les couleurs du logo complet selon une variation - * @param fullLogoSvg - Logo complet avec texte - * @param variationSvg - Variation avec les bonnes couleurs - * @returns Logo complet avec les couleurs adaptées - */ - private static adaptLogoColors(fullLogoSvg: string, variationSvg: string): string { - try { - // Extraire les couleurs de la variation - const colors = this.extractColorsFromSvg(variationSvg); - - // Appliquer ces couleurs au logo complet - let adaptedLogo = fullLogoSvg; - - // Remplacer les couleurs principales - colors.forEach((color, index) => { - // Remplacer les couleurs par ordre d'apparition - const colorRegex = new RegExp(`fill="[^"]*"`, 'g'); - if (index === 0) { - adaptedLogo = adaptedLogo.replace(colorRegex, `fill="${color}"`); - } - }); - - return adaptedLogo; - } catch (error) { - logger.error('Error adapting logo colors:', error); - return fullLogoSvg; - } - } - - /** - * Extrait les couleurs d'un SVG - * @param svgContent - Contenu SVG - * @returns Tableau des couleurs trouvées - */ - private static extractColorsFromSvg(svgContent: string): string[] { - const colors: string[] = []; - const fillMatches = svgContent.match(/fill="([^"]*)"/g); - - if (fillMatches) { - fillMatches.forEach((match) => { - const color = match.match(/fill="([^"]*)"/)?.[1]; - if (color && color !== 'none' && !colors.includes(color)) { - colors.push(color); - } - }); - } - - return colors; - } - - /** - * Supprime les éléments vides d'un SVG - * @param svgElement - Élément SVG à nettoyer - */ - private static removeEmptyElements(svgElement: SVGElement): void { - const emptyElements = svgElement.querySelectorAll('g:empty, defs:empty'); - emptyElements.forEach((element) => element.remove()); - } -} diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html index 0ffe08024..253cafbdb 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html @@ -241,6 +241,54 @@

} + +@if (shouldShowSuccess()) { +
+
+ +
+
+ +
+

+ {{ 'dashboard.logoVariations.success.completed' | translate }} +

+

+ {{ 'dashboard.logoVariations.success.autoAdvancing' | translate }} +

+
+ + +
+ @for (variation of getAllVariations(); track variation.id) { +
+
+
+
+

{{ variation.label }}

+
+ } +
+ + +
+
+ + {{ 'dashboard.logoVariations.status.advancing' | translate }} +
+
+
+
+} + @if (shouldShowVariations()) {
@@ -255,117 +303,70 @@

- +
- - @for ( - category of [ - 'dashboard.logoVariations.categories.withText' | translate, - 'dashboard.logoVariations.categories.iconOnly' | translate, - ]; - track category - ) { - @if (hasVariationsForCategory(category)) { -
-

{{ category }}

- - - + + +
+ +
- +
+
+ + +
+
+

{{ variation.label }}

- -
-
-
- - -
-
-

{{ variation.label }}

- @if (isVariationSelected(variation.id)) { -
- -
- } -
+ +
+
-

{{ variation.description }}

+

{{ variation.description }}

- -
- @if (isVariationSelected(variation.id)) { - - - Selected - - } @else { - - {{ 'dashboard.logoVariations.buttons.clickToSelect' | translate }} - - } -
-
-
- - + +
+ + + {{ 'dashboard.logoVariations.status.generated' | translate }} + +
+
- } - } + +
- - @if (selectedVariations().length > 0) { -
-

- - {{ - 'dashboard.logoVariations.selectionsMade' - | translate: { count: selectedVariations().length } - }} -

- - -
- } @else { -
-

- {{ 'dashboard.logoVariations.errors.selectAtLeastOne' | translate }} -

+ +
+

+ + {{ 'dashboard.logoVariations.status.processing' | translate }} +

+
+ + {{ 'dashboard.logoVariations.status.preparingNext' | translate }}
- } +
} diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.ts index 41e3577f1..d2ca874b7 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.ts @@ -21,13 +21,11 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core'; interface DisplayVariation { id: string; - type: 'withText' | 'iconOnly'; background: 'lightBackground' | 'darkBackground' | 'monochrome'; label: string; svgContent: string; description: string; backgroundColor: string; - category: string; } @Component({ @@ -60,7 +58,7 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { protected readonly estimatedTime = signal('1-2 minutes'); protected readonly hasStartedGeneration = signal(false); protected readonly error = signal(null); - protected readonly selectedVariations = signal([]); + protected readonly isCompleted = signal(false); // Computed properties protected readonly shouldShowLoader = computed(() => { @@ -68,7 +66,11 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { }); protected readonly shouldShowVariations = computed(() => { - return this.generatedVariations().length > 0; + return this.generatedVariations().length > 0 && !this.isCompleted(); + }); + + protected readonly shouldShowSuccess = computed(() => { + return this.isCompleted() && this.generatedVariations().length > 0; }); protected readonly shouldShowInitialPrompt = computed(() => { @@ -76,7 +78,7 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { }); protected readonly canProceed = computed(() => { - return this.selectedVariations().length > 0; + return this.isCompleted(); }); // Track function for carousel @@ -126,105 +128,49 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { next: (response) => { console.log('Logo variations generated successfully:', response); - // Transform the response into DisplayVariation objects + // Transform the response into DisplayVariation objects (simplified to 3 variations) const variations: DisplayVariation[] = []; - // Process withText variations + // Use withText variations as primary (since logos are now complete) if (response.variations.withText) { const withText = response.variations.withText; if (withText.lightBackground) { variations.push({ - id: 'withText-lightBackground', - type: 'withText', + id: 'lightBackground', background: 'lightBackground', - label: this.translate.instant('dashboard.logoVariations.labels.withTextLight'), + label: this.translate.instant('dashboard.logoVariations.labels.lightBackground'), svgContent: withText.lightBackground, description: this.translate.instant( - 'dashboard.logoVariations.descriptions.withTextLight', + 'dashboard.logoVariations.descriptions.lightBackground', ), backgroundColor: '#ffffff', - category: this.translate.instant('dashboard.logoVariations.categories.withText'), }); } if (withText.darkBackground) { variations.push({ - id: 'withText-darkBackground', - type: 'withText', + id: 'darkBackground', background: 'darkBackground', - label: this.translate.instant('dashboard.logoVariations.labels.withTextDark'), + label: this.translate.instant('dashboard.logoVariations.labels.darkBackground'), svgContent: withText.darkBackground, description: this.translate.instant( - 'dashboard.logoVariations.descriptions.withTextDark', + 'dashboard.logoVariations.descriptions.darkBackground', ), backgroundColor: '#1f2937', - category: this.translate.instant('dashboard.logoVariations.categories.withText'), }); } if (withText.monochrome) { variations.push({ - id: 'withText-monochrome', - type: 'withText', + id: 'monochrome', background: 'monochrome', - label: this.translate.instant('dashboard.logoVariations.labels.withTextMonochrome'), + label: this.translate.instant('dashboard.logoVariations.labels.monochrome'), svgContent: withText.monochrome, description: this.translate.instant( - 'dashboard.logoVariations.descriptions.withTextMonochrome', - ), - backgroundColor: '#f3f4f6', - category: this.translate.instant('dashboard.logoVariations.categories.withText'), - }); - } - } - - // Process iconOnly variations - if (response.variations.iconOnly) { - const iconOnly = response.variations.iconOnly; - - if (iconOnly.lightBackground) { - variations.push({ - id: 'iconOnly-lightBackground', - type: 'iconOnly', - background: 'lightBackground', - label: this.translate.instant('dashboard.logoVariations.labels.iconOnlyLight'), - svgContent: iconOnly.lightBackground, - description: this.translate.instant( - 'dashboard.logoVariations.descriptions.iconOnlyLight', - ), - backgroundColor: '#ffffff', - category: this.translate.instant('dashboard.logoVariations.categories.iconOnly'), - }); - } - - if (iconOnly.darkBackground) { - variations.push({ - id: 'iconOnly-darkBackground', - type: 'iconOnly', - background: 'darkBackground', - label: this.translate.instant('dashboard.logoVariations.labels.iconOnlyDark'), - svgContent: iconOnly.darkBackground, - description: this.translate.instant( - 'dashboard.logoVariations.descriptions.iconOnlyDark', - ), - backgroundColor: '#1f2937', - category: this.translate.instant('dashboard.logoVariations.categories.iconOnly'), - }); - } - - if (iconOnly.monochrome) { - variations.push({ - id: 'iconOnly-monochrome', - type: 'iconOnly', - background: 'monochrome', - label: this.translate.instant('dashboard.logoVariations.labels.iconOnlyMonochrome'), - svgContent: iconOnly.monochrome, - description: this.translate.instant( - 'dashboard.logoVariations.descriptions.iconOnlyMonochrome', + 'dashboard.logoVariations.descriptions.monochrome', ), backgroundColor: '#f3f4f6', - category: this.translate.instant('dashboard.logoVariations.categories.iconOnly'), }); } } @@ -240,8 +186,8 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { this.translate.instant('dashboard.logoVariations.progress.completed'), ); - // Auto-select all variations by default - this.selectedVariations.set(variations.map((v) => v.id)); + // Auto-accept all variations and update project immediately + this.autoAcceptVariations(response.variations); }, error: (error) => { console.error('Error in logo variation generation:', error); @@ -253,80 +199,22 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { }); } - protected toggleVariationSelection(variationType: string): void { - const currentSelections = this.selectedVariations(); - - if (currentSelections.includes(variationType)) { - // Remove from selection - this.selectedVariations.set(currentSelections.filter((type) => type !== variationType)); - } else { - // Add to selection - this.selectedVariations.set([...currentSelections, variationType]); - } - } - - protected isVariationSelected(variationType: string): boolean { - return this.selectedVariations().includes(variationType); - } - - protected getVariationsByCategory(category: string): DisplayVariation[] { - const categoryMap: { [key: string]: 'withText' | 'iconOnly' } = { - [this.translate.instant('dashboard.logoVariations.categories.withText')]: 'withText', - [this.translate.instant('dashboard.logoVariations.categories.iconOnly')]: 'iconOnly', - }; - const mappedCategory = categoryMap[category]; - return this.generatedVariations().filter((v) => v.type === mappedCategory); - } - - protected hasVariationsForCategory(category: string): boolean { - return this.getVariationsByCategory(category).length > 0; + // Simplified: return all variations since we only have 3 now + protected getAllVariations(): DisplayVariation[] { + return this.generatedVariations(); } - protected goToNextStep(): void { - if (!this.canProceed()) { - return; - } - - // Update project with selected logo variations - const selectedVariations = this.generatedVariations().filter((variation) => - this.selectedVariations().includes(variation.id), - ); - + /** + * Auto-accept all generated variations and update project + */ + private autoAcceptVariations(variations: LogoVariations): void { const currentProject = this.project(); const currentBranding = currentProject?.analysisResultModel?.branding; - // Build the variations object from selected variations - const withTextVariations = { - lightBackground: selectedVariations.find( - (v) => v.type === 'withText' && v.background === 'lightBackground', - )?.svgContent, - darkBackground: selectedVariations.find( - (v) => v.type === 'withText' && v.background === 'darkBackground', - )?.svgContent, - monochrome: selectedVariations.find( - (v) => v.type === 'withText' && v.background === 'monochrome', - )?.svgContent, - }; - - const iconOnlyVariations = { - lightBackground: selectedVariations.find( - (v) => v.type === 'iconOnly' && v.background === 'lightBackground', - )?.svgContent, - darkBackground: selectedVariations.find( - (v) => v.type === 'iconOnly' && v.background === 'darkBackground', - )?.svgContent, - monochrome: selectedVariations.find( - (v) => v.type === 'iconOnly' && v.background === 'monochrome', - )?.svgContent, - }; - - // Update the logo with variations + // Update the logo with all variations const updatedLogo: LogoModel = { ...this.selectedLogo(), - variations: { - withText: withTextVariations, - iconOnly: iconOnlyVariations, - }, + variations: variations, }; const updatedBranding = { @@ -334,6 +222,7 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { logo: updatedLogo, }; + // Update project immediately this.projectUpdate.emit({ ...currentProject, analysisResultModel: { @@ -342,7 +231,13 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { }, } as ProjectModel); - this.nextStep.emit(); + // Mark as completed and show success state briefly + this.isCompleted.set(true); + + // Auto-advance to next step after a brief delay to show success + setTimeout(() => { + this.nextStep.emit(); + }, 2000); // 2 second delay to show the success state } private simulateProgress(): void { @@ -395,7 +290,7 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { this.hasStartedGeneration.set(false); this.generatedVariations.set([]); this.generationProgress.set(0); - this.selectedVariations.set([]); + this.isCompleted.set(false); // Restart generation this.startVariationGeneration(); diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.html index f1fb09b7e..9480a7ee8 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.html @@ -123,53 +123,6 @@

>

- - -
- - -
- - -
-
} diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.ts index 3fd1ac91b..a9c57749e 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/typography-selection/typography-selection.ts @@ -59,8 +59,7 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { // Outputs @Output() readonly typographySelected = new EventEmitter(); @Output() readonly projectUpdate = new EventEmitter>(); - @Output() readonly nextStep = new EventEmitter(); - @Output() readonly previousStep = new EventEmitter(); + @Output() readonly typographySelectionChanged = new EventEmitter(); // Signals protected activeTab = signal('generated'); @@ -119,12 +118,14 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { // If switching to generated, ensure something is selected if possible if (tab === 'generated' && !this.selectedTypographyId() && this.typographyModels().length > 0) { this.selectedTypographyId.set(this.typographyModels()[0].id); + this.notifySelectionChange(); } } protected onTypographySelected(typography: TypographyModel): void { this.selectedTypographyId.set(typography.id); this.typographySelected.emit(typography); + this.notifySelectionChange(); } protected onRegenerateTypographies(): void { @@ -137,68 +138,50 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { this.initializeTypographies(); } - protected goBack(): void { - this.previousStep.emit(); - } - - protected saveAsDraft(): void { + // Method to prepare and emit project data when parent requests it + public prepareTypographyData(): Partial | null { const selectedTypography = this.currentSelectedTypography(); - if (!selectedTypography) return; + if (!selectedTypography) return null; + + // For custom typography, add it to the generatedTypography list so it can be found in project-summary + let updatedGeneratedTypography = + this.project.analysisResultModel?.branding?.generatedTypography || []; + + if (this.activeTab() === 'custom' && selectedTypography.id === 'custom-preview') { + // Create a proper custom typography with unique ID + const customTypography: TypographyModel = { + ...selectedTypography, + id: `custom-${Date.now()}`, // Unique ID for custom typography + }; - const draftData: Partial = { + // Add custom typography to the list if not already present + const existingCustomIndex = updatedGeneratedTypography.findIndex((t) => + t.id.startsWith('custom-'), + ); + if (existingCustomIndex >= 0) { + updatedGeneratedTypography[existingCustomIndex] = customTypography; + } else { + updatedGeneratedTypography = [...updatedGeneratedTypography, customTypography]; + } + + selectedTypography.id = customTypography.id; // Update the selected typography ID + } + + return { analysisResultModel: { ...this.project.analysisResultModel, branding: { ...this.project.analysisResultModel?.branding, typography: selectedTypography, + generatedTypography: updatedGeneratedTypography, }, }, }; - this.projectUpdate.emit(draftData); } - protected continueToNext(): void { - if (this.canContinue()) { - const selectedTypography = this.currentSelectedTypography(); - if (!selectedTypography) return; - - // For custom typography, add it to the generatedTypography list so it can be found in project-summary - let updatedGeneratedTypography = - this.project.analysisResultModel?.branding?.generatedTypography || []; - - if (this.activeTab() === 'custom' && selectedTypography.id === 'custom-preview') { - // Create a proper custom typography with unique ID - const customTypography: TypographyModel = { - ...selectedTypography, - id: `custom-${Date.now()}`, // Unique ID for custom typography - }; - - // Add custom typography to the list if not already present - const existingCustomIndex = updatedGeneratedTypography.findIndex((t) => - t.id.startsWith('custom-'), - ); - if (existingCustomIndex >= 0) { - updatedGeneratedTypography[existingCustomIndex] = customTypography; - } else { - updatedGeneratedTypography = [...updatedGeneratedTypography, customTypography]; - } - - selectedTypography.id = customTypography.id; // Update the selected typography ID - } - - const projectData: Partial = { - analysisResultModel: { - ...this.project.analysisResultModel, - branding: { - ...this.project.analysisResultModel?.branding, - typography: selectedTypography, - generatedTypography: updatedGeneratedTypography, - }, - }, - }; - this.projectUpdate.emit(projectData); - this.nextStep.emit(); - } + // Notify parent about selection state changes + private notifySelectionChange(): void { + this.typographySelectionChanged.emit(this.canContinue()); } protected onSearchInput(query: string): void { @@ -214,6 +197,7 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { this.selectedSecondaryFont.set(font.family); } this.typographyService.loadGoogleFont(font.family); + this.notifySelectionChange(); } ngOnInit(): void { @@ -233,6 +217,11 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { if (generatedTypography && generatedTypography.length > 0) { this.typographyModels.set(generatedTypography); this.isLoading.set(false); + // Auto-select first typography if none selected + if (!this.selectedTypographyId()) { + this.selectedTypographyId.set(generatedTypography[0].id); + this.notifySelectionChange(); + } } else { this.regenerateTypographies(); } @@ -273,6 +262,7 @@ export class TypographySelectionComponent implements OnInit, OnDestroy { // Auto-select first item if (mockTypographies.length > 0) { this.selectedTypographyId.set(mockTypographies[0].id); + this.notifySelectionChange(); } }, 2000); } diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.html index 8b80c874a..be3dcb41c 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.html @@ -54,9 +54,8 @@

@if (isStepActive(3)) { } @if (isStepActive(4)) { diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.ts index 6d2b072f2..b4b993331 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/create-project.ts @@ -1,4 +1,4 @@ -import { Component, inject, OnInit, signal, computed } from '@angular/core'; +import { Component, inject, OnInit, signal, computed, ViewChild } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Router } from '@angular/router'; import { ProjectModel } from '../../models/project.model'; @@ -110,6 +110,12 @@ export class CreateProjectComponent implements OnInit { marketing: false, }); + // Step-specific validation state + protected readonly typographySelectionValid = signal(false); + + // ViewChild to access typography component + @ViewChild(TypographySelectionComponent) typographyComponent?: TypographySelectionComponent; + // Static data protected readonly projectTypes = CreateProjectDatas.groupedProjectTypes; protected readonly targets = CreateProjectDatas.groupedTargets; @@ -160,7 +166,7 @@ export class CreateProjectComponent implements OnInit { case 'colors': return !!project.analysisResultModel?.branding?.generatedColors?.length; case 'typography': - return !!project.analysisResultModel?.branding?.typography; + return this.typographySelectionValid(); case 'logo': return !!project.analysisResultModel?.branding?.logo; case 'variations': @@ -185,10 +191,26 @@ export class CreateProjectComponent implements OnInit { } } + /** + * Handle typography selection change + */ + protected onTypographySelectionChanged(isValid: boolean): void { + this.typographySelectionValid.set(isValid); + } + /** * Navigate to next step */ protected goToNextStep(): void { + // For typography step, prepare and save typography data before proceeding + if (this.currentStepIndex() === 3 && this.typographyComponent) { + // Typography step + const typographyData = this.typographyComponent.prepareTypographyData(); + if (typographyData) { + this.onProjectUpdate(typographyData); + } + } + if (this.canGoNext()) { const nextIndex = this.currentStepIndex() + 1; if (nextIndex < this.steps.length) { From 141251aff744dc24c339e4bdd08054e932deb958 Mon Sep 17 00:00:00 2001 From: arolleaguekeng Date: Mon, 26 Jan 2026 02:44:34 +0100 Subject: [PATCH 3/5] refactor logo variations UI to remove auto-advance and add manual proceed button after generation completion Remove shouldShowSuccess computed property and separate success state template. Merge success and variations display into single template with conditional header based on completion state. Replace auto-advance timeout with manual proceed button that emits nextStep event. Update status messages to show 'allGenerated' and 'readyToProceed' when completed instead of auto-advancing spinner. --- .../logo-variations/logo-variations.html | 110 ++++++++---------- .../logo-variations/logo-variations.ts | 13 +-- 2 files changed, 48 insertions(+), 75 deletions(-) diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html index 253cafbdb..b01092e63 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html @@ -241,66 +241,32 @@

} - -@if (shouldShowSuccess()) { -
-
- -
-
- -
-

- {{ 'dashboard.logoVariations.success.completed' | translate }} -

-

- {{ 'dashboard.logoVariations.success.autoAdvancing' | translate }} -

-
- - -
- @for (variation of getAllVariations(); track variation.id) { -
-
-
-
-

{{ variation.label }}

-
- } -
- - -
-
- - {{ 'dashboard.logoVariations.status.advancing' | translate }} -
-
-
-
-} - @if (shouldShowVariations()) {
-

- {{ 'dashboard.logoVariations.success.title' | translate }} -

-

- {{ 'dashboard.logoVariations.success.subtitle' | translate }} -

+ @if (isCompleted()) { +
+ +
+

+ {{ 'dashboard.logoVariations.success.completed' | translate }} +

+

+ {{ 'dashboard.logoVariations.success.reviewAndProceed' | translate }} +

+ } @else { +

+ {{ 'dashboard.logoVariations.success.title' | translate }} +

+

+ {{ 'dashboard.logoVariations.success.subtitle' | translate }} +

+ }
@@ -356,17 +322,33 @@

{{ variation.label }}

- -
-

- - {{ 'dashboard.logoVariations.status.processing' | translate }} -

-
- - {{ 'dashboard.logoVariations.status.preparingNext' | translate }} + + @if (isCompleted()) { +
+

+ + {{ 'dashboard.logoVariations.status.allGenerated' | translate }} +

+

+ {{ 'dashboard.logoVariations.status.readyToProceed' | translate }} +

+
-
+ } @else { +
+

+ + {{ 'dashboard.logoVariations.status.processing' | translate }} +

+
+ + {{ 'dashboard.logoVariations.status.preparingNext' | translate }} +
+
+ }
} diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.ts b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.ts index d2ca874b7..4a785301b 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.ts +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.ts @@ -66,11 +66,7 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { }); protected readonly shouldShowVariations = computed(() => { - return this.generatedVariations().length > 0 && !this.isCompleted(); - }); - - protected readonly shouldShowSuccess = computed(() => { - return this.isCompleted() && this.generatedVariations().length > 0; + return this.generatedVariations().length > 0; }); protected readonly shouldShowInitialPrompt = computed(() => { @@ -231,13 +227,8 @@ export class LogoVariationsComponent implements OnInit, OnDestroy { }, } as ProjectModel); - // Mark as completed and show success state briefly + // Mark as completed - user can now proceed manually this.isCompleted.set(true); - - // Auto-advance to next step after a brief delay to show success - setTimeout(() => { - this.nextStep.emit(); - }, 2000); // 2 second delay to show the success state } private simulateProgress(): void { From 4ed0c392607b41587a6da3f1f91a502e43fba29a Mon Sep 17 00:00:00 2001 From: arolleaguekeng Date: Mon, 26 Jan 2026 02:59:01 +0100 Subject: [PATCH 4/5] reduce Gemini token limit from 1500 to 500, add i18n translations for logo variations status messages and buttons, and refactor completion UI to remove redundant success state display Update branding.service.ts to reduce maxOutputTokens from 1500 to 500. Add comprehensive i18n translations for logo variations including retry/continueToSummary buttons, status messages (generated/processing/allGenerated/readyToProceed/advancing), and category descriptions (lightBackground/darkBackground/monochrome --- .../services/BandIdentity/branding.service.ts | 5 +--- .../main-dashboard/public/assets/i18n/en.json | 26 ++++++++++++++++--- .../main-dashboard/public/assets/i18n/fr.json | 26 ++++++++++++++++--- .../logo-variations/logo-variations.html | 26 ++++++------------- 4 files changed, 53 insertions(+), 30 deletions(-) diff --git a/apps/api/api/services/BandIdentity/branding.service.ts b/apps/api/api/services/BandIdentity/branding.service.ts index 5f4baf647..c805d584e 100644 --- a/apps/api/api/services/BandIdentity/branding.service.ts +++ b/apps/api/api/services/BandIdentity/branding.service.ts @@ -26,12 +26,10 @@ import { PdfService } from '../pdf.service'; import { cacheService } from '../cache.service'; import crypto from 'crypto'; import { projectService } from '../project.service'; -import { LogoJsonToSvgService } from './logoJsonToSvg.service'; import { SvgOptimizerService } from './svgOptimizer.service'; export class BrandingService extends GenericService { private pdfService: PdfService; - private logoJsonToSvgService: LogoJsonToSvgService; // Configuration LLM pour la génération de logos et variations // Temperature modérée pour équilibrer créativité et cohérence @@ -39,7 +37,7 @@ export class BrandingService extends GenericService { provider: LLMProvider.GEMINI, modelName: 'gemini-3-flash-preview', llmOptions: { - maxOutputTokens: 1500, + maxOutputTokens: 500, temperature: 0.4, // Équilibre entre créativité et cohérence topP: 0.9, topK: 55, @@ -73,7 +71,6 @@ export class BrandingService extends GenericService { constructor(promptService: PromptService) { super(promptService); this.pdfService = new PdfService(); - this.logoJsonToSvgService = new LogoJsonToSvgService(); logger.info('BrandingService initialized with optimized logo generation'); } diff --git a/apps/main-dashboard/public/assets/i18n/en.json b/apps/main-dashboard/public/assets/i18n/en.json index fa9b382b3..f8e7e081d 100644 --- a/apps/main-dashboard/public/assets/i18n/en.json +++ b/apps/main-dashboard/public/assets/i18n/en.json @@ -361,7 +361,9 @@ "buttons": { "generate": "Generate Variations", "clickToSelect": "Click to select", - "proceed": "Proceed with selection" + "proceed": "Proceed with selection", + "retry": "Retry", + "continueToSummary": "Continue to Summary" }, "estimatedTime": "Estimated time: {{time}}", "generating": { @@ -385,7 +387,9 @@ }, "success": { "title": "Logo Variations", - "subtitle": "Select the variations you want to keep for your project." + "subtitle": "Select the variations you want to keep for your project.", + "completed": "Variations Generated Successfully!", + "reviewAndProceed": "Review your variations and proceed when ready." }, "categories": { "withText": "With Text", @@ -397,7 +401,10 @@ "withTextMonochrome": "With Text - Monochrome", "iconOnlyLight": "Icon Only - Light Background", "iconOnlyDark": "Icon Only - Dark Background", - "iconOnlyMonochrome": "Icon Only - Monochrome" + "iconOnlyMonochrome": "Icon Only - Monochrome", + "lightBackground": "Light Background", + "darkBackground": "Dark Background", + "monochrome": "Monochrome" }, "descriptions": { "withTextLight": "Full logo optimized for light backgrounds", @@ -405,7 +412,18 @@ "withTextMonochrome": "Full logo in monochrome version", "iconOnlyLight": "Icon only optimized for light backgrounds", "iconOnlyDark": "Icon only optimized for dark backgrounds", - "iconOnlyMonochrome": "Icon only in monochrome version" + "iconOnlyMonochrome": "Icon only in monochrome version", + "lightBackground": "Optimized for white and light backgrounds", + "darkBackground": "Optimized for dark and modern backgrounds", + "monochrome": "Version in black and white for all uses" + }, + "status": { + "generated": "Generated", + "processing": "Processing variations...", + "preparingNext": "Preparing next step...", + "allGenerated": "All variations generated successfully!", + "readyToProceed": "Ready to proceed to the next step.", + "advancing": "Advancing to next step..." }, "selectionsMade": "{{count}} selection(s) made" }, diff --git a/apps/main-dashboard/public/assets/i18n/fr.json b/apps/main-dashboard/public/assets/i18n/fr.json index 4fd7c0e63..a673c7286 100644 --- a/apps/main-dashboard/public/assets/i18n/fr.json +++ b/apps/main-dashboard/public/assets/i18n/fr.json @@ -361,7 +361,9 @@ "buttons": { "generate": "Générer les variations", "clickToSelect": "Cliquez pour sélectionner", - "proceed": "Continuer avec la sélection" + "proceed": "Continuer avec la sélection", + "retry": "Réessayer", + "continueToSummary": "Continuer vers le résumé" }, "estimatedTime": "Temps estimé : {{time}}", "generating": { @@ -385,7 +387,9 @@ }, "success": { "title": "Variations du logo", - "subtitle": "Sélectionnez les variations que vous souhaitez conserver pour votre projet." + "subtitle": "Sélectionnez les variations que vous souhaitez conserver pour votre projet.", + "completed": "Variations générées avec succès !", + "reviewAndProceed": "Examinez vos variations et continuez quand vous êtes prêt." }, "categories": { "withText": "Avec texte", @@ -397,7 +401,10 @@ "withTextMonochrome": "Avec texte - Monochrome", "iconOnlyLight": "Icône uniquement - Fond clair", "iconOnlyDark": "Icône uniquement - Fond sombre", - "iconOnlyMonochrome": "Icône uniquement - Monochrome" + "iconOnlyMonochrome": "Icône uniquement - Monochrome", + "lightBackground": "Fond clair", + "darkBackground": "Fond sombre", + "monochrome": "Monochrome" }, "descriptions": { "withTextLight": "Logo complet optimisé pour les fonds clairs", @@ -405,7 +412,18 @@ "withTextMonochrome": "Logo complet en version monochrome", "iconOnlyLight": "Icône uniquement optimisée pour les fonds clairs", "iconOnlyDark": "Icône uniquement optimisée pour les fonds sombres", - "iconOnlyMonochrome": "Icône uniquement en version monochrome" + "iconOnlyMonochrome": "Icône uniquement en version monochrome", + "lightBackground": "Optimisé pour les fonds blancs et clairs", + "darkBackground": "Optimisé pour les fonds sombres et modernes", + "monochrome": "Version en noir et blanc pour toutes les utilisations" + }, + "status": { + "generated": "Généré", + "processing": "Traitement des variations...", + "preparingNext": "Préparation de l'étape suivante...", + "allGenerated": "Toutes les variations générées avec succès !", + "readyToProceed": "Prêt à passer à l'étape suivante.", + "advancing": "Passage à l'étape suivante..." }, "selectionsMade": "{{count}} sélection(s) faite(s)" }, diff --git a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html index b01092e63..dc19c82b5 100644 --- a/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html +++ b/apps/main-dashboard/src/app/modules/dashboard/pages/create-project/components/logo-variations/logo-variations.html @@ -177,7 +177,9 @@

{{ 'dashboard.logoVariations.features.lightBackground.title' | translate }}

-

Optimized for white and light backgrounds

+

+ {{ 'dashboard.logoVariations.features.lightBackground.description' | translate }} +

@@ -189,7 +191,9 @@

{{ 'dashboard.logoVariations.features.darkBackground.title' | translate }}

-

Optimized for dark and modern backgrounds

+

+ {{ 'dashboard.logoVariations.features.darkBackground.description' | translate }} +

@@ -234,7 +238,7 @@

class="outer-button px-8 py-4 bg-danger/20 border-danger/30 hover:bg-danger/30" > - Retry + {{ 'dashboard.logoVariations.buttons.retry' | translate }}

@@ -323,21 +327,7 @@

{{ variation.label }}

- @if (isCompleted()) { -
-

- - {{ 'dashboard.logoVariations.status.allGenerated' | translate }} -

-

- {{ 'dashboard.logoVariations.status.readyToProceed' | translate }} -

- -
- } @else { + @if (!isCompleted()) {

From 6dd221d65a9d46f25e9318d905c6304dac75dd20 Mon Sep 17 00:00:00 2001 From: arolleaguekeng Date: Mon, 26 Jan 2026 03:03:18 +0100 Subject: [PATCH 5/5] upgrade Gemini model from 2.5-flash to 3-flash-preview across all services and remove alternative model configurations (Claude, GPT-4, DeepSeek) from default model config --- .../BusinessPlan/businessPlan.service.ts | 2 +- .../services/Deployment/deployment.service.ts | 4 +- .../api/services/common/generic.service.ts | 2 +- .../we-dev-next/src/app/api/model/config.ts | 40 ++----------------- 4 files changed, 8 insertions(+), 40 deletions(-) diff --git a/apps/api/api/services/BusinessPlan/businessPlan.service.ts b/apps/api/api/services/BusinessPlan/businessPlan.service.ts index 0f629cc56..d9bd4f659 100644 --- a/apps/api/api/services/BusinessPlan/businessPlan.service.ts +++ b/apps/api/api/services/BusinessPlan/businessPlan.service.ts @@ -143,7 +143,7 @@ export class BusinessPlanService extends GenericService { ]; const promptConfig: PromptConfig = { provider: LLMProvider.GEMINI, - modelName: 'gemini-2.5-flash', + modelName: 'gemini-3-flash-preview', }; // Initialize empty sections array to collect results as they come in diff --git a/apps/api/api/services/Deployment/deployment.service.ts b/apps/api/api/services/Deployment/deployment.service.ts index 5699d1fd2..f88591562 100644 --- a/apps/api/api/services/Deployment/deployment.service.ts +++ b/apps/api/api/services/Deployment/deployment.service.ts @@ -770,7 +770,7 @@ Please provide only the terraform.tfvars file content as output.`; // Use AI to generate the tfvars content const promptConfig: PromptConfig = { provider: LLMProvider.GEMINI, - modelName: 'gemini-2.5-flash', + modelName: 'gemini-3-flash-preview', llmOptions: { temperature: 0.3, maxOutputTokens: 4000, @@ -1140,7 +1140,7 @@ Please provide only the terraform.tfvars file content as output.`; const aiResponse = await this.promptService.runPrompt( { provider: LLMProvider.GEMINI, - modelName: 'gemini-2.5-flash', + modelName: 'gemini-3-flash-preview', llmOptions: { temperature: 0.7, maxOutputTokens: 1024, diff --git a/apps/api/api/services/common/generic.service.ts b/apps/api/api/services/common/generic.service.ts index b9a59aa33..4127884e8 100644 --- a/apps/api/api/services/common/generic.service.ts +++ b/apps/api/api/services/common/generic.service.ts @@ -99,7 +99,7 @@ export class GenericService { contextFromPreviousSteps: string = '', promptConfig: PromptConfig = { provider: LLMProvider.GEMINI, - modelName: 'gemini-2.5-flash', + modelName: 'gemini-3-flash-preview', userId, promptType: promptType || step.stepName, } diff --git a/apps/appgen/apps/we-dev-next/src/app/api/model/config.ts b/apps/appgen/apps/we-dev-next/src/app/api/model/config.ts index 64796f78e..6f77de63c 100644 --- a/apps/appgen/apps/we-dev-next/src/app/api/model/config.ts +++ b/apps/appgen/apps/we-dev-next/src/app/api/model/config.ts @@ -16,45 +16,13 @@ interface ModelConfig { // Default model configurations const defaultModelConfigs: ModelConfig[] = [ { - modelName: 'gemini-2.5-flash', - modelKey: 'gemini-2.5-flash', + modelName: 'gemini-3-flash-preview', + modelKey: 'gemini-3-flash-preview', useImage: true, provider: 'gemini', - description: 'Gemini 2.5 Flash model', + description: 'Gemini 3 Flash model', functionCall: true, - }, - { - modelName: 'claude-3-5-sonnet', - modelKey: 'claude-3-5-sonnet-20240620', - useImage: true, - provider: 'claude', - description: 'Claude 3.5 Sonnet model', - functionCall: true, - }, - { - modelName: 'gpt-4o-mini', - modelKey: 'gpt-4o-mini', - useImage: false, - provider: 'openai', - description: 'GPT-4 Optimized Mini model', - functionCall: true, - }, - { - modelName: 'deepseek-R1', - modelKey: 'deepseek-reasoner', - useImage: false, - provider: 'deepseek', - description: 'Deepseek R1 model with reasoning and chain-of-thought capabilities', - functionCall: false, - }, - { - modelName: 'deepseek-v3', - modelKey: 'deepseek-chat', - useImage: false, - provider: 'deepseek', - description: 'Deepseek V3 model', - functionCall: true, - }, + } ]; // Function to parse model configurations from environment variable