Feature: Create Event - First Step Frontend #17

Merged
igorpropisnov merged 20 commits from feature/create-event into main 2024-08-22 14:58:36 +02:00
4 changed files with 69 additions and 36 deletions
Showing only changes of commit 584f34f947 - Show all commits

View File

@ -1,5 +1,5 @@
<div class="flex flex-col h-full">
<div class="w-full bg-neutral max-w-full sticky top-0 z-20 pt-2">
<div class="w-full bg-base-100 max-w-full sticky top-0 z-10 pt-4">
<ul class="steps steps-horizontal w-full py-2">
@for (step of steps; track $index) {
<li
@ -30,34 +30,38 @@
</div>
<div
class="w-full bg-neutral max-w-full sticky bottom-0 z-20 px-4 sm:px-8 py-4">
class="w-full bg-base-100 max-w-full sticky bottom-0 z-10 px-4 sm:px-8 py-4">
<div class="flex justify-between max-w-4xl mx-auto">
<button
type="button"
class="btn btn-primary"
(click)="prevStep()"
[disabled]="currentStep() === 0"
[class.opacity-50]="currentStep() === 0">
<div>
@if (currentStep() > 0) {
<span>
Back to
<span class="font-bold">{{ steps[currentStep() - 1] }}</span>
</span>
<button
type="button"
class="btn btn-primary btn-outline"
(click)="prevStep()"
[disabled]="currentStep() === 0"
[class.opacity-50]="currentStep() === 0">
<span>
Back to
<span class="font-bold">{{ steps[currentStep() - 1] }}</span>
</span>
</button>
}
</button>
<button
type="button"
class="btn btn-primary"
(click)="nextStep()"
[disabled]="currentStep() === steps.length - 1"
[class.opacity-50]="currentStep() === steps.length - 1">
</div>
<div>
@if (currentStep() < steps.length - 1) {
<span>
Next to
<span class="font-bold">{{ steps[currentStep() + 1] }}</span>
</span>
<button
type="button"
class="btn btn-primary btn-outline"
(click)="nextStep()"
[disabled]="currentStep() === steps.length - 1"
[class.opacity-50]="currentStep() === steps.length - 1">
<span>
Next to
<span class="font-bold">{{ steps[currentStep() + 1] }}</span>
</span>
</button>
}
</button>
</div>
</div>
</div>
</div>

View File

@ -65,10 +65,6 @@
<span class="label-text-alt"></span>
</div>
</label>
<div>
<pre>{{ form().value | json }}</pre>
</div>
</div>
</form>

View File

@ -24,7 +24,8 @@
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-6"
class="size-6 cursor-pointer"
(click)="toggleDropdown()"
[class.rotate-180]="showDropdown()">
<path
stroke-linecap="round"
@ -34,6 +35,8 @@
</label>
@if (showDropdown()) {
<ul
(mouseenter)="onDropdownMouseEnter()"
(mouseleave)="onDropdownMouseLeave()"
class="menu bg-base-100 w-full mt-1 shadow-lg rounded-box absolute top-full left-0 z-10">
@if (filteredItems().length > 0) {
@for (item of filteredItems(); track item) {
@ -61,7 +64,7 @@
</svg>
} @else {
<div
class="tooltip tooltip-info"
class="tooltip tooltip-primary tooltip-left"
data-tip="Edit this location's details. You can modify the name, address, or any other relevant information associated with this place.">
<svg
xmlns="http://www.w3.org/2000/svg"

View File

@ -1,7 +1,9 @@
import { CommonModule } from '@angular/common';
import {
Component,
ElementRef,
forwardRef,
HostListener,
input,
InputSignal,
output,
@ -57,6 +59,16 @@ export class DropdownComponent implements ControlValueAccessor, Validator {
public itemSelected: OutputEmitterRef<string> = output<string>();
public submitNewItems: OutputEmitterRef<boolean> = output<boolean>();
public itemEdit: OutputEmitterRef<string> = output<string>();
private isMouseInDropdown: WritableSignal<boolean> = signal<boolean>(false);
public constructor(private readonly elementRef: ElementRef) {}
@HostListener('document:click', ['$event'])
public onDocumentClick(event: MouseEvent): void {
if (!this.elementRef.nativeElement.contains(event.target)) {
this.closeDropdown();
}
}
public writeValue(value: string | null): void {
if (value && this.isValidOption(value)) {
@ -88,6 +100,23 @@ export class DropdownComponent implements ControlValueAccessor, Validator {
return null;
}
public onDropdownMouseEnter(): void {
this.isMouseInDropdown.set(true);
}
public onDropdownMouseLeave(): void {
this.isMouseInDropdown.set(false);
}
public closeDropdown(): void {
this.showDropdown.set(false);
this.isMouseInDropdown.set(false);
}
public toggleDropdown(): void {
this.showDropdown.set(!this.showDropdown());
}
public onInput(event: Event): void {
const value = (event.target as HTMLInputElement).value;
@ -113,7 +142,8 @@ export class DropdownComponent implements ControlValueAccessor, Validator {
this.itemSelected.emit('');
}
this.showDropdown.set(true);
this.showDropdown.set(matchingItems.length > 0 || value.trim() !== '');
this.onTouched();
}
@ -142,7 +172,7 @@ export class DropdownComponent implements ControlValueAccessor, Validator {
if (this.isValidOption(item)) {
this.searchTerm.set(item);
this.selectedItem.set(item);
this.showDropdown.set(false);
this.closeDropdown();
this.itemSelected.emit(item);
this.onChange(item);
this.onTouched();
@ -150,6 +180,7 @@ export class DropdownComponent implements ControlValueAccessor, Validator {
}
public submitNewItem(): void {
this.closeDropdown();
this.submitNewItems.emit(true);
}
@ -161,15 +192,14 @@ export class DropdownComponent implements ControlValueAccessor, Validator {
}
public onFocus(): void {
this.showDropdown.set(true);
this.filteredItems.set(this.items());
}
public onBlur(): void {
setTimeout(() => {
this.showDropdown.set(false);
if (!this.isMouseInDropdown) {
this.closeDropdown();
this.onTouched();
}, 100);
}
}
private isValidOption(value: string): boolean {