diff --git a/angular.json b/angular.json
index 64ccb1d3e8afb31161751d7557add12e6027903c..b81fd06fd589b07d081ed824bafbcae59ef452e6 100644
--- a/angular.json
+++ b/angular.json
@@ -34,6 +34,7 @@
               "src/assets"
             ],
             "styles": [
+              "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
               "src/styles.scss"
             ],
             "scripts": []
@@ -102,6 +103,7 @@
               "src/assets"
             ],
             "styles": [
+              "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
               "src/styles.scss"
             ],
             "scripts": []
diff --git a/package-lock.json b/package-lock.json
index a18d2d33d5a37a29543a2606fdc0ddccb3ce489a..0b70bdae1d79cb0e889297624aa8f767626e52e7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,13 +9,17 @@
       "version": "0.0.0",
       "dependencies": {
         "@angular/animations": "~12.2.0",
+        "@angular/cdk": "^12.2.9",
         "@angular/common": "~12.2.0",
         "@angular/compiler": "~12.2.0",
         "@angular/core": "~12.2.0",
         "@angular/forms": "~12.2.0",
+        "@angular/material": "^12.2.9",
         "@angular/platform-browser": "~12.2.0",
         "@angular/platform-browser-dynamic": "~12.2.0",
         "@angular/router": "~12.2.0",
+        "@asymmetrik/ngx-leaflet": "^8.1.0",
+        "leaflet": "^1.7.1",
         "rxjs": "~6.6.0",
         "tslib": "^2.3.0",
         "zone.js": "~0.11.4"
@@ -25,6 +29,7 @@
         "@angular/cli": "~12.2.9",
         "@angular/compiler-cli": "~12.2.0",
         "@types/jasmine": "~3.8.0",
+        "@types/leaflet": "^1.7.5",
         "@types/node": "^12.11.1",
         "jasmine-core": "~3.8.0",
         "karma": "~6.3.0",
@@ -289,6 +294,28 @@
         "@angular/core": "12.2.9"
       }
     },
+    "node_modules/@angular/cdk": {
+      "version": "12.2.9",
+      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-12.2.9.tgz",
+      "integrity": "sha512-9Wgj69iGAZ4teQqW/zPbVg2RGna+m9i3v0zkWGx/+Uo95rikJCUZBQM4bfeOe+bSJrS77jV5EisBWG7ayNUSzQ==",
+      "dependencies": {
+        "tslib": "^2.2.0"
+      },
+      "optionalDependencies": {
+        "parse5": "^5.0.0"
+      },
+      "peerDependencies": {
+        "@angular/common": "^12.0.0 || ^13.0.0-0",
+        "@angular/core": "^12.0.0 || ^13.0.0-0",
+        "rxjs": "^6.5.3 || ^7.0.0"
+      }
+    },
+    "node_modules/@angular/cdk/node_modules/parse5": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+      "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+      "optional": true
+    },
     "node_modules/@angular/cli": {
       "version": "12.2.9",
       "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-12.2.9.tgz",
@@ -427,6 +454,22 @@
         "rxjs": "^6.5.3 || ^7.0.0"
       }
     },
+    "node_modules/@angular/material": {
+      "version": "12.2.9",
+      "resolved": "https://registry.npmjs.org/@angular/material/-/material-12.2.9.tgz",
+      "integrity": "sha512-+eM67RF038S56m3wsj37h0PyyRD18cQ8V2zmKG1UezH0nnosbmCAwzH9BfcNiIB+/V+k5QMJ/JVu5MjDQqX37w==",
+      "dependencies": {
+        "tslib": "^2.2.0"
+      },
+      "peerDependencies": {
+        "@angular/animations": "^12.0.0 || ^13.0.0-0",
+        "@angular/cdk": "12.2.9",
+        "@angular/common": "^12.0.0 || ^13.0.0-0",
+        "@angular/core": "^12.0.0 || ^13.0.0-0",
+        "@angular/forms": "^12.0.0 || ^13.0.0-0",
+        "rxjs": "^6.5.3 || ^7.0.0"
+      }
+    },
     "node_modules/@angular/platform-browser": {
       "version": "12.2.9",
       "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-12.2.9.tgz",
@@ -488,6 +531,17 @@
       "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==",
       "dev": true
     },
