Changeset 28d7d35


Ignore:
Timestamp:
01/31/21 06:27:26 (19 months ago)
Author:
Mile Jankuloski <mile.jankuloski@…>
Branches:
master
Children:
de9d697
Parents:
7520f88
Message:

Maps, geolocation api, dialogs & more

Location:
Farmatiko/ClientApp
Files:
3 added
29 edited

Legend:

Unmodified
Added
Removed
  • Farmatiko/ClientApp/angular.json

    r7520f88 r28d7d35  
    2727              "src/custom-theme.scss",
    2828              "node_modules/bootstrap/dist/css/bootstrap.min.css",
    29               "src/styles.css"
     29              "src/styles.css",
     30              "./node_modules/leaflet/dist/leaflet.css"
    3031            ],
    3132            "scripts": []
  • Farmatiko/ClientApp/package-lock.json

    r7520f88 r28d7d35  
    866866        }
    867867      }
     868    },
     869    "@asymmetrik/ngx-leaflet": {
     870      "version": "8.1.0",
     871      "resolved": "https://registry.npmjs.org/@asymmetrik/ngx-leaflet/-/ngx-leaflet-8.1.0.tgz",
     872      "integrity": "sha512-lq7LduBP/vXcaSEmKnx7mzCR8WsoYqh9pB6BNnq53yeCwsqRbG3GdKye1/i8VvoRzjDsmQBPQsIFZ9uclXrtgg=="
    868873    },
    869874    "@babel/code-frame": {
     
    73007305      }
    73017306    },
     7307    "leaflet": {
     7308      "version": "1.7.1",
     7309      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz",
     7310      "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw=="
     7311    },
    73027312    "less": {
    73037313      "version": "3.9.0",
  • Farmatiko/ClientApp/package.json

    r7520f88 r28d7d35  
    2424    "@angular/platform-server": "10.0.4",
    2525    "@angular/router": "10.0.4",
     26    "@asymmetrik/ngx-leaflet": "^8.1.0",
    2627    "@nguniversal/module-map-ngfactory-loader": "8.1.1",
    2728    "angular-rename": "^1.0.7",
     
    3132    "core-js": "^3.3.3",
    3233    "jquery": "3.4.1",
     34    "leaflet": "^1.7.1",
    3335    "ngx-countup": "^7.3.1",
    3436    "oidc-client": "^1.9.1",
  • Farmatiko/ClientApp/src/app/app.module.ts

    r7520f88 r28d7d35  
    66import { MaterialModule } from './shared/material.module';
    77import { ReactiveFormsModule } from '@angular/forms';
     8import { LeafletModule } from '@asymmetrik/ngx-leaflet';
    89
    910import { CoreModule } from './shared/core.module';
     
    6566    MaterialModule,
    6667    ReactiveFormsModule,
     68    LeafletModule,
    6769    CoreModule
    6870  ],
  • Farmatiko/ClientApp/src/app/counter/counter.component.css

    r7520f88 r28d7d35  
    22    display: flex;
    33    flex-direction: column;
    4     max-height: 500px;
    54    min-width: 300px;
    65}
     
    2726    padding: 1em 0;
    2827}
     28.tableRow:hover {
     29    background-color: #D4F2CD;
     30    transform: scale(1.0005);
     31}
     32
     33h2 button {
     34    float: right;
     35    padding: 0 5em;
     36}
     37
     38#map {
     39    height: 100%;
     40}
     41
     42.map-frame {
     43    border: 2px solid black;
     44    height: 100%;
     45}
     46
     47.map-wrapper {
     48    margin: 0 3em 3em 3em;
     49    min-height: 400px;
     50}
  • Farmatiko/ClientApp/src/app/counter/counter.component.html

    r7520f88 r28d7d35  
    66  <div class="wrapper">
    77    <div class="header">
    8     <h2>Здравствени установи</h2>
     8    <h2>Здравствени установи
     9      <button mat-icon-button color="primary" (click)="refreshMap()" [disabled]="!showMap">
     10        <mat-icon>refresh</mat-icon>Освежи
     11      </button>
     12      <button mat-icon-button color="accent" [disabled]="clicked" (click)="toggleMap(); clicked = true">
     13        <mat-icon>map</mat-icon>Активирај
     14      </button>
     15    </h2>
     16    <div class="map-wrapper" *ngIf="showMap">
     17      <div class="map-frame">
     18        <div id="map" style="height: 400px;" leaflet [leafletOptions]="options"></div>
     19      </div>
     20    </div>
     21
    922  <mat-form-field>
    1023    <input matInput (keyup)="applyFilterFacilities($event.target.value)" placeholder="Пронајди установа">
     
    1629          <th>Име</th>
    1730          <th>Општина</th>
    18           <th>Адреса</th>
    1931          <th>Тип</th>
    20           <th>Е-пошта</th>
    21           <th>Телефон</th>
    2232        </tr>
    2333      </thead>
    2434      <tbody>
    25         <tr *ngFor="let facility of filteredFacilities">
    26           <td><a (click)="openFacilityDialog(facility)">{{ facility.name }}</a></td>
     35        <tr *ngFor="let facility of filteredFacilities" (click)="openFacilityDialog(facility)" class="tableRow">
     36          <td>{{ facility.name }}</td>
    2737          <td>{{ facility.municipality }}</td>
    28           <td>{{ facility.address }}</td>
    2938          <td>{{ facility.type }}</td>
    30           <td>{{ facility.email }}</td>
    31           <td>{{ facility.phone }}</td>
    3239        </tr>
    3340    </tbody>
     
    4855          <th>Име</th>
    4956          <th>Гранка</th>
    50           <th>Установа</th>
    51           <th>Назив</th>
    5257        </tr>
    5358      </thead>
    5459      <tbody>
    55         <tr *ngFor="let worker of filteredWorkers">
    56           <td><a (click)="openWorkerDialog(worker)">{{ worker.name }}</a></td>
     60        <tr *ngFor="let worker of filteredWorkers" (click)="openWorkerDialog(worker)" class="tableRow">
     61          <td>{{ worker.name }}</td>
    5762          <td>{{ worker.branch }}</td>
    58           <td>{{ worker.facility }}</td>
    59           <td>{{ worker.title }}</td>
    6063        </tr>
    6164    </tbody>
  • Farmatiko/ClientApp/src/app/counter/counter.component.ts

    r7520f88 r28d7d35  
    55import { FacilityDialogComponent } from '../dialogs/facility-dialog/facility-dialog.component';
    66import { WorkerDialogComponent } from '../dialogs/worker-dialog/worker-dialog.component';
     7import { latLng, LatLng, tileLayer, marker, icon } from 'leaflet';
     8import { HttpClient } from '@angular/common/http';
    79
    810@Component({
     
    1618  public filteredFacilities: IHealthFacilities[] = [];
    1719  public filteredWorkers: IHealthcareWorkers[] = [];
    18 
    19   constructor(private dataService: DataService, private dialog: MatDialog) {
     20  public lat;
     21  public lng;
     22  clicked = false;
     23  showMap: boolean = false;
     24  options = {
     25    layers: [
     26      tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' })
     27    ],
     28    zoom: 8,
     29    center: latLng(41.61807, 21.74348)
     30  }
     31 
     32  constructor(private dataService: DataService, private dialog: MatDialog, private http: HttpClient) {
    2033   
    2134  }
     
    2740        },
    2841        (err: any) => console.log(err),
    29         () => console.log('Facility data retrieved!'));
     42        () => {
     43          this.appendFacilityMarkers(this.facilities)
     44          console.log('Facility data retrieved!');
     45        });
    3046
    3147    this.dataService.getWorkers()
     
    3551        (err: any) => console.log(err),
    3652        () => console.log('Facility data retrieved!'));
     53
     54    if (navigator.geolocation) {
     55      navigator.geolocation.getCurrentPosition((position) => {
     56        if (position) {
     57          this.lat = position.coords.latitude;
     58          this.lng = position.coords.longitude;
     59          let layer = marker([ this.lat, this.lng ], {
     60            icon: icon({
     61              iconSize: [ 25, 41 ],
     62              iconAnchor: [ 13, 41 ],
     63              iconUrl: 'assets/home-icon.png'
     64            })
     65          }).bindPopup("Вашата локација");
     66          this.options.layers.push(layer);
     67        }
     68      });
     69    }
     70  }
     71
     72  appendFacilityMarkers(facils: IHealthFacilities[]) {
     73    this.options.layers = [];
     74    this.options.layers.push(tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}));
     75    if(this.lat && this.lng) {
     76      this.options.layers.push(marker([ this.lat, this.lng ], {
     77        icon: icon({
     78          iconSize: [ 25, 41 ],
     79          iconAnchor: [ 13, 41 ],
     80          iconUrl: 'assets/home-icon.png'
     81        })
     82      }).bindPopup("Вашата локација"));
     83    }
     84    facils.forEach((facil) => {
     85      this.http.get<any>('https://nominatim.openstreetmap.org/search/?country=Macedonia&city='+facil.municipality+'&street='+facil.address+'&format=json').subscribe(obj => {
     86        console.log(obj); 
     87        if(obj.length) {
     88            let layer = marker([ obj[0]?.lat, obj[0]?.lon ], {
     89              icon: icon({
     90                iconSize: [ 25, 41 ],
     91                iconAnchor: [ 13, 41 ],
     92                iconUrl: 'assets/hospital-icon.png'
     93              })
     94            }).bindPopup(facil.name);
     95            this.options.layers.push(layer);
     96          }
     97        }, error => console.error(error));
     98    });
    3799  }
    38100
     
    45107          },
    46108          (err: any) => console.log(err),
    47           () => console.log('Facility data retrieved!'));
     109          () => {
     110            this.appendFacilityMarkers(this.filteredFacilities);
     111            if(this.showMap) {
     112              this.showMap = false;
     113              setTimeout(() => this.showMap = true, 300);
     114            }
     115            console.log('Facility data retrieved!');
     116          });
    48117    }
    49118    else {
    50119      this.filteredFacilities = this.facilities;
     120      this.appendFacilityMarkers(this.facilities);
     121      if(this.showMap) {
     122        this.showMap = false;
     123        setTimeout(() => this.showMap = true, 300);
     124      }
    51125    }
    52126  }
     
    80154    });
    81155  }
     156 
     157  toggleMap() {
     158    this.showMap = !this.showMap;
     159  }
     160
     161  refreshMap() {
     162    this.showMap = false;
     163    setTimeout(() => this.showMap = true, 300);
     164  }
     165
    82166}
  • Farmatiko/ClientApp/src/app/dashboard/dashboard.component.html

    r7520f88 r28d7d35  
    4444      <tbody>
    4545        <tr *ngFor="let pharmacies of head.Pharmacy">
    46           <td>{{pharmacies.name}}</td>
    47           <td>{{pharmacies.location}}</td>
    48           <td>{{pharmacies.address}}</td>
    49           <td>{{pharmacies.workAllTime}}</td>
     46          <td (click)="openPharmacyDialog(pharmacies)">{{pharmacies.name}}</td>
     47          <td (click)="openPharmacyDialog(pharmacies)">{{pharmacies.location}}</td>
     48          <td (click)="openPharmacyDialog(pharmacies)">{{pharmacies.address}}</td>
     49          <td (click)="openPharmacyDialog(pharmacies)">{{pharmacies.workAllTime}}</td>
    5050          <td><a (click)="openEditPharmacyDialog(pharmacies)">Edit</a></td>
    5151        </tr>
     
    7272      </thead>
    7373      <tbody>
    74         <tr *ngFor="let pharmacy of pharmacies">
    75           <td><a (click)="openPharmacyDialog(pharmacy)">{{ pharmacy.name }}</a></td>
    76           <td>{{ pharmacy.location }}</td>
    77           <td>{{ pharmacy.address }}</td>
    78           <td>{{ pharmacy.workAllTime }}</td>
    79           <td><a (click)="claimPharmacy(pharmacy)">Claim</a></td>
     74        <tr *ngFor="let pharmacy of filteredPharmacies">
     75          <td (click)="openPharmacyDialog(pharmacy)">{{ pharmacy.name }}</td>
     76          <td (click)="openPharmacyDialog(pharmacy)">{{ pharmacy.location }}</td>
     77          <td (click)="openPharmacyDialog(pharmacy)">{{ pharmacy.address }}</td>
     78          <td (click)="openPharmacyDialog(pharmacy)">{{ pharmacy.workAllTime }}</td>
     79          <td><a (click)="claimPharmacy(pharmacy)" *ngIf="!pharmacy.headName">Claim</a> <span *ngIf="pharmacy.headName">Already claimed</span></td>
    8080        </tr>
    8181    </tbody>
     
    114114        <tbody>
    115115          <tr *ngFor="let medicine of filteredMedicines">
    116             <td *ngIf="!medicinesEditMode"><a (click)="openMedicineDialog(medicine)">{{ medicine.name }}</a></td>
     116            <td *ngIf="!medicinesEditMode" (click)="openMedicineDialog(medicine)">{{ medicine.name }}</td>
    117117            <td *ngIf="medicinesEditMode"><mat-form-field appearance="fill"><input matInput [(ngModel)]="medicine.name" name="medname"></mat-form-field></td>
    118             <td *ngIf="!medicinesEditMode">{{ medicine.strength }}</td>
     118            <td *ngIf="!medicinesEditMode" (click)="openMedicineDialog(medicine)">{{ medicine.strength }}</td>
    119119            <td *ngIf="medicinesEditMode"><mat-form-field appearance="fill"><input matInput [(ngModel)]="medicine.strength" name="medstr"></mat-form-field></td>
    120             <td *ngIf="!medicinesEditMode">{{ medicine.form }}</td>
     120            <td *ngIf="!medicinesEditMode" (click)="openMedicineDialog(medicine)">{{ medicine.form }}</td>
    121121            <td *ngIf="medicinesEditMode"><mat-form-field appearance="fill"><input matInput [(ngModel)]="medicine.form" name="medform"></mat-form-field></td>
    122             <td *ngIf="!medicinesEditMode">{{ medicine.wayOfIssuing }}</td>
     122            <td *ngIf="!medicinesEditMode" (click)="openMedicineDialog(medicine)">{{ medicine.wayOfIssuing }}</td>
    123123            <td *ngIf="medicinesEditMode"><mat-form-field appearance="fill"><input matInput [(ngModel)]="medicine.wayOfIssuing" name="medwayOfIssuing"></mat-form-field></td>
    124             <td *ngIf="!medicinesEditMode">{{ medicine.manufacturer }}</td>
     124            <td *ngIf="!medicinesEditMode" (click)="openMedicineDialog(medicine)">{{ medicine.manufacturer }}</td>
    125125            <td *ngIf="medicinesEditMode"><mat-form-field appearance="fill"><input matInput [(ngModel)]="medicine.manufacturer" name="medmanufacturer"></mat-form-field></td>
    126             <td *ngIf="!medicinesEditMode">{{ medicine.price }}</td>
     126            <td *ngIf="!medicinesEditMode" (click)="openMedicineDialog(medicine)">{{ medicine.price }}</td>
    127127            <td *ngIf="medicinesEditMode"><mat-form-field appearance="fill"><input matInput [(ngModel)]="medicine.price" name="medprice"></mat-form-field></td>
    128             <td *ngIf="!medicinesEditMode">{{ medicine.packaging }}</td>
     128            <td *ngIf="!medicinesEditMode" (click)="openMedicineDialog(medicine)">{{ medicine.packaging }}</td>
    129129            <td *ngIf="medicinesEditMode"><mat-form-field appearance="fill"><input matInput [(ngModel)]="medicine.packaging" name="medpackaging"></mat-form-field></td>
    130130            <td>
  • Farmatiko/ClientApp/src/app/dashboard/dashboard.component.ts

    r7520f88 r28d7d35  
    4040    this.dataService.getPharmacies()
    4141        .subscribe((pharmacy: IPharmacy[]) => {
    42           this.pharmacies = pharmacy;
    43           this.head.Pharmacy.forEach((pharma) => {
    44             this.filteredPharmacies = this.pharmacies = this.pharmacies.filter(x => x == pharma);
    45           });
     42          this.pharmacies = this.filteredPharmacies = pharmacy;
     43          // Iskluceno filtriranje na farmacies (Star metod)
     44          // this.head.Pharmacy.forEach((pharma) => {
     45          //   this.filteredPharmacies = this.pharmacies = this.pharmacies.filter(x => x == pharma);
     46          // });
    4647        },
    4748        (err: any) => console.log(err),
     
    147148      if(listMedicines){
    148149        listMedicines.forEach((medicine) => {
    149           this.head.PharmacyMedicines = this.head.PharmacyMedicines.filter(x => x != medicine);
     150          if(this.head.PharmacyMedicines) {
     151            this.head.PharmacyMedicines = this.head.PharmacyMedicines.filter(x => x != medicine);
     152          }
     153          else {
     154            this.head.PharmacyMedicines = [];
     155          }
    150156          this.head.PharmacyMedicines.push(medicine);
    151157          this.filteredMedicines = this.head.PharmacyMedicines;
     
    175181          .subscribe((pharmacy: IPharmacy[]) => {
    176182            this.filteredPharmacies = pharmacy;
    177             this.head.Pharmacy.forEach((pharma) => {
    178               this.filteredPharmacies = this.filteredPharmacies.filter(x => x == pharma);
    179             });
     183            // this.head.Pharmacy.forEach((pharma) => {
     184            //   this.filteredPharmacies = this.filteredPharmacies.filter(x => x == pharma);
     185            // });
    180186          },
    181187          (err: any) => console.log(err),
  • Farmatiko/ClientApp/src/app/dialogs/edit-pharmacy-head-dialog/edit-pharmacy-head-dialog.component.html

    r7520f88 r28d7d35  
    33    <div class="form-group">
    44      <label>ИД</label>
    5       <input type="text" class="form-control" name="id" [(ngModel)]="head.id" #id="ngModel" required>
     5      <input type="text" class="form-control" name="id" [(ngModel)]="head.id" #id="ngModel" required disabled>
    66      <div class="alert alert-danger">ID is required</div>
    77    </div>
  • Farmatiko/ClientApp/src/app/dialogs/facility-dialog/facility-dialog.component.css

    r7520f88 r28d7d35  
     1button {
     2    float: right;
     3}
  • Farmatiko/ClientApp/src/app/dialogs/facility-dialog/facility-dialog.component.html

    r7520f88 r28d7d35  
    1 <h3>Повеќе инфо</h3>
     1<h3>Повеќе информации</h3>
     2<table class="table table-striped">
     3    <tbody>
     4        <tr>
     5            <td>Име</td>
     6            <td>{{facility?.name}}</td>
     7        </tr>
     8        <tr>
     9            <td>Општина</td>
     10            <td>{{facility?.municipality}}</td>
     11        </tr>
     12        <tr>
     13            <td>Тип на установа</td>
     14            <td>{{facility?.type}}</td>
     15        </tr>
     16        <tr>
     17            <td>Адреса</td>
     18            <td>{{facility?.address}}</td>
     19        </tr>
     20        <tr>
     21            <td>Е-пошта</td>
     22            <td>{{facility?.email}}</td>
     23        </tr>
     24        <tr>
     25            <td>Телефон</td>
     26            <td>{{facility?.phone}}</td>
     27        </tr>
     28    </tbody>
     29</table>
     30
     31<div style="height: 200px;" leaflet [leafletOptions]="options" *ngIf="mapShown"></div>
    232<br>
    3 <p>ИД: {{facility.id}}</p>
    4 <p>Име: {{facility.name}}</p>
    5 <p>Општина: {{facility.municipality}}</p>
    6 <p>Тип на установа: {{facility.type}}</p>
    7 <p>Адреса: {{facility.address}}</p>
    8 <p>Адреса: {{facility.email}}</p>
    9 <p>Адреса: {{facility.phone}}</p>
    10 <br>
    11 <p><a (click)="close()">Затвори</a></p>
     33<p><button mat-button color="primary" (click)="close()">Затвори</button></p>
  • Farmatiko/ClientApp/src/app/dialogs/facility-dialog/facility-dialog.component.ts

    r7520f88 r28d7d35  
    22import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
    33import { IHealthFacilities } from '../../shared/interfaces';
     4import { latLng, LatLng, tileLayer, marker, icon } from 'leaflet';
     5import { HttpClient } from '@angular/common/http';
    46
    57@Component({
     
    1012export class FacilityDialogComponent implements OnInit {
    1113  facility: IHealthFacilities;
     14  mapShown: boolean = true;
     15  options = {
     16    layers: [
     17      tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' })
     18    ],
     19    zoom: 7,
     20    center: latLng(41.61807, 21.74348)
     21  }
    1222
    13   constructor(private dialogRef: MatDialogRef<FacilityDialogComponent>, @Inject(MAT_DIALOG_DATA) data) {
     23  constructor(private dialogRef: MatDialogRef<FacilityDialogComponent>, @Inject(MAT_DIALOG_DATA) data, private http: HttpClient) {
    1424    this.facility = data;
     25    if(this.facility) {
     26      this.addMarkers();
     27    }
    1528  }
    1629
    1730  ngOnInit(): void {
    1831  }
     32
     33  addMarkers() {
     34    this.http.get<any>('https://nominatim.openstreetmap.org/search/?country=Macedonia&city='+this.facility?.municipality+'&street='+this.facility?.address+'&format=json').subscribe(obj => {
     35      console.log(obj); 
     36      if(obj.length) {
     37          let layer = marker([ obj[0]?.lat, obj[0]?.lon ], {
     38            icon: icon({
     39              iconSize: [ 25, 41 ],
     40              iconAnchor: [ 13, 41 ],
     41              iconUrl: 'assets/hospital-icon.png'
     42            })
     43          }).bindPopup("Аптека: "+this.facility?.name);
     44          this.options.layers.push(layer);
     45          this.options.center = latLng(obj[0]?.lat, obj[0]?.lon);
     46          this.options.zoom = 13;
     47        }
     48      }, error => console.error(error));
     49      this.mapShown = false;
     50      setTimeout(() => this.mapShown = true, 300);
     51  }
     52
    1953
    2054  close() {
  • Farmatiko/ClientApp/src/app/dialogs/medicine-dialog/medicine-dialog.component.css

    r7520f88 r28d7d35  
     1button {
     2    float: right;
     3}
  • Farmatiko/ClientApp/src/app/dialogs/medicine-dialog/medicine-dialog.component.html

    r7520f88 r28d7d35  
    1 <h3>Повеќе инфо</h3>
    2 <br>
    3 <p>ИД: {{medicine.id}}</p>
    4 <p>Име: {{medicine.name}}</p>
    5 <p>Форма: {{medicine.form}}</p>
    6 <p>Пакување: {{medicine.packaging}}</p>
    7 <p>Цена: {{medicine.price}}</p>
    8 <p>Јачина: {{medicine.strength}}</p>
    9 <p>Начин на издавање: {{medicine.wayOfIssuing}}</p>
    10 <p>Производител: {{medicine.manufacturer}}</p>
    11 <br>
    12 <p><a (click)="close()">Затвори</a></p>
     1<h3>Повеќе информации</h3>
     2<table class="table table-striped">
     3    <tbody>
     4        <tr>
     5            <td>Име</td>
     6            <td>{{medicine?.name}}</td>
     7        </tr>
     8        <tr>
     9            <td>Форма</td>
     10            <td>{{medicine?.form}}</td>
     11        </tr>
     12        <tr>
     13            <td>Пакување</td>
     14            <td>{{medicine?.packaging}}</td>
     15        </tr>
     16        <tr>
     17            <td>Цена</td>
     18            <td>{{medicine?.price}}</td>
     19        </tr>
     20        <tr>
     21            <td>Јачина</td>
     22            <td>{{medicine?.strength}}</td>
     23        </tr>
     24        <tr>
     25            <td>Начин на издавање</td>
     26            <td>{{medicine?.wayOfIssuing}}</td>
     27        </tr>
     28        <tr>
     29            <td>Производител</td>
     30            <td>{{medicine?.manufacturer}}</td>
     31        </tr>
     32    </tbody>
     33</table>
     34<div *ngIf="medicine?.headNames">
     35    <h5>Достапен во аптеките на:</h5>
     36    <table class="table table-striped">
     37        <tbody>
     38            <tr *ngFor="let head of medicine?.headNames">
     39                <td>{{head}}</td>
     40            </tr>
     41        </tbody>
     42    </table>
     43</div>
     44<p><button mat-button color="primary" (click)="close()">Затвори</button></p>
  • Farmatiko/ClientApp/src/app/dialogs/pharmacy-dialog/pharmacy-dialog.component.css

    r7520f88 r28d7d35  
     1button {
     2    float: right;
     3}
     4
     5div {
     6    white-space: nowrap;
     7}
  • Farmatiko/ClientApp/src/app/dialogs/pharmacy-dialog/pharmacy-dialog.component.html

    r7520f88 r28d7d35  
    1 <h3>Повеќе инфо</h3>
     1<h3>Повеќе информации</h3>
     2<table class="table table-striped">
     3    <tbody>
     4        <tr>
     5            <td>Име</td>
     6            <td>{{pharmacy?.name}}</td>
     7        </tr>
     8        <tr>
     9            <td>Општина</td>
     10            <td>{{pharmacy?.location}}</td>
     11        </tr>
     12        <tr>
     13            <td>Адреса</td>
     14            <td>{{pharmacy?.address}}</td>
     15        </tr>
     16        <tr>
     17            <td>Работи 24/7</td>
     18            <td><div *ngIf="pharmacy.workAllTime == true">Да</div><div *ngIf="pharmacy.workAllTime != true">Не</div></td>
     19        </tr>
     20        <tr>
     21            <td>Компанија</td>
     22            <td>{{pharmacy?.headName}}</td>
     23        </tr>
     24    </tbody>
     25</table>
     26
     27<div style="height: 200px;" leaflet [leafletOptions]="options" *ngIf="mapShown"></div>
    228<br>
    3 <p>ИД: {{pharmacy.id}}</p>
    4 <p>Име: {{pharmacy.name}}</p>
    5 <p>Општина: {{pharmacy.location}}</p>
    6 <p>Адреса: {{pharmacy.address}}</p>
    7 <p>Работи 24/7: {{pharmacy.workAllTime}}</p>
    8 <br>
    9 <p><a (click)="close()">Затвори</a></p>
     29<p><button mat-button color="primary" (click)="close()">Затвори</button></p>
  • Farmatiko/ClientApp/src/app/dialogs/pharmacy-dialog/pharmacy-dialog.component.ts

    r7520f88 r28d7d35  
    1 import { Component, OnInit, Inject } from '@angular/core';
     1import { Component, OnInit, Inject, AfterViewInit } from '@angular/core';
    22import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
    33import { IPharmacy } from '../../shared/interfaces';
     4import { latLng, LatLng, tileLayer, marker, icon } from 'leaflet';
     5import { HttpClient } from '@angular/common/http';
    46
    57@Component({
     
    1012export class PharmacyDialogComponent implements OnInit {
    1113  pharmacy: IPharmacy;
     14  mapShown: boolean = true;
     15  options = {
     16    layers: [
     17      tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' })
     18    ],
     19    zoom: 7,
     20    center: latLng(41.61807, 21.74348)
     21  }
    1222
    13   constructor(private dialogRef: MatDialogRef<PharmacyDialogComponent>, @Inject(MAT_DIALOG_DATA) data) {
     23  constructor(private dialogRef: MatDialogRef<PharmacyDialogComponent>, @Inject(MAT_DIALOG_DATA) data, private http: HttpClient) {
    1424    this.pharmacy = data;
     25    if(this.pharmacy) {
     26      this.addMarkers();
     27    }
    1528  }
    1629
    1730  ngOnInit(): void {
     31  }
     32
     33  addMarkers() {
     34    this.http.get<any>('https://nominatim.openstreetmap.org/search/?country=Macedonia&city='+this.pharmacy?.location+'&street='+this.pharmacy?.address+'&format=json').subscribe(obj => {
     35      console.log(obj); 
     36      if(obj.length) {
     37          let layer = marker([ obj[0]?.lat, obj[0]?.lon ], {
     38            icon: icon({
     39              iconSize: [ 25, 41 ],
     40              iconAnchor: [ 13, 41 ],
     41              iconUrl: 'assets/pharmacy-icon.png'
     42            })
     43          }).bindPopup("Аптека: "+this.pharmacy?.name);
     44          this.options.layers.push(layer);
     45          this.options.center = latLng(obj[0]?.lat, obj[0]?.lon);
     46          this.options.zoom = 13;
     47        }
     48      }, error => console.error(error));
     49      this.mapShown = false;
     50      setTimeout(() => this.mapShown = true, 300);
    1851  }
    1952
     
    2255  }
    2356
     57
    2458}
  • Farmatiko/ClientApp/src/app/dialogs/worker-dialog/worker-dialog.component.css

    r7520f88 r28d7d35  
     1button {
     2    float: right;
     3}
  • Farmatiko/ClientApp/src/app/dialogs/worker-dialog/worker-dialog.component.html

    r7520f88 r28d7d35  
    1 <h3>Повеќе инфо</h3>
     1<h3>Повеќе информации</h3>
    22<br>
    3 <p>ИД: {{worker.id}}</p>
    4 <p>Име: {{worker.name}}</p>
    5 <p>Гранка: {{worker.branch}}</p>
    6 <p>Титула: {{worker.title}}</p>
    7 <br>
    8 <p>Институција: {{worker.facility.name}}</p>
    9 <p>{{worker.facility.municipality}}</p>
    10 <p>{{worker.facility.type}}</p>
    11 <br>
    12 <p><a (click)="close()">Затвори</a></p>
     3<table class="table table-striped">
     4    <tbody>
     5        <tr>
     6            <td>Име</td>
     7            <td>{{worker?.name}}</td>
     8        </tr>
     9        <tr>
     10            <td>Гранка</td>
     11            <td>{{worker?.branch}}</td>
     12        </tr>
     13        <tr>
     14            <td>Титула</td>
     15            <td>{{worker?.title}}</td>
     16        </tr>
     17    </tbody>
     18    <br>
     19    <tbody *ngIf="worker?.facility">
     20        <tr>
     21            <td>Институција</td>
     22            <td>{{worker?.facility?.name}}</td>
     23        </tr>
     24        <tr *ngIf="isExpanded">
     25            <td>Општина</td>
     26            <td>{{worker?.facility?.municipality}}</td>
     27        </tr>
     28        <tr *ngIf="isExpanded">
     29            <td>Тип</td>
     30            <td>{{worker?.facility?.type}}</td>
     31        </tr>
     32        <tr *ngIf="isExpanded">
     33            <td>Адреса</td>
     34            <td>{{worker.facility?.address}}</td>
     35        </tr>
     36        <tr *ngIf="isExpanded">
     37            <td>Е-пошта</td>
     38            <td>{{worker.facility?.email}}</td>
     39        </tr>
     40        <tr *ngIf="isExpanded">
     41            <td>Телефон</td>
     42            <td>{{worker.facility?.phone}}</td>
     43        </tr>
     44    </tbody>
     45    <tbody *ngIf="!worker?.facility">
     46        <tr>
     47            <td>Институција</td>
     48            <td>Нема податок</td>
     49        </tr>
     50        <tr *ngIf="isExpanded">
     51            <td>Општина</td>
     52            <td>Нема податок</td>
     53        </tr>
     54        <tr *ngIf="isExpanded">
     55            <td>Тип</td>
     56            <td>Нема податок</td>
     57        </tr>
     58        <tr *ngIf="isExpanded">
     59            <td>Адреса</td>
     60            <td>Нема податок</td>
     61        </tr>
     62        <tr *ngIf="isExpanded">
     63            <td>Е-пошта</td>
     64            <td>Нема податок</td>
     65        </tr>
     66        <tr *ngIf="isExpanded">
     67            <td>Телефон</td>
     68            <td>Нема податок</td>
     69        </tr>
     70    </tbody>
     71</table>
     72<button mat-icon-button color="primary" *ngIf="!isExpanded" (click)="toggleExpansion()" style="min-width: 100%">
     73    <mat-icon>expand_more</mat-icon>
     74</button>
     75<button mat-icon-button color="primary" *ngIf="isExpanded" (click)="toggleExpansion()" style="min-width: 100%">
     76    <mat-icon>expand_less</mat-icon>
     77</button>
     78<p><button mat-button color="primary" (click)="close()">Затвори</button></p>
  • Farmatiko/ClientApp/src/app/dialogs/worker-dialog/worker-dialog.component.ts

    r7520f88 r28d7d35  
    1010export class WorkerDialogComponent implements OnInit {
    1111  worker: IHealthcareWorkers;
     12  isExpanded: boolean = false;
    1213
    1314  constructor(private dialogRef: MatDialogRef<WorkerDialogComponent>, @Inject(MAT_DIALOG_DATA) data) {
     
    2223  }
    2324
     25  toggleExpansion() {
     26    this.isExpanded = !this.isExpanded;
     27  }
     28
    2429}
  • Farmatiko/ClientApp/src/app/home/home.component.css

    r7520f88 r28d7d35  
    22  display: flex;
    33  flex-direction: column;
    4   max-height: 500px;
    54  min-width: 300px;
    65}
     
    2726  padding: 1em 0;
    2827}
     28.tableRow:hover {
     29  background-color: #D4F2CD;
     30  transform: scale(1.0005);
     31}
     32
     33h2 button {
     34  float: right;
     35  padding: 0 5em;
     36}
     37
     38#map {
     39  height: 100%;
     40}
     41
     42.map-frame {
     43  border: 2px solid black;
     44  height: 100%;
     45}
     46
     47.map-wrapper {
     48  margin: 0 3em 3em 3em;
     49  min-height: 400px;
     50}
  • Farmatiko/ClientApp/src/app/home/home.component.html

    r7520f88 r28d7d35  
    1414        <tr>
    1515          <th>Име</th>
    16           <th>Јачина</th>
    1716          <th>Форма</th>
    18           <th>Начин на издавање</th>
    19           <th>Производител</th>
    2017          <th>Цена</th>
    21           <th>Пакување</th>
    2218        </tr>
    2319      </thead>
    2420      <tbody>
    25         <tr *ngFor="let medicine of filteredMedicines">
    26           <td><a (click)="openMedicineDialog(medicine)">{{ medicine.name }}</a></td>
    27           <td>{{ medicine.strength }}</td>
     21        <tr *ngFor="let medicine of filteredMedicines" (click)="openMedicineDialog(medicine)" class="tableRow">
     22          <td>{{ medicine.name }}</td>
    2823          <td>{{ medicine.form }}</td>
    29           <td>{{ medicine.wayOfIssuing }}</td>
    30           <td>{{ medicine.manufacturer }}</td>
    3124          <td>{{ medicine.price }}</td>
    32           <td>{{ medicine.packaging }}</td>
    3325        </tr>
    3426    </tbody>
     
    3931  <div class="wrapper">
    4032    <div class="header">
    41     <h2>Аптеки</h2>
     33    <h2>Аптеки
     34      <button mat-icon-button color="primary" (click)="refreshMap()" [disabled]="!showMap">
     35        <mat-icon>refresh</mat-icon>Освежи
     36      </button>
     37      <button mat-icon-button color="accent" [disabled]="clicked" (click)="toggleMap(); clicked = true">
     38        <mat-icon>map</mat-icon>Активирај
     39      </button>
     40    </h2>
     41    <div class="map-wrapper" *ngIf="showMap">
     42      <div class="map-frame">
     43        <div id="map" style="height: 400px;" leaflet [leafletOptions]="options"></div>
     44      </div>
     45    </div>
     46
    4247    <mat-form-field>
    4348      <input matInput (keyup)="applyFilterPharmacies($event.target.value)" placeholder="Пронајди аптека">
     
    4954          <th>Име</th>
    5055          <th>Локација</th>
    51           <th>Адреса</th>
    5256          <th>Работи 27/7?</th>
    5357        </tr>
    5458      </thead>
    5559      <tbody>
    56         <tr *ngFor="let pharmacy of filteredPharmacies">
    57           <td><a (click)="openPharmacyDialog(pharmacy)">{{ pharmacy.name }}</a></td>
     60        <tr *ngFor="let pharmacy of filteredPharmacies" (click)="openPharmacyDialog(pharmacy)" class="tableRow">
     61          <td>{{ pharmacy.name }}</td>
    5862          <td>{{ pharmacy.location }}</td>
    59           <td>{{ pharmacy.address }}</td>
    60           <td>{{ pharmacy.workAllTime }}</td>
     63          <td *ngIf="pharmacy.workAllTime == true">Да</td>
     64          <td *ngIf="pharmacy.workAllTime != true">Не</td>
    6165        </tr>
    6266    </tbody>
    6367  </table>
     68
    6469    </div>
    6570    </mat-tab>
  • Farmatiko/ClientApp/src/app/home/home.component.ts

    r7520f88 r28d7d35  
    55import { MedicineDialogComponent } from '../dialogs/medicine-dialog/medicine-dialog.component';
    66import { PharmacyDialogComponent } from '../dialogs/pharmacy-dialog/pharmacy-dialog.component';
     7import { latLng, LatLng, tileLayer, marker, icon } from 'leaflet';
     8import { HttpClient } from '@angular/common/http';
    79
    810@Component({
     
    1618  public filteredMedicines: IMedicine[] = [];
    1719  public filteredPharmacies: IPharmacy[] = [];
     20  public lat;
     21  public lng;
     22  clicked = false;
     23  showMap: boolean = false;
     24  options = {
     25    layers: [
     26      tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' })
     27    ],
     28    zoom: 8,
     29    center: latLng(41.61807, 21.74348)
     30  }
    1831
    19   constructor(private dataService: DataService, private dialog: MatDialog) {
     32  constructor(private dataService: DataService, private dialog: MatDialog, private http: HttpClient) {
    2033
    2134  }
     
    3447        },
    3548        (err: any) => console.log(err),
    36         () => console.log('Pharmacy data retrieved'));
     49        () => {
     50          this.appendPharmacyMarkers(this.pharmacies);
     51          console.log('Pharmacy data retrieved');
     52        });
     53    if (navigator.geolocation) {
     54      navigator.geolocation.getCurrentPosition((position) => {
     55        if (position) {
     56          this.lat = position.coords.latitude;
     57          this.lng = position.coords.longitude;
     58          let layer = marker([ this.lat, this.lng ], {
     59            icon: icon({
     60              iconSize: [ 25, 41 ],
     61              iconAnchor: [ 13, 41 ],
     62              iconUrl: 'assets/home-icon.png'
     63            })
     64          }).bindPopup("Вашата локација");
     65          this.options.layers.push(layer);
     66        }
     67      });
     68    }
    3769  }
     70
     71  appendPharmacyMarkers(pharmas: IPharmacy[]) {
     72    this.options.layers = [];
     73    this.options.layers.push(tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}));
     74    if(this.lat && this.lng) {
     75      this.options.layers.push(marker([ this.lat, this.lng ], {
     76        icon: icon({
     77          iconSize: [ 25, 41 ],
     78          iconAnchor: [ 13, 41 ],
     79          iconUrl: 'assets/home-icon.png'
     80        })
     81      }).bindPopup("Вашата локација"));
     82    }
     83    pharmas.forEach((pharmacy) => {
     84      this.http.get<any>('https://nominatim.openstreetmap.org/search/?country=Macedonia&city='+pharmacy.location+'&street='+pharmacy.address+'&format=json').subscribe(obj => {
     85        console.log(obj); 
     86        if(obj.length) {
     87            let layer = marker([ obj[0]?.lat, obj[0]?.lon ], {
     88              icon: icon({
     89                iconSize: [ 25, 41 ],
     90                iconAnchor: [ 13, 41 ],
     91                iconUrl: 'assets/pharmacy-icon.png'
     92              })
     93            }).bindPopup("Аптека: "+pharmacy.name);
     94            this.options.layers.push(layer);
     95          }
     96        }, error => console.error(error));
     97    });
     98  }
     99
    38100
    39101  applyFilterMedicines(filterValue: string) {
     
    60122          },
    61123          (err: any) => console.log(err),
    62           () => console.log('Pharmacy data retrieved'));
     124          () => {
     125            this.appendPharmacyMarkers(this.filteredPharmacies);
     126            if(this.showMap) {
     127              this.showMap = false;
     128              setTimeout(() => this.showMap = true, 300);
     129            }
     130            console.log('Pharmacy data retrieved')
     131        });
    63132    }
    64133    else {
    65134      this.filteredPharmacies = this.pharmacies;
     135      this.appendPharmacyMarkers(this.pharmacies);
     136      if(this.showMap) {
     137        this.showMap = false;
     138        setTimeout(() => this.showMap = true, 300);
     139      }
    66140    }
    67141  }
     
    80154    });
    81155  }
     156
     157  toggleMap() {
     158    this.showMap = !this.showMap;
     159  }
     160
     161  refreshMap() {
     162    this.showMap = false;
     163    setTimeout(() => this.showMap = true, 300);
     164  }
     165
    82166}
  • Farmatiko/ClientApp/src/app/login/login.component.css

    r7520f88 r28d7d35  
    4444    justify-content: flex-end;
    4545}
     46
     47.aligner {
     48    float: right;
     49    padding-left: 2.5em;
     50}
  • Farmatiko/ClientApp/src/app/login/login.component.html

    r7520f88 r28d7d35  
    11<div class="wrapper">
    22<mat-card>
    3 <mat-card-header><h2>Најава</h2></mat-card-header>
     3<mat-card-header><h2>Најава
     4  <div class="aligner">
     5  <button mat-icon-button color="primary" [routerLink]="['/']">
     6    Почетна <mat-icon>home</mat-icon>
     7  </button>
     8</div></h2></mat-card-header>
    49<mat-card-content>
    510<form [formGroup]="loginForm" novalidate>
  • Farmatiko/ClientApp/src/app/nav-menu/nav-menu.component.html

    r7520f88 r28d7d35  
    3333            </mat-menu>
    3434          </li>
     35          <li *ngIf="!loggedIn">
     36            <button mat-raised-button color="primary" [routerLink]="['/login']"><mat-icon>account_circle</mat-icon> Најава</button>
     37          </li>
    3538        </ul>
    3639      </div>
  • Farmatiko/ClientApp/src/app/shared/interfaces.ts

    r7520f88 r28d7d35  
    2626    price: number;
    2727    packaging: string;
     28    headNames?: string[];
    2829}
    2930
     
    4647    address: string;
    4748    workAllTime?: boolean;
     49    headName?: string;
    4850}
    4951
  • Farmatiko/ClientApp/src/index.html

    r7520f88 r28d7d35  
    1010      <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
    1111    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
     12    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
     13    integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
     14    crossorigin="" />
     15    <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
     16      integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
     17      crossorigin=""></script>
    1218</head>
    1319  <body>
Note: See TracChangeset for help on using the changeset viewer.