Skip to content

Commit ac308a2

Browse files
authored
Fix form steps (#160)
* ADD horizontal steps on catalogs and products * ADD horizontal steps on services and resources forms * ADD stepper and action button in every form * FIX catalog next buttons * FIX catalogs finish buttons
1 parent 3fc64d7 commit ac308a2

19 files changed

Lines changed: 1201 additions & 731 deletions

src/app/pages/seller-offerings/offerings/seller-catalogs/create-catalog/create-catalog.component.html

Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,36 +26,29 @@
2626
<!-- End Breadcrumb -->
2727

2828
<div class="bg-secondary-50 dark:bg-secondary-100 border border-secondary-50 dark:border-gray-800 mt-4 p-8 rounded-lg">
29-
<h2 class="text-3xl font-bold text-primary-100 dark:text-white ml-4">{{ 'CREATE_CATALOG._new' | translate }}</h2>
30-
<hr class="h-px m-4 bg-gray-300 dark:bg-gray-200 border-0">
31-
<div class="md:grid md:grid-cols-25/75 xl:grid-cols-20/80">
32-
<div class="flex sm:flex-row md:flex-col md:mr-4 overflow-x-auto max-w-[calc(100vw-5rem)]">
33-
<h2 class="text-xl hidden md:block font-bold text-black mb-4 dark:text-white">{{ 'CREATE_CATALOG._steps' | translate }}</h2>
34-
<button id="general-info" (click)="toggleGeneral()" [disabled]="!generalDone"
35-
class="grid sm:grid-rows-2 md:grid-rows-1 md:grid-cols-25/75 xl:grid-cols-20/80 mb-2 mr-2 md:mr-0 text-primary-100 dark:text-primary-50 justify-items-center md:justify-items-start">
36-
<span id="general-circle" class="flex items-center justify-center w-6 h-6 md:w-8 md:h-8 border border-2 border-primary-100 dark:border-primary-50 rounded-full shrink-0">
37-
1
38-
</span>
39-
<span>
40-
<h3 class="flex sm:text-center md:text-start">{{ 'UPDATE_CATALOG._general' | translate }}</h3>
41-
<p class="hidden xl:flex text-xs sm:text-center md:text-start">{{ 'UPDATE_CATALOG._general_info' | translate }}</p>
42-
</span>
43-
</button>
44-
<hr class="h-px mb-2 bg-gray-300 dark:bg-gray-200 border-0">
45-
<button id="summary" [disabled]="!finishDone || generalForm.invalid" (click)="showFinish()"
46-
class="grid sm:grid-rows-2 md:grid-rows-1 md:grid-cols-25/75 xl:grid-cols-20/80 mb-2 mr-2 md:mr-0 text-gray-500 justify-items-center md:justify-items-start">
47-
<span id="summary-circle" class="flex items-center justify-center w-6 h-6 md:w-8 md:h-8 border border-2 border-gray-400 rounded-full shrink-0">
48-
2
49-
</span>
50-
<span>
51-
<h3 class="flex justify-start">{{ 'UPDATE_CATALOG._finish' | translate }}</h3>
52-
<p class="hidden xl:flex text-xs justify-start text-start">{{ 'UPDATE_CATALOG._summary' | translate }}</p>
53-
</span>
54-
</button>
55-
</div>
29+
<h2 class="text-3xl font-bold text-primary-100 dark:text-white ml-4 pb-4">{{ 'CREATE_CATALOG._new' | translate }}</h2>
30+
<ol class="flex items-start w-full text-sm font-medium text-center text-gray-500 dark:text-gray-400">
31+
@for (step of steps; track i; let i = $index) {
32+
<li
33+
(click)="handleStepClick(i)"
34+
[class.cursor-not-allowed]="!canNavigate(i)"
35+
[class.opacity-50]="!canNavigate(i)"
36+
[class.text-primary-100]="currentStep === i"
37+
class="flex-1 cursor-pointer">
38+
<span class="flex items-center justify-center w-8 h-8 md:w-10 md:h-10 mx-auto border-2 border-primary-100 dark:border-primary-50 shrink-0 rounded-full"
39+
[class.bg-primary-100]="currentStep === i"
40+
[class.text-white]="currentStep === i">
41+
{{ i + 1 }}
42+
</span>
43+
<span class="md:block mt-2 hidden">{{ step }}</span>
44+
</li>
45+
}
46+
</ol>
47+
48+
<h3 class="block md:hidden mt-2 text-center text-2xl text-primary-100 dark:text-white pb-4">{{ this.steps[currentStep] }}</h3>
49+
<div class="md:p-8">
5650
<div>
57-
@if(showGeneral){
58-
<h2 class="text-3xl font-bold text-primary-100 dark:text-white ml-4">{{ 'CREATE_CATALOG._general' | translate }}</h2>
51+
@if (currentStep === 0) {
5952
<form class="m-4 gap-4" [formGroup]="generalForm">
6053
<label for="prod-name" class="font-bold text-lg dark:text-white">{{ 'CREATE_CATALOG._name' | translate }}</label>
6154
<input data-cy="catalogName" formControlName="name" type="text" id="prod-name" maxLength="100"
@@ -67,18 +60,15 @@ <h2 class="text-3xl font-bold text-primary-100 dark:text-white ml-4">{{ 'CREATE_
6760
<app-markdown-textarea data-cy=catalogDsc formControlName="description"></app-markdown-textarea>
6861

6962
</form>
70-
<div class="flex w-full justify-items-end justify-end">
71-
<button data-cy="catalogNext" type="button" (click)="showFinish();generalDone=true;" [disabled]="!generalForm.valid" [ngClass]="!generalForm.valid ? 'opacity-50' : 'hover:bg-primary-50'" class="flex text-white justify-end bg-primary-100 hover:bg-primary-50 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center">
63+
<!--<div class="flex w-full justify-items-end justify-end">
64+
<button data-cy="catalogNext" type="button" (click)="goToStep(currentStep + 1)" [disabled]="!generalForm.valid" [ngClass]="!generalForm.valid ? 'opacity-50' : 'hover:bg-primary-50'" class="flex text-white justify-end bg-primary-100 hover:bg-primary-50 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center">
7265
{{ 'CREATE_CATALOG._next' | translate }}
7366
<svg class="rtl:rotate-180 w-3.5 h-3.5 ms-2" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
7467
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"/>
7568
</svg>
7669
</button>
77-
</div>
78-
}
79-
80-
@if(showSummary){
81-
<h2 class="text-3xl font-bold text-primary-100 ml-4 dark:text-white">{{ 'CREATE_CATALOG._finish' | translate }}</h2>
70+
</div>-->
71+
} @else if (currentStep === 1) {
8272
<div class="m-8">
8373
@if(loading){
8474
<div role="status" class="w-full h-full flex justify-center align-middle">
@@ -124,17 +114,58 @@ <h2 class="text-3xl font-bold text-primary-100 ml-4 dark:text-white">{{ 'CREATE_
124114
}
125115

126116

127-
<div class="flex w-full justify-items-end justify-end ml-4">
117+
<!--<div class="flex w-full justify-items-end justify-end ml-4">
128118
<button data-cy="catalogFinish" [disabled]="loading" type="button" (click)="createCatalog();" class="flex text-white justify-end bg-primary-100 hover:bg-primary-50 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center disabled:opacity-50 disabled:cursor-not-allowed">
129119
{{ 'CREATE_CATALOG._create' | translate }}
130120
<svg class="rtl:rotate-180 w-3.5 h-3.5 ms-2" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
131121
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"/>
132122
</svg>
133123
</button>
134-
</div>
124+
</div>-->
135125

136126
</div>
137127
}
128+
<!-- Navigation Buttons -->
129+
<div class="flex justify-end mt-6 space-x-4">
130+
<button (click)="goToStep(currentStep - 1)"
131+
[disabled]="currentStep === 0"
132+
[ngClass]="{
133+
'text-gray-500 dark:text-gray-400 hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-700 dark:hover:text-white': currentStep !== 0,
134+
'text-gray-300 dark:text-gray-600 cursor-not-allowed': currentStep === 0
135+
}"
136+
class="px-4 py-2 flex items-center justify-center text-base font-medium rounded-lg bg-white border border-gray-300 dark:bg-gray-800 dark:border-gray-700 ">
137+
<svg class="min-w-4 w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
138+
<path fill="currentColor"
139+
d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3
140+
256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"/>
141+
</svg>
142+
{{ 'CREATE_OFFER._previous' | translate }}
143+
</button>
144+
145+
<button data-cy=catalogNext (click)="goToStep(currentStep + 1)"
146+
[disabled]="currentStep === steps.length - 1 || !validateCurrentStep() || !canNavigate(currentStep) || !generalForm.valid"
147+
[ngClass]="{
148+
'hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-700 dark:hover:text-white': currentStep !== steps.length - 1 && (validateCurrentStep() || canNavigate(currentStep)),
149+
'cursor-not-allowed opacity-50': currentStep === steps.length - 1 || (!validateCurrentStep() || !canNavigate(currentStep))
150+
}"
151+
class="px-4 py-2 flex items-center justify-center text-base font-medium rounded-lg text-gray-500 bg-white border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400">
152+
{{ 'CREATE_OFFER._next_step' | translate }}
153+
<svg class="min-w-4 w-4 h-4 ml-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
154+
<path fill="currentColor"
155+
d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7
156+
256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"/>
157+
</svg>
158+
</button>
159+
@if(currentStep === 1){
160+
<button data-cy=catalogFinish (click)="createCatalog()"
161+
[disabled]="!generalForm.valid || loading"
162+
[ngClass]="loading || !generalForm.valid ? 'opacity-50' : 'hover:bg-primary-50'"
163+
164+
class="px-4 py-2 text-base font-medium text-white rounded-lg bg-primary-100">
165+
Create Catalog
166+
</button>
167+
}
168+
</div>
138169
</div>
139170
</div>
140171
</div>

src/app/pages/seller-offerings/offerings/seller-catalogs/create-catalog/create-catalog.component.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ export class CreateCatalogComponent implements OnInit {
2323

2424
stepsElements:string[]=['general-info','summary'];
2525
stepsCircles:string[]=['general-circle','summary-circle'];
26+
currentStep = 0;
27+
highestStep = 0;
28+
steps = [
29+
'General Info',
30+
'Summary'
31+
];
2632

2733
//markdown variables:
2834
showPreview:boolean=false;
@@ -98,6 +104,14 @@ export class CreateCatalogComponent implements OnInit {
98104

99105
showFinish(){
100106
this.finishDone=true;
107+
this.setCatalogData();
108+
this.showGeneral=false;
109+
this.showSummary=true;
110+
this.selectStep('summary','summary-circle');
111+
this.showPreview=false;
112+
}
113+
114+
setCatalogData(){
101115
if(this.generalForm.value.name!=null){
102116
this.catalogToCreate={
103117
name: this.generalForm.value.name,
@@ -114,14 +128,11 @@ export class CreateCatalogComponent implements OnInit {
114128
}
115129
console.log('CATALOG TO CREATE:')
116130
console.log(this.catalogToCreate)
117-
this.showGeneral=false;
118-
this.showSummary=true;
119-
this.selectStep('summary','summary-circle');
120131
}
121-
this.showPreview=false;
122132
}
123133

124134
createCatalog(){
135+
this.setCatalogData();
125136
this.loading=true;
126137
this.api.postCatalog(this.catalogToCreate).subscribe({
127138
next: data => {
@@ -289,4 +300,45 @@ export class CreateCatalogComponent implements OnInit {
289300
return false
290301
}
291302
}
303+
304+
goToStep(index: number) {
305+
// Solo validar en modo creación
306+
if (index > this.currentStep) {
307+
// Validar el paso actual
308+
const currentStepValid = this.validateCurrentStep();
309+
if (!currentStepValid) {
310+
return; // No permitir avanzar si el paso actual no es válido
311+
}
312+
}
313+
314+
this.currentStep = index;
315+
if(this.currentStep>this.highestStep){
316+
this.highestStep=this.currentStep
317+
}
318+
319+
if(this.currentStep==1){
320+
this.showFinish();
321+
}
322+
}
323+
324+
validateCurrentStep(): boolean {
325+
switch (this.currentStep) {
326+
case 0: // General Info
327+
return this.generalForm?.valid || false;
328+
case 1: // Product Specification
329+
return true;
330+
default:
331+
return true;
332+
}
333+
}
334+
335+
canNavigate(index: number) {
336+
return (this.generalForm?.valid && (index <= this.currentStep)) || (this.generalForm?.valid && (index <= this.highestStep));
337+
}
338+
339+
handleStepClick(index: number): void {
340+
if (this.canNavigate(index)) {
341+
this.goToStep(index);
342+
}
343+
}
292344
}

0 commit comments

Comments
 (0)