Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
David Domigues
committed
Sep 23, 2021
1 parent
66bf27f
commit 0f1adc9
Showing
9 changed files
with
198 additions
and
43 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,77 @@ | ||
import { Component } from '@angular/core'; | ||
import { MapInfoWindow, MapMarker } from '@angular/google-maps'; | ||
import { BehaviorSubject } from 'rxjs'; | ||
|
||
import { MarkerForm } from './components/marker-form.component'; | ||
import { MarkersService } from './markers.service'; | ||
import { MarkerData } from './models/marker-data'; | ||
|
||
@Component({ | ||
selector: 'app-root', | ||
styleUrls: ['./app.component.scss'], | ||
template: ` | ||
<google-map [options]="options" width="100vw" height="100vh" (mapClick)="onClick($event)"> | ||
<google-map [options]="options" width="100vw" height="100vh" (mapClick)="onAddMarker($event, info, markerForm)"> | ||
<!-- MARKERS --> | ||
<map-marker | ||
#marker="mapMarker" | ||
*ngFor="let data of markersService.markers$ | async" | ||
[position]="data" | ||
[options]="markerOptions" | ||
(mapClick)="onOpenInfo(marker, info, data, paragraph, image)" | ||
*ngFor="let data of markers$ | async; trackBy: trackFn" | ||
[position]="{ lat: +data.lat, lng: +data.long }" | ||
(mapClick)="onViewMarker(marker, info, data, markerForm)" | ||
></map-marker> | ||
<!-- INFO --> | ||
<!-- MARKER FORM --> | ||
<map-info-window #info="mapInfoWindow"> | ||
<p #paragraph></p> | ||
<img #image alt="" /> | ||
<marker-form #markerForm (submitted)="onRefresh()"></marker-form> | ||
</map-info-window> | ||
</google-map> | ||
<pre> | ||
{{ markersService.markers$ | async | json }} | ||
<!-- <pre> | ||
{{ markers$ | async | json }} | ||
</pre | ||
> | ||
> --> | ||
`, | ||
}) | ||
export class AppComponent { | ||
refresh = new BehaviorSubject(null); | ||
markers$ = this.mrkrService.getMarkers(this.refresh); | ||
|
||
options: google.maps.MapOptions = { | ||
center: { lat: 40.4378698, lng: -3.8196208 }, | ||
center: { lat: 42, lng: -1 }, | ||
zoom: 6, | ||
}; | ||
|
||
markerOptions: google.maps.MarkerOptions = { draggable: false }; | ||
markerPositions: google.maps.LatLngLiteral[] = []; | ||
constructor(private mrkrService: MarkersService) {} | ||
|
||
onAddMarker(event: google.maps.MapMouseEvent, infoWindow: MapInfoWindow, markerForm: MarkerForm) { | ||
const position = event.latLng.toJSON(); | ||
|
||
markerForm.form.reset(); | ||
markerForm.form.patchValue({ | ||
lat: position.lat, | ||
long: position.lng, | ||
}); | ||
|
||
constructor(public markersService: MarkersService) {} | ||
infoWindow.options = { position }; | ||
infoWindow.open(); | ||
} | ||
|
||
onViewMarker(marker: MapMarker, infoWindow: MapInfoWindow, mrkData: MarkerData, markerForm: MarkerForm) { | ||
this.mrkrService.getMarkersById(mrkData.id).subscribe((data) => { | ||
markerForm.form.reset(); | ||
markerForm.form.patchValue(data); | ||
infoWindow.open(marker); | ||
}); | ||
} | ||
|
||
onClick(event: google.maps.MapMouseEvent) { | ||
this.markerPositions.push(event.latLng.toJSON()); | ||
ngAfterViewInit() { | ||
setTimeout(() => { | ||
const dismissButton: HTMLButtonElement = document.querySelector('.dismissButton'); | ||
dismissButton && dismissButton.click(); | ||
}, 1000); | ||
} | ||
|
||
onOpenInfo(marker: MapMarker, infoWindow: MapInfoWindow, mrkData: MarkerData, paragraph: HTMLParagraphElement, image: HTMLImageElement) { | ||
image.src = mrkData.image_url; | ||
paragraph.innerText = mrkData.content; | ||
infoWindow.open(marker); | ||
onRefresh() { | ||
this.refresh.next(null); | ||
} | ||
|
||
trackFn = (idx, { id }) => id; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,16 @@ | ||
import { CommonModule } from '@angular/common'; | ||
import { HttpClientModule } from '@angular/common/http'; | ||
import { NgModule } from '@angular/core'; | ||
import { ReactiveFormsModule } from '@angular/forms'; | ||
import { GoogleMapsModule } from '@angular/google-maps'; | ||
import { BrowserModule } from '@angular/platform-browser'; | ||
|
||
import { AppRoutingModule } from './app-routing.module'; | ||
import { AppComponent } from './app.component'; | ||
import { MarkerForm } from './components/marker-form.component'; | ||
|
||
@NgModule({ | ||
declarations: [AppComponent], | ||
imports: [BrowserModule, AppRoutingModule, HttpClientModule, GoogleMapsModule], | ||
declarations: [AppComponent, MarkerForm], | ||
imports: [BrowserModule, HttpClientModule, CommonModule, GoogleMapsModule, ReactiveFormsModule], | ||
bootstrap: [AppComponent], | ||
}) | ||
export class AppModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
.form-fields { | ||
display: grid; | ||
gap: 5px; | ||
grid-template-columns: 75px auto; | ||
|
||
b { | ||
text-align: right; | ||
line-height: 20px; | ||
} | ||
|
||
input, | ||
textarea { | ||
width: 100%; | ||
box-sizing: border-box; | ||
border: none; | ||
border-bottom: 2px solid #e2bdbd; | ||
|
||
&:focus-visible { | ||
outline: none; | ||
border-bottom: 2px solid #b79191; | ||
} | ||
} | ||
} | ||
|
||
img { | ||
width: 20vw; | ||
margin: 4px auto; | ||
display: block; | ||
} | ||
|
||
button { | ||
border: none; | ||
color: white; | ||
padding: 8px; | ||
text-align: center; | ||
font-size: 14px; | ||
cursor: pointer; | ||
width: 50%; | ||
|
||
&[type='submit'] { | ||
background: #4caf50; | ||
|
||
&:disabled { | ||
background: #4caf509c; | ||
} | ||
|
||
&:active { | ||
background: #4caf50e0; | ||
} | ||
} | ||
|
||
&[type='button'] { | ||
background: #fb3324; | ||
|
||
&:active { | ||
background: #fb3324ab; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Component, EventEmitter, Output } from '@angular/core'; | ||
import { FormControl, FormGroup } from '@angular/forms'; | ||
import { MapInfoWindow } from '@angular/google-maps'; | ||
|
||
import { MarkersService } from './../markers.service'; | ||
|
||
@Component({ | ||
selector: 'marker-form', | ||
styleUrls: ['marker-form.component.scss'], | ||
template: ` | ||
<form [formGroup]="form" (ngSubmit)="onSubmit()"> | ||
<div class="form-fields"> | ||
<b> Title: </b> | ||
<input formControlName="title" required /> | ||
<b> Content: </b> | ||
<textarea rows="5" formControlName="content" required></textarea> | ||
<b> Image URL: </b> | ||
<input #image formControlName="image_url" /> | ||
</div> | ||
<img [src]="image.value" alt="insert a valid image URL" /> | ||
<button type="submit" [disabled]="form.invalid">SUBMIT</button> | ||
<button *ngIf="markerId" type="button" (click)="onDelete()">DELETE</button> | ||
</form> | ||
`, | ||
}) | ||
export class MarkerForm { | ||
form = new FormGroup({ | ||
id: new FormControl(), | ||
title: new FormControl(), | ||
content: new FormControl(), | ||
image_url: new FormControl(), | ||
lat: new FormControl(), | ||
long: new FormControl(), | ||
}); | ||
|
||
@Output() submitted = new EventEmitter(); | ||
|
||
get markerId() { | ||
return this.form.get('id').value; | ||
} | ||
|
||
constructor(private infoWindow: MapInfoWindow, private mrkService: MarkersService) {} | ||
|
||
onSubmit() { | ||
this.mrkService.submitMarker(this.form.getRawValue()).subscribe((next) => { | ||
this.submitted.emit(next); | ||
this.infoWindow.close(); | ||
}); | ||
} | ||
|
||
onDelete() { | ||
this.mrkService.deleteMarker(this.markerId).subscribe((next) => { | ||
this.submitted.emit(next); | ||
this.infoWindow.close(); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,31 @@ | ||
import { HttpClient } from '@angular/common/http'; | ||
import { Injectable } from '@angular/core'; | ||
import { map } from 'rxjs/operators'; | ||
import { iif, Subject } from 'rxjs'; | ||
import { switchMap } from 'rxjs/operators'; | ||
|
||
import { MarkerData } from './models/marker-data'; | ||
|
||
@Injectable({ providedIn: 'root' }) | ||
export class MarkersService { | ||
markers$ = this.http | ||
.get('http://localhost:3000/api/v1/posts') | ||
.pipe(map((markers: any[]) => markers.map((m) => ({ ...m, lat: +m.lat, lng: +m.long })))); | ||
|
||
constructor(private http: HttpClient) {} | ||
|
||
getMarkers(refreshSignal: Subject<null>) { | ||
return refreshSignal.pipe(switchMap(() => this.http.get('http://localhost:3000/api/v1/posts'))); | ||
} | ||
|
||
getMarkersById(id: number) { | ||
return this.http.get(`http://localhost:3000/api/v1/posts/${id}`); | ||
} | ||
|
||
submitMarker(body: Partial<MarkerData>) { | ||
return iif( | ||
() => !!body.id, | ||
this.http.put(`http://localhost:3000/api/v1/posts/${body.id}`, body), | ||
this.http.post('http://localhost:3000/api/v1/posts', body) | ||
); | ||
} | ||
|
||
deleteMarker(id: number) { | ||
return this.http.delete(`http://localhost:3000/api/v1/posts/${id}`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
html, | ||
body { | ||
height: 100%; | ||
} | ||
body { | ||
margin: 0; | ||
font-family: Ubuntu-Regular; | ||
font-family: Roboto, 'Helvetica Neue', sans-serif; | ||
} |