+    "node_modules/@asymmetrik/ngx-leaflet": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@asymmetrik/ngx-leaflet/-/ngx-leaflet-8.1.0.tgz",
+      "integrity": "sha512-lq7LduBP/vXcaSEmKnx7mzCR8WsoYqh9pB6BNnq53yeCwsqRbG3GdKye1/i8VvoRzjDsmQBPQsIFZ9uclXrtgg==",
+      "peerDependencies": {
+        "@angular/common": ">=10",
+        "@angular/core": ">=10",
+        "leaflet": "1",
+        "tslib": "2"
+      }
+    },
     "node_modules/@babel/code-frame": {
       "version": "7.15.8",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz",
@@ -2486,6 +2540,12 @@
       "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
       "dev": true
     },
+    "node_modules/@types/geojson": {
+      "version": "7946.0.8",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
+      "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==",
+      "dev": true
+    },
     "node_modules/@types/glob": {
       "version": "7.1.4",
       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz",
@@ -2508,6 +2568,15 @@
       "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
       "dev": true
     },
+    "node_modules/@types/leaflet": {
+      "version": "1.7.5",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.5.tgz",
+      "integrity": "sha512-+Myo00Yb5OuvUyrH+vUwn9DRgOaBJsF/etIMdMcNhWGBMo58Mo1cxLInvCd0ZpvItju/AeDYFB/Od2pLiHB3VA==",
+      "dev": true,
+      "dependencies": {
+        "@types/geojson": "*"
+      }
+    },
     "node_modules/@types/minimatch": {
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
@@ -8326,6 +8395,11 @@
         "node": ">= 8"
       }
     },
+    "node_modules/leaflet": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz",
+      "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw=="
+    },
     "node_modules/less": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/less/-/less-4.1.1.tgz",
@@ -16055,6 +16129,23 @@
         "tslib": "^2.2.0"
       }
     },
+    "@angular/cdk": {
+      "version": "12.2.9",
+      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-12.2.9.tgz",
+      "integrity": "sha512-9Wgj69iGAZ4teQqW/zPbVg2RGna+m9i3v0zkWGx/+Uo95rikJCUZBQM4bfeOe+bSJrS77jV5EisBWG7ayNUSzQ==",
+      "requires": {
+        "parse5": "^5.0.0",
+        "tslib": "^2.2.0"
+      },
+      "dependencies": {
+        "parse5": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+          "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+          "optional": true
+        }
+      }
+    },
     "@angular/cli": {
       "version": "12.2.9",
       "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-12.2.9.tgz",
@@ -16144,6 +16235,14 @@
         "tslib": "^2.2.0"
       }
     },
+    "@angular/material": {
+      "version": "12.2.9",
+      "resolved": "https://registry.npmjs.org/@angular/material/-/material-12.2.9.tgz",
+      "integrity": "sha512-+eM67RF038S56m3wsj37h0PyyRD18cQ8V2zmKG1UezH0nnosbmCAwzH9BfcNiIB+/V+k5QMJ/JVu5MjDQqX37w==",
+      "requires": {
+        "tslib": "^2.2.0"
+      }
+    },
     "@angular/platform-browser": {
       "version": "12.2.9",
       "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-12.2.9.tgz",
@@ -16174,6 +16273,12 @@
       "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==",
       "dev": true
     },
+    "@asymmetrik/ngx-leaflet": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@asymmetrik/ngx-leaflet/-/ngx-leaflet-8.1.0.tgz",
+      "integrity": "sha512-lq7LduBP/vXcaSEmKnx7mzCR8WsoYqh9pB6BNnq53yeCwsqRbG3GdKye1/i8VvoRzjDsmQBPQsIFZ9uclXrtgg==",
+      "requires": {}
+    },
     "@babel/code-frame": {
       "version": "7.15.8",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz",
@@ -17625,6 +17730,12 @@
       "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
       "dev": true
     },
+    "@types/geojson": {
+      "version": "7946.0.8",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
+      "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==",
+      "dev": true
+    },
     "@types/glob": {
       "version": "7.1.4",
       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz",
@@ -17647,6 +17758,15 @@
       "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
       "dev": true
     },
+    "@types/leaflet": {
+      "version": "1.7.5",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.5.tgz",
+      "integrity": "sha512-+Myo00Yb5OuvUyrH+vUwn9DRgOaBJsF/etIMdMcNhWGBMo58Mo1cxLInvCd0ZpvItju/AeDYFB/Od2pLiHB3VA==",
+      "dev": true,
+      "requires": {
+        "@types/geojson": "*"
+      }
+    },
     "@types/minimatch": {
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
@@ -22188,6 +22308,11 @@
       "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==",
       "dev": true
     },
+    "leaflet": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz",
+      "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw=="
+    },
     "less": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/less/-/less-4.1.1.tgz",
diff --git a/package.json b/package.json
index d5b79a2d836277a1553a35a943c03d775d8768bc..349ac8144b9cc3baf8634eb3c885627c4a3c182b 100644
--- a/package.json
+++ b/package.json
@@ -11,13 +11,17 @@
   "private": true,
   "dependencies": {
     "@angular/animations": "~12.2.0",
+    "@angular/cdk": "^12.2.9",
     "@angular/common": "~12.2.0",
     "@angular/compiler": "~12.2.0",
     "@angular/core": "~12.2.0",
     "@angular/forms": "~12.2.0",
+    "@angular/material": "^12.2.9",
     "@angular/platform-browser": "~12.2.0",
     "@angular/platform-browser-dynamic": "~12.2.0",
     "@angular/router": "~12.2.0",
+    "@asymmetrik/ngx-leaflet": "^8.1.0",
+    "leaflet": "^1.7.1",
     "rxjs": "~6.6.0",
     "tslib": "^2.3.0",
     "zone.js": "~0.11.4"
@@ -27,6 +31,7 @@
     "@angular/cli": "~12.2.9",
     "@angular/compiler-cli": "~12.2.0",
     "@types/jasmine": "~3.8.0",
+    "@types/leaflet": "^1.7.5",
     "@types/node": "^12.11.1",
     "jasmine-core": "~3.8.0",
     "karma": "~6.3.0",
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 0680b43f9c6ae05df91c576141f20ed411d07c7d..e355942728719d67ca168d95bb59d85e5862511f 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1 +1,8 @@
+<div class="wrapper">
+    <h1>Consumer</h1> 
+</div>
+
+
+<app-map class="wrapper"></app-map>
+
 <router-outlet></router-outlet>
diff --git a/src/app/app.component.scss b/src/app/app.component.scss
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..11343d6aaab51e1f55c84f3561a8ef0c1eb6fb38 100644
--- a/src/app/app.component.scss
+++ b/src/app/app.component.scss
@@ -0,0 +1,5 @@
+@import './src/variables.scss';
+
+.wrapper { 
+    padding: 0 calc((100% - #{$break-large})/2);
+}
\ No newline at end of file
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index b1c6c96a9de8f091f39b3b8feb7e29cfcfb1ed81..b3911649ab532de15c28c800667b3ea031e29c57 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,18 +1,43 @@
 import { NgModule } from '@angular/core';
 import { BrowserModule } from '@angular/platform-browser';
 
-import { AppRoutingModule } from './app-routing.module';
+// --- Map
+import { LeafletModule } from '@asymmetrik/ngx-leaflet';
+
+// --- WS
+// import * as SockJS from 'sockjs-client';
+
+// --- Modules
+import { SharedModule } from './shared/shared.module';
+import { CoreModule } from './core/core.module';
+
+// --- Services
+import { ApiService } from "./core/api.service";
+// import { StompService, StompConfig } from '@stomp/ng2-stompjs';
+import { environment } from './../environments/environment';
+
+// --- Components
 import { AppComponent } from './app.component';
+import { MapComponent } from './components/map/map.component';
+import { AppRoutingModule } from './app-routing.module';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+
 
 @NgModule({
   declarations: [
-    AppComponent
+    AppComponent,
+    MapComponent
   ],
   imports: [
     BrowserModule,
-    AppRoutingModule
+    AppRoutingModule,
+    SharedModule,
+    CoreModule,
+    LeafletModule,
+    BrowserAnimationsModule
   ],
-  providers: [],
+  providers: [ApiService],
   bootstrap: [AppComponent]
 })
 export class AppModule { }
diff --git a/src/app/components/map/map.component.html b/src/app/components/map/map.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..2da3bd7a5c4412170d7849fc993266781fe285f7
--- /dev/null
+++ b/src/app/components/map/map.component.html
@@ -0,0 +1,5 @@
+<div style="height: 80vh;" 
+    leaflet 
+    [leafletOptions]="options"
+    (leafletMapReady)="onMapReady($event)">
+</div> 
\ No newline at end of file
diff --git a/src/app/components/map/map.component.scss b/src/app/components/map/map.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/components/map/map.component.spec.ts b/src/app/components/map/map.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..449dba05078e4b01d37c7b5c39c65eee88582e04
--- /dev/null
+++ b/src/app/components/map/map.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MapComponent } from './map.component';
+
+describe('MapComponent', () => {
+  let component: MapComponent;
+  let fixture: ComponentFixture<MapComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ MapComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(MapComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/components/map/map.component.ts b/src/app/components/map/map.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6a9ca6e87e9c0f93ee6065c3faba5c3f9ecfbab8
--- /dev/null
+++ b/src/app/components/map/map.component.ts
@@ -0,0 +1,122 @@
+import { NONE_TYPE } from '@angular/compiler';
+import { Component, OnInit } from '@angular/core';
+import * as L from "leaflet";
+
+class Location {
+  id: string;
+  type = 'position';
+  lat: Float32Array;
+  lng: Float32Array;
+
+  constructor(obj: any, id: any) {
+    this.id = id
+    this.lat = obj.lat
+    this.lng = obj.lng
+  }
+}
+
+class Measurements {
+  id: string
+  type = 'measurements'
+  data: number[];
+
+  constructor(dist: any, id: any) {
+    this.id = id
+    this.data = dist
+  }
+}
+
+@Component({
+  selector: 'app-map',
+  templateUrl: './map.component.html',
+  styleUrls: ['./map.component.scss']
+})
+export class MapComponent implements OnInit {
+
+  _stompService: any; 
+  map: L.Map;
+
+  constructor() {
+    this.map = L.map('map', {
+        center: [51.505, -0.09],
+        zoom: 13
+    });
+  }
+
+  ngOnInit(): void { 
+    // wait on new Location
+    this._stompService.watch('/topic/locations').subscribe((message: any) => {
+      let payload = JSON.parse(message.body);
+      this.addNewMarker(payload)
+    });
+
+    // wait on new measurements
+    this._stompService.watch('/topic/positions').subscribe((message: any) => {
+      let payload = JSON.parse(message.body);
+      console.log('positions', payload)
+      this.addPosition(payload)
+    });
+  }
+
+  addPosition(point: any) {
+    let marker = L.marker(point.position, {
+      icon: L.icon({
+        iconSize: [25, 41],
+        iconAnchor: [13, 41],
+        iconUrl: 'assets/marker-icon-red.png',
+        iconRetinaUrl: 'assets/marker-icon-2x-red.png',
+        shadowUrl: 'assets/marker-shadow.png'
+      })
+    }).bindPopup(point.id).openPopup();
+    marker.addTo(this.map);
+  }
+
+  // --- Controllers
+
+  // @https://asymmetrik.com/ngx-leaflet-tutorial-angular-cli/
+  // --- Layers: Define base layers so we can reference them multiple times
+  streetMaps = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+    detectRetina: true,
+    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
+  });
+  wMaps = L.tileLayer('http://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png', {
+    detectRetina: true,
+    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
+  });
+
+  satelliteMaps = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
+    id: 'mapbox.streets',
+    attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
+  });
+  
+  options = {
+    layers: [this.streetMaps],
+    zoom: 15,
+    center: L.latLng([51.037845, 13.762852])
+  };
+
+  onMapReady(map: L.Map) {
+    this.map = map
+
+    // Layers control object with our two base layers and the three overlay layers
+    let baseLayers = {
+      'Street Maps': this.streetMaps,
+      'Wikimedia Maps': this.wMaps,
+      'Satellite': this.satelliteMaps
+    }
+    L.control.layers(baseLayers).addTo(this.map);
+  }  
+  
+  addNewMarker(obj: any) {
+    let marker = L.marker([obj.lat, obj.lng], {
+      icon: L.icon({
+        iconSize: [25, 41],
+        iconAnchor: [13, 41],
+        iconUrl: 'assets/marker-icon-grey.png',
+        iconRetinaUrl: 'assets/marker-icon-2x-grey.png',
+        shadowUrl: 'assets/marker-shadow.png'
+      })
+    }).bindPopup(obj.id).openPopup();
+    marker.addTo(this.map);
+  }
+}
diff --git a/src/app/core/api.service.spec.ts b/src/app/core/api.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..77286123bbf2073af05b68dcf53b8e2ff54b8925
--- /dev/null
+++ b/src/app/core/api.service.spec.ts
@@ -0,0 +1,23 @@
+import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
+import {TestBed} from '@angular/core/testing';
+
+import {ApiService} from './api.service';
+
+describe('ApiService', () => {
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      imports: [HttpClientTestingModule],
+      providers: [ApiService]
+    });
+  });
+
+  afterEach(() => {
+    const httpMock = TestBed.get(HttpTestingController);
+    httpMock.verify();
+  });
+
+  it('should be created', () => {
+    const service: ApiService = TestBed.get(ApiService);
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/core/api.service.ts b/src/app/core/api.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a81e3f8eaf1bc9525686bff18c55988c6438f7b0
--- /dev/null
+++ b/src/app/core/api.service.ts
@@ -0,0 +1,41 @@
+import {HttpClient} from '@angular/common/http';
+import {Injectable} from '@angular/core';
+import {Observable, throwError} from 'rxjs';
+import {catchError} from 'rxjs/operators';
+
+export interface ApiError {
+  code: string;
+  message: string;
+}
+
+@Injectable({
+  providedIn: 'root'
+})
+export class ApiService {
+
+  private locationsUrl: string;
+
+  constructor(private httpClient: HttpClient) {
+    this.locationsUrl = 'http://localhost:8080/locations';
+  }
+
+  getXml(url: string): Observable<string> {
+    return this.httpClient
+      .get(url, {responseType: 'text'})
+      .pipe(catchError(this._handleError));
+  }
+
+
+  public findAll(): Observable<string[]> {
+    return this.httpClient.get<string[]>(this.locationsUrl);
+  }
+
+  public save(loc: string) {
+    return this.httpClient.post<string>(this.locationsUrl, loc);
+  }
+
+  private _handleError(error: ApiError) {
+    return throwError(error.message || 'Could not complete your request; please try again later.');
+  }
+
+}
diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..339a9110e79cdfebc90753a22a569599404ada29
--- /dev/null
+++ b/src/app/core/core.module.ts
@@ -0,0 +1,12 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+
+
+@NgModule({
+  declarations: [],
+  imports: [
+    CommonModule
+  ]
+})
+export class CoreModule { }
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..57e3890402079692045dcd74b346c0386009c2d8
--- /dev/null
+++ b/src/app/shared/shared.module.ts
@@ -0,0 +1,73 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+// --- @angular/flex-layout : Layout for Angular applications; using Flexbox and a Responsive API
+// import { FlexLayoutModule } from '@angular/flex-layout';
+
+// --- Forms
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+
+// --- material.angular.io : Material Design components for Angular
+import { MatButtonModule } from '@angular/material/button';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { MatMenuModule } from '@angular/material/menu';
+import { MatTabsModule } from '@angular/material/tabs';
+import { MatToolbarModule } from '@angular/material/toolbar';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatDialogModule } from '@angular/material/dialog';
+import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatSelectModule } from '@angular/material/select';
+import { MatCardModule } from '@angular/material/card';
+import { MatExpansionModule } from '@angular/material/expansion';
+import { MatSidenavModule } from '@angular/material/sidenav';
+import { MatTooltipModule } from '@angular/material/tooltip';
+// Animation
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+
+
+@NgModule({
+  declarations: [],
+  imports: [
+    FormsModule, 
+    ReactiveFormsModule,
+    CommonModule,
+    MatButtonModule,
+    MatIconModule,
+    MatInputModule,
+    MatMenuModule,
+    MatTabsModule,
+    MatToolbarModule,
+    BrowserAnimationsModule,
+    MatFormFieldModule,
+    MatDialogModule,
+    MatSnackBarModule,
+    MatSelectModule,
+    MatCardModule,
+    MatExpansionModule,
+    MatSidenavModule,
+    MatTooltipModule
+  ],
+  exports: [
+    FormsModule, 
+    ReactiveFormsModule,
+    CommonModule,
+    MatButtonModule,
+    MatIconModule,
+    MatInputModule,
+    MatMenuModule,
+    MatTabsModule,
+    MatToolbarModule,
+    BrowserAnimationsModule,
+    MatFormFieldModule,
+    MatDialogModule,
+    MatSnackBarModule,
+    MatSelectModule,
+    MatCardModule,
+    MatExpansionModule,
+    MatSidenavModule,
+    MatTooltipModule
+  ]
+})
+export class SharedModule { }
diff --git a/src/index.html b/src/index.html
index 586887e69a92979676e7e2b1f03828721f35540a..7de67b6cc5d22f2152bd478b93f3fc20bd8d0f0c 100644
--- a/src/index.html
+++ b/src/index.html
@@ -6,6 +6,9 @@
   <base href="/">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
+  <link rel="preconnect" href="https://fonts.gstatic.com">
+  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
+  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
 </head>
 <body>
   <app-root></app-root>
diff --git a/src/styles.scss b/src/styles.scss
index eb7dc01531e395daadfaf0c2a8378ded0066a412..c1378aee2ad3d3d83377ec5194a1695a857ee0d9 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -15,3 +15,6 @@ app-root {
     flex-wrap: nowrap;
     min-height: 100vh;
 }
+
+html, body { height: 100%; }
+body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }