337 lines
15 KiB
HTML
337 lines
15 KiB
HTML
@let vm = (model$ | async)!;
|
|
<div class="bg-surface-0 dark:bg-surface-950 p-6 md:p-12 lg:p-15 flex flex-col gap-8">
|
|
<div class="flex flex-col md:flex-row justify-between items-center md:items-end gap-4 md:gap-6">
|
|
<div>
|
|
<img src="assets/images/MUSA/logo.png"
|
|
alt="logo-consorzio-musa"
|
|
class="block mx-auto"
|
|
style="height: 50px" />
|
|
</div>
|
|
<div class="flex-1 flex flex-col text-center md:text-left">
|
|
<h1 class="text-surface-900 dark:text-surface-0 text-2xl font-semibold leading-tight">
|
|
Consorzio Mu.Sa.
|
|
</h1>
|
|
<h2 class="text-surface-500 dark:text-surface-200 text-xl font-normal leading-tight">
|
|
Cerca strutture convenzionate
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
|
|
<p-divider class="w-full my-0!"></p-divider>
|
|
<form [formGroup]="cercaStruttureForm"
|
|
(ngSubmit)="getStrutture()">
|
|
<div class="flex flex-wrap gap-8 md:gap-12 items-start">
|
|
<div
|
|
class="flex-1 bg-surface-0 dark:bg-surface-950 flex flex-col justify-start items-start gap-8 md:gap-12 w-full">
|
|
<div class="self-stretch flex flex-col justify-start items-start gap-6">
|
|
<div class="self-stretch flex flex-col justify-start items-start gap-6">
|
|
<div
|
|
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-lg md:text-xl font-semibold leading-tight">
|
|
Strutture Convenzionate</div>
|
|
<div class="self-stretch flex flex-col justify-start items-start gap-4">
|
|
<div class="self-stretch flex flex-col justify-start items-start gap-2">
|
|
<div id="tipoStruttura"
|
|
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
|
|
Tipologia struttura</div>
|
|
<p-dropdown [options]="vm.tipologieStrutture"
|
|
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0"
|
|
name="tiplogiaStruttura"
|
|
appendTo="body"
|
|
formControlName="tipologiaStruttura"
|
|
placeholder="Seleziona il tipo struttura"
|
|
showClear="true"
|
|
optionLabel="descrizione"
|
|
optionValue="codice"
|
|
ariaLabelledBy="tipoStruttura"
|
|
[filter]="true"></p-dropdown>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="self-stretch flex flex-col md:flex-row justify-start items-start gap-4">
|
|
<div class="flex-1 flex flex-col justify-start items-start gap-2 w-full">
|
|
<div id="luogoAutocomplete"
|
|
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
|
|
Luogo<small class="text-red-600">*
|
|
@if (
|
|
cercaStruttureForm.controls.luogo.errors?.['required'] &&
|
|
vm.cercaStruttureFormSubmitted
|
|
) {
|
|
Luogo obbligatorio
|
|
}
|
|
</small></div>
|
|
<p-autoComplete #acSt
|
|
formControlName="luogo"
|
|
[suggestions]="vm.filteredLuoghiEsteso"
|
|
(completeMethod)="fetchLuogo($event, 1)"
|
|
(onSelect)="state.set({ filteredLuoghiEsteso: [] })"
|
|
(onHide)="checkLuogo()"
|
|
styleClass="w-full"
|
|
inputStyleClass="w-full"
|
|
placeholder="Cerca per città, provincia o regione"
|
|
appendTo="body"
|
|
minLength="1"
|
|
[delay]="500"
|
|
scrollHeight="237px"
|
|
emptyMessage="Nessun luogo trovato"
|
|
[showClear]="true"
|
|
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0"
|
|
[ngClass]="{
|
|
'ng-invalid ng-dirty':
|
|
cercaStruttureForm.controls.luogo.errors?.['required'] &&
|
|
vm.cercaStruttureFormSubmitted
|
|
}"
|
|
dataKey="dataKey"
|
|
ariaLabelledBy="luogoAutocomplete"
|
|
optionLabel="luogo">
|
|
<ng-template let-luogo
|
|
#item>
|
|
<div class="flex align-items-center">
|
|
@if (luogo.tipo === 'comune') {
|
|
<fa-icon class="self-center fs-16 mr-3 text-color-secondary"
|
|
[icon]="faCity"></fa-icon>
|
|
<div class="flex flex-col">
|
|
<span>{{ luogo.comune
|
|
}}{{
|
|
luogo.codiceStato === 'ITA'
|
|
? ' (' + luogo.siglaProvincia + ')'
|
|
: ''
|
|
}}</span>
|
|
<small class="font-light text-xs text-color-secondary">
|
|
<i>{{
|
|
luogo.codiceStato === 'ITA'
|
|
? 'Comune: '
|
|
: ('Stato estero: ' | titlecase)
|
|
}}</i>{{
|
|
luogo.codiceStato === 'ITA'
|
|
? 'Italia → ' +
|
|
luogo.regione +
|
|
' → ' +
|
|
luogo.provincia +
|
|
' → ' +
|
|
luogo.comune
|
|
: ''
|
|
}}</small>
|
|
</div>
|
|
} @else if (luogo.tipo === 'stato') {
|
|
<fa-icon class="self-center fs-16 mr-3 text-color-secondary"
|
|
[icon]="faGlobeEurope"></fa-icon>
|
|
<div class="flex flex-col">
|
|
<span>{{ luogo.stato }}</span>
|
|
<small class="font-light text-xs text-color-secondary">
|
|
{{
|
|
luogo.codiceStato === 'ITA'
|
|
? ('Stato' | titlecase)
|
|
: ('Stato estero' | titlecase)
|
|
}}</small>
|
|
</div>
|
|
} @else if (luogo.tipo === 'regione') {
|
|
<fa-icon class="fs-16 mr-3 text-color-secondary"
|
|
[icon]="faMapLocationDot"></fa-icon>
|
|
<div class="flex flex-col">
|
|
<span>{{ luogo.regione }}</span>
|
|
<small class="font-light text-xs text-color-secondary">
|
|
<i>Regione:</i>
|
|
{{'Italia → ' + luogo.regione }}</small>
|
|
</div>
|
|
} @else if (luogo.tipo === 'provincia') {
|
|
<fa-icon class="self-center fs-16 mr-3 text-color-secondary"
|
|
[icon]="faMapLocationDot"></fa-icon>
|
|
<div class="flex flex-col">
|
|
<span>{{ luogo.provincia }}</span>
|
|
<small class="font-light text-xs text-color-secondary">
|
|
<i>Provincia:</i>
|
|
{{
|
|
'Italia → ' + luogo.regione + ' → ' + luogo.provincia
|
|
}}</small>
|
|
</div>
|
|
}
|
|
</div>
|
|
</ng-template>
|
|
</p-autoComplete>
|
|
</div>
|
|
<div class="flex-1 flex flex-col justify-start items-start gap-2 w-full">
|
|
<div id="indirizzo"
|
|
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
|
|
Indirizzo</div>
|
|
<input type="text"
|
|
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0 "
|
|
formControlName="indirizzo"
|
|
pInputText
|
|
aria-labelledby="indirizzo"
|
|
placeholder="Inserisci l'indirizzo" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="self-stretch flex flex-col md:flex-row justify-end items-center gap-4">
|
|
<button pButton
|
|
severity="secondary"
|
|
class="w-full md:w-auto"
|
|
(click)="cercaStruttureForm.reset()"
|
|
[outlined]="true">
|
|
<span pButtonLabel>Annulla filtri</span>
|
|
</button>
|
|
<button pButton
|
|
type="submit"
|
|
[disabled]="vm.isSearching"
|
|
[loading]="vm.isSearching"
|
|
icon="pi pi-search"
|
|
[label]="vm.isSearching ? 'Ricerca in corso...' : 'Cerca strutture'"
|
|
severity="primary"
|
|
class="w-full md:w-auto"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="flex-auto lg:flex-1 bg-surface-50 dark:bg-surface-900 rounded-2xl border-2 border-dashed border-surface-200 dark:border-surface-700 h-[350px] w-full lg:1/2">
|
|
<google-map #gmap
|
|
height="100%"
|
|
width="100%"
|
|
[options]="options">
|
|
<map-marker #marker="mapMarker"
|
|
*ngFor="let markerOption of markerOptions; let i = index"
|
|
[options]="markerOption"
|
|
(mapClick)="openInfoWindow(marker, i)"></map-marker>
|
|
<map-info-window></map-info-window>
|
|
</google-map>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<p-table #struttureTable
|
|
*ngIf="vm.strutture !== undefined"
|
|
[totalRecords]="vm.strutture.length"
|
|
dataKey="id"
|
|
[loading]="vm.struttureAreLoading"
|
|
[value]="vm.strutture"
|
|
[columns]="cols"
|
|
[showCurrentPageReport]="!vm.struttureAreLoading"
|
|
responsiveLayout="scroll"
|
|
currentPageReportTemplate="Strutture {first} - {last} di {totalRecords}"
|
|
[paginator]="true"
|
|
[rows]="10"
|
|
[autoLayout]="false"
|
|
responsiveLayout="stack"
|
|
scrollHeight="400px"
|
|
[rowsPerPageOptions]="[10, 50, 100]"
|
|
[globalFilterFields]="['struttura.nome', 'struttura.struttureTipiStrutture']">
|
|
<ng-template #caption>
|
|
<div class="flex">
|
|
<p-iconfield iconPosition="left"
|
|
class="ml-auto">
|
|
<p-inputicon>
|
|
<i class="pi pi-search"></i>
|
|
</p-inputicon>
|
|
<input pInputText
|
|
type="text"
|
|
aria-label="Filtra strutture"
|
|
(input)="applyFilterGlobal($event, 'contains')"
|
|
placeholder="Filtra strutture" />
|
|
</p-iconfield>
|
|
</div>
|
|
</ng-template>
|
|
|
|
<ng-template pTemplate="header"
|
|
let-columns>
|
|
<tr>
|
|
<th *ngFor="let col of cols"
|
|
pResizableColumn
|
|
[pSortableColumn]="col.sortField ?? ''"
|
|
class="p-table-scrollable-header">
|
|
<div style="display: flex; align-items: center; text-wrap: nowrap">
|
|
<div>
|
|
{{ col.header }}
|
|
<p-sortIcon *ngIf="col.sortField"
|
|
[field]="col.sortField"></p-sortIcon>
|
|
</div>
|
|
</div>
|
|
</th>
|
|
</tr>
|
|
</ng-template>
|
|
<ng-template pTemplate="body"
|
|
let-row
|
|
let-rowIndex="rowIndex">
|
|
<tr>
|
|
<ng-container *ngFor="let col of cols"
|
|
[ngSwitch]="col.field">
|
|
<td *ngSwitchCase="'struttura.struttureTipiStrutture'">
|
|
<div>
|
|
<ng-container *ngFor="let item of row.struttura.struttureTipiStrutture.split(',')">
|
|
<span class="font-light">{{ item.trim() }}</span><br />
|
|
</ng-container>
|
|
</div>
|
|
</td>
|
|
<td *ngSwitchCase="'struttura.nome'">
|
|
<div>
|
|
<p-rating *ngIf="row.struttura.stelline.length"
|
|
[(ngModel)]="row.struttura.stelline.length"
|
|
[readonly]="true" />
|
|
<p><b>{{ row.struttura.nome }}</b></p>
|
|
</div>
|
|
<div *ngIf="row.struttura.sitoWeb"
|
|
class="mt-4 ont-light">
|
|
<a class="cursor-pointer hover:underline text-primary-700"
|
|
(click)="externalLink(row.struttura.sitoWeb)">Sito Web</a>
|
|
</div>
|
|
</td>
|
|
<td *ngSwitchCase="'indirizzo'">
|
|
<span class="font-light">
|
|
<p> {{ row.struttura.indirizzo }}{{ row.struttura.numeroCivico ? ', ' + row.struttura.numeroCivico : '' }}
|
|
</p>
|
|
<p>
|
|
{{ row.struttura.cap }}
|
|
{{ row.struttura.codiceLuogo ? row.struttura.codiceLuogo.comune + ' (' +
|
|
row.struttura.codiceLuogo.siglaProvincia + ')' : ''
|
|
}}
|
|
</p>
|
|
<div class="text-sm"
|
|
*ngIf="row.struttura.cupPubblico">
|
|
CUP Pubblico:
|
|
<a class="cursor-pointer hover:underline text-primary-700"
|
|
href="tel:{{ row.struttura.cupPubblico }}">{{ row.struttura.cupPubblico }}</a>
|
|
</div>
|
|
<div *ngIf="row.struttura.cupPrivato"
|
|
class="text-sm">
|
|
CUP Privato:
|
|
<a class="cursor-pointer hover:underline text-primary-700"
|
|
href="tel:{{ row.struttura.cupPrivato }}">{{ row.struttura.cupPrivato }}</a>
|
|
</div>
|
|
<ng-container *ngIf="!row.struttura.cupPubblico && !row.struttura.cupPrivato">
|
|
<div *ngIf="row.struttura.telefono1"
|
|
class="text-sm">
|
|
tel:
|
|
<a class="cursor-pointer hover:underline text-primary-700"
|
|
href="tel:{{ row.struttura.telefono1 }}">{{ row.struttura.telefono1 }}</a>
|
|
</div>
|
|
<div *ngIf="row.struttura.telefono2"
|
|
class="text-sm">
|
|
tel:
|
|
<a class="cursor-pointer hover:underline text-primary-700"
|
|
href="tel:{{ row.struttura.telefono2 }}">{{ row.struttura.telefono2 }}</a>
|
|
</div>
|
|
</ng-container>
|
|
</span>
|
|
</td>
|
|
|
|
<td *ngSwitchCase="'posizione'">
|
|
<div class="flex align-items-center">
|
|
<p-button icon="pi pi-map-marker"
|
|
label="Apri in Google Maps"
|
|
[rounded]="true"
|
|
styleClass="hover:underline text-primary-700"
|
|
(onClick)="calculateMapsLink(row)"
|
|
[text]="true" />
|
|
</div>
|
|
</td>
|
|
</ng-container>
|
|
</tr>
|
|
</ng-template>
|
|
<ng-template #emptymessage>
|
|
<tr>
|
|
<td colspan="3">Nessuna struttura trovata.</td>
|
|
</tr>
|
|
</ng-template>
|
|
</p-table>
|
|
</div>
|
|
<p-toast />
|