Skip to content

Commit

Permalink
refactor: extract app home to a component
Browse files Browse the repository at this point in the history
  • Loading branch information
Fernanda-Kipper committed Jun 3, 2024
1 parent 97e6acd commit 326af29
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 306 deletions.
176 changes: 1 addition & 175 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,175 +1 @@
<app-header></app-header>

<main id="content" class="bg-white py-24 sm:py-32">
<div class="mx-auto max-w-7xl px-6 lg:px-8">
<div id="list-header" class="mx-auto max-w-2xl text-center mb-6">
<h2 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
Lista de Eventos
</h2>
<p class="mt-2 text-lg leading-8 text-gray-600">
Aqui você irá encontrar a lista de próximos eventos de tecnologia que
irão rolar no Brasil compartilhados pela comunidade!
</p>
</div>
<div id="event-filter" class="relative">
<div class="absolute inset-0 flex items-center" aria-hidden="true">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center">
<div class="flex items-center justify-center">
<span class="relative inline-flex">
<button
(click)="toggleModal()"
type="button"
class="rounded-xl inline-flex items-center px-6 py-1 font-semibold leading-6 text-sm shadow bg-white hover:bg-gray-50 dark:bg-slate-800 dark:hover:bg-slate-600 dark:text-white transition ease-in-out duration-150 cursor-pointer ring-1 ring-slate-900/10 dark:ring-slate-200/20"
>
<svg
class="-ml-1 -mr-0.5 h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
/>
</svg>
Filtro
</button>
<span
class="flex {{
isFilterActive()
}} absolute h-3 w-3 top-0 right-0 -mt-1 -mr-1"
>
<span
class="animate-ping absolute inline-flex h-full w-full rounded-full bg-indigo-600 opacity-75"
></span>
<span
class="relative inline-flex rounded-full h-3 w-3 bg-indigo-600"
></span>
</span>
</span>
</div>
</div>
</div>
<div
id="event-list"
class="mt-16 flex justify-center w-full sm:mt-20 lg:mx-0"
>
<ul class="-my-8 grid grid-cols-3 gap-7 w-full divide-y divide-gray-100">
@for (event of eventList; track event) {
<app-event
[url]="event.url"
[banner]="event.banner"
[title]="event.title"
[description]="event.description"
[date]="event.date"
[place]="event.place"
>{{ event }}</app-event
>
}
</ul>
</div>
</div>
</main>
<app-modal [isModalOpen]="isModalOpen" (closeModal)="toggleModal()">
<div>
<div class="mt-3 text-center sm:mt-5">
<h3
class="text-base font-semibold leading-6 text-gray-900"
id="modal-title"
>
Selecione os filtros
</h3>
</div>
</div>
<form [formGroup]="filterForm">
<div class="mb-5">
<label
for="stateDropdown"
class="mb-3 block text-base font-medium text-[#07074D]"
>
Estado
</label>
<select
id="stateDropdown"
formControlName="locale"
class="w-full rounded-md border py-3 px-6 outline-none"
(change)="stateSelect2()"
>
@for (option of states; track option.label) {
<option [value]="option.id">{{ option.label }}</option>
}
</select>
</div>
<div class="mb-5">
<label
for="cityDropdown"
class="mb-3 block text-base font-medium text-[#07074D]"
>
Cidade
</label>
<select
id="cityDropdown"
formControlName="city"
class="w-full rounded-md border py-3 px-6 outline-none"
>
@for (option of cities; track option.label) {
<option [value]="option.value">{{ option.label }}</option>
}
</select>
</div>
<div class="-mx-3 flex flex-wrap">
<div class="w-full px-3 sm:w-1/2">
<div class="mb-5">
<label
for="date"
class="mb-3 block text-base font-medium text-[#07074D]"
>
De
</label>
<input
formControlName="from"
type="date"
name="date"
id="date"
class="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md"
/>
</div>
</div>
<div class="w-full px-3 sm:w-1/2">
<div class="mb-5">
<label
for="date"
class="mb-3 block text-base font-medium text-[#07074D]"
>
Até
</label>
<input
formControlName="to"
type="date"
name="date"
id="date"
class="w-full rounded-md border border-[#e0e0e0] bg-white py-3 px-6 text-base font-medium text-[#6B7280] outline-none focus:border-[#6A64F1] focus:shadow-md"
/>
</div>
</div>
</div>
<div class="mt-5 flex flex-col gap-2 sm:mt-6">
<button
(click)="submit()"
[disabled]="!filterForm.valid"
type="button"
class="inline-flex w-full justify-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 disabled:bg-red-400 disabled:hover:bg-red-300 disabled:cursor-not-allowed"
>
Aplicar
</button>
<button
(click)="clearFilter()"
type="button"
class="inline-flex w-full justify-center rounded-md bg-indigo-400 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-300 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
Limpar filtro
</button>
</div>
</form>
</app-modal>
<router-outlet></router-outlet>
133 changes: 3 additions & 130 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,138 +1,11 @@
import {
Component,
ElementRef,
OnInit,
signal,
ViewChild,
} from '@angular/core';
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {
FormControl,
FormGroup,
ReactiveFormsModule,
Validators,
} from '@angular/forms';
import { CommonModule } from '@angular/common';

import { NgSelectModule } from '@ng-select/ng-select';

import { EventComponent } from './components/event/event.component';
import { ModalComponent } from './components/modal/modal.component';
import { HeaderComponent } from './header/header.component';
import { FilterService } from './services/filter.service';
import { UF } from './types/UF.type';
import { City } from './types/City.type';
import { EventItem } from './types/Event.type';

interface FilterForm {
locale: FormControl<string | null>;
city: FormControl<string | null>;
from: FormControl<Date | null>;
to: FormControl<Date | null>;
}

@Component({
selector: 'app-root',
standalone: true,
imports: [
RouterOutlet,
CommonModule,
NgSelectModule,
ReactiveFormsModule,
ModalComponent,
EventComponent,
HeaderComponent,
],
imports: [RouterOutlet],
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
@ViewChild('stateSelect') stateSelect!: ElementRef<HTMLSelectElement>;

filterForm!: FormGroup<FilterForm>;
isModalOpen = signal(false);

states: { id: number; label: string; value: string }[] = [];
cities: { id: number; label: string; value: string }[] = [];

eventList: EventItem[] = [];

filterIsActive = false;

constructor(private filterService: FilterService) {}

ngOnInit() {
this.filterForm = new FormGroup<FilterForm>({
locale: new FormControl<string | null>(null, [Validators.required]),
city: new FormControl<string | null>(null, [Validators.required]),
from: new FormControl<Date | null>(null, [Validators.required]),
to: new FormControl<Date | null>(null, [Validators.required]),
});

this.loadLocalesFilter();

this.eventList = [
{
title: 'Frontin Sampa',
place: 'São Paulo',
date: '19/10/2024',
description: 'Maior evento de Frontend do Brasil!',
banner: 'https://images.sympla.com.br/630305a3009a1-lg.png',
url: 'https://frontinsampa.com.br/',
},
];
}

loadLocalesFilter() {
this.filterService.loadLocales().subscribe({
next: (body: UF[]) => {
this.states = body.map((value) => ({
id: value.id,
label: value.nome,
value: value.sigla,
}));
},
});
}

loadCities(selectedState: number) {
this.filterService.loadCitiesByState(selectedState).subscribe({
next: (cities: City[]) => {
this.cities = cities.map((city) => ({
id: city.id,
label: city.nome,
value: city.nome,
}));
},
error: (error) => {
console.error('Error loading cities:', error);
// Handle the error (e.g., show an error message to the user)
},
});
}

stateSelect2() {
const selectedStateValue = this.filterForm.get('locale')!.value;
if (selectedStateValue) {
this.loadCities(Number(selectedStateValue));
}
}

toggleModal() {
this.isModalOpen.update((value) => !value);
}

submit() {
this.isModalOpen.set(false);
this.filterIsActive = true;
}

isFilterActive() {
return this.filterIsActive ? 'visible' : 'invisible';
}

clearFilter() {
this.filterIsActive = false;
this.filterForm.reset();
}
}
export class AppComponent {}
13 changes: 12 additions & 1 deletion src/app/app.routes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
import { Routes } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { RegisterEventComponent } from './pages/register-event/register-event.component';

export const routes: Routes = [];
export const routes: Routes = [
{
path: '',
component: HomeComponent,
},
{
path: 'registra-evento',
component: RegisterEventComponent,
},
];
Loading

0 comments on commit 326af29

Please sign in to comment.