OTM/public/template/journey.html
soraefir 0693d47939
All checks were successful
continuous-integration/drone/push Build is passing
Added Notes and Folding
2023-06-19 13:14:52 +02:00

530 lines
36 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>Helcel-OTM</title>
<link rel='shortcut icon' href='/public/img/helcel.ico' type='image/x-icon'/>
<meta charset='utf-8'/>
<meta name='viewport' content='width=device-width, initial-scale=1'/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=IBM+Plex+Sans:400,700,300" type="text/css">
<link rel='stylesheet' href='/public/css/index.css'/>
<link rel="stylesheet" href="https://unpkg.com/vue2-datepicker/index.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.awesome-markers/dist/leaflet.awesome-markers.css">
<link rel="stylesheet" href="https://unpkg.com/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect/dist/vue-multiselect.min.css">
</head>
<body>
<main id="app">
<div v-if="vtp==-1" v-cloak>
<header class="header">
<div class="header-inner container">
<a href="/" class="header-logo text-dark">
<img class="header-logoImage" src="/public/img/helcel.png" alt="Helcel logo" width="40">
<span class="hide-small">HOTM</span>
</a>
<div class="input input-invis"><input class="small" v-model="journey_data.name" type="text" /></div>
<div class="row header-nav text-big" style="margin-bottom: 0;">
<div class="col-sm-2"><a :href="'/short/'+journey_id" ><i class="fas fa-file-contract"></i></a></div>
<div class="col-sm-2"><a :href="'/view/'+journey_id +'#0'" ><i class="fas fa-camera"></i></a></div>
<div class="col-sm-2"><a href="#main" v-on:click.prevent="first_step"><i class="fas fa-tools"></i></a></div>
<div class="col-sm-1 text-small"><a href="#prevprev" v-on:click.prevent="prevprev_step"><i class="fas fa-angle-double-left"></i></a></div>
<div class="col-sm-1"><a href="#prev" v-on:click.prevent="prev_step"><i class="fas fa-angle-left"></i></a></div>
<div class="col-sm-1"><a href="#next" v-on:click.prevent="next_step"><i class="fas fa-angle-right"></i></a></div>
<div class="col-sm-1 text-small"><a href="#nextnext" v-on:click.prevent="nextnext_step"><i class="fas fa-angle-double-right"></i></a></div>
</div>
</div>
</header>
<div v-if="journey_step==-1">
<div v-for="(item,idx) in journey_data.main" :class="idx%2===0 ? 'bg-dark text-white' : ''" v-cloak>
<div class="container section">
<div class="row text-center">
<div class="col-auto"><button class="button button--secondary button--mobileFull" v-on:click="rm_section(idx)">X</button></div>
<div class="col-auto"><button class="button button--secondary button--mobileFull" v-on:click="toggle_section_vis(idx)">-</button></div>
<div class="input col-sm-4"><input class="" v-model="item.title" type="text" /></div>
</div>
<div class="row" v-if="visible_step & (0x1 << idx)">
<div class="col-12 col-sm-8">
<l-map
:zoom.sync="item.map.zoom"
:center.sync="item.map.center"
style="padding-top: 100%;"
>
<l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
></l-tile-layer>
<l-control-scale position="topright" :imperial="false" :metric="true"></l-control-scale>
<l-marker v-if="item.hotel" :lat-lng.sync="item.hotel.latlon">
<l-icon>
<div v-html="generate_icon(item.hotel,'darkblue')"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{item.hotel.sname}}</h1>
<span class="row text-small text-gray">{{item.hotel.display_name}}</span>
<div class="row input">
<textarea-autosize
class="col-12 col-sm-10 text-small"
placeholder="Notes"
v-model="item.hotel.notes"
:min-height="30"
:max-height="350"
/>
</div>
</l-popup>
<!-- <l-tooltip :options="{ permanent: true, interactive: true }">
<div>
H
</div>
</l-tooltip> -->
</l-marker>
<l-marker v-for="place in item.places.restaurants" :lat-lng.sync="place.latlon">
<l-icon>
<div v-html="generate_icon(place,'cadetblue')"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
<div class="row input">
<textarea-autosize
class="col-12 col-sm-10 text-small"
placeholder="Notes"
v-model="place.notes"
:min-height="30"
:max-height="350"
/>
</div>
</l-popup>
</l-marker>
<l-marker v-for="place in item.places.activities" :lat-lng.sync="place.latlon">
<l-icon>
<div v-html="generate_icon(place)"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
<div class="row input">
<textarea-autosize
class="col-12 col-sm-10 text-small"
placeholder="Notes"
v-model="place.notes"
:min-height="30"
:max-height="350"
/>
</div>
</l-popup>
</l-marker>
</l-map>
</div>
<div class="col-12 col-sm-4">
<div class="row text-center">
<div><label>Date Range</label></div>
<div class="input text-dark">
<date-picker :lang="lang" v-model="item.dateRange" range placeholder="Date Range"></date-picker>
</div>
</div>
<div class="row text-center">
<div><label>Hotel</label></div>
<multiselect v-model="item.hotel" id="ajax" label="sname" track-by="place_id" placeholder="Type to search" open-direction="bottom" :options="query.nominatim" :searchable="true" :loading="querying.hotel" :internal-search="false" :clear-on-select="false" :options-limit="50" :limit="1" :max-height="600" @search-change="debounceSearch.hotel"></multiselect>
</div>
<div class="row text-center">
<div><label>Fight</label></div>
<multiselect v-model="item.flightA" id="ajax" label="label" track-by="id" placeholder="Type to search" open-direction="bottom" :multiple="true" :options="query.flight" :searchable="true" :loading="querying.flight" :internal-search="false" :clear-on-select="false" :options-limit="50" :limit="10" :max-height="600" @search-change="debounceSearch.flight"></multiselect>
<multiselect v-model="item.flightB" id="ajax" label="label" track-by="id" placeholder="Type to search" open-direction="bottom" :multiple="true" :options="query.flight" :searchable="true" :loading="querying.flight" :internal-search="false" :clear-on-select="false" :options-limit="50" :limit="10" :max-height="600" @search-change="debounceSearch.flight"></multiselect>
</div>
<div class="row text-center">
<div><label>Restoration</label></div>
<multiselect v-model="item.places.restaurants" id="ajax" label="sname" track-by="place_id" placeholder="Type to search" open-direction="bottom" :multiple="true" :options="query.nominatim" :searchable="true" :loading="querying.food" :internal-search="false" :clear-on-select="false" :options-limit="50" :limit="10" :max-height="600" @search-change="debounceSearch.restaurants"></multiselect>
</div>
<div class="row text-center">
<div><label>Activities</label></div>
<multiselect v-model="item.places.activities" id="ajax" label="sname" track-by="place_id" placeholder="Type to search" open-direction="bottom" :multiple="true" :options="query.nominatim" :searchable="true" :loading="querying.place" :internal-search="false" :clear-on-select="false" :options-limit="50" :limit="10" :max-height="600" @search-change="debounceSearch.places"></multiselect>
</div>
<div class="row text-center">
<div><label>Notes</label></div>
<div class="input text-dark" style="width:100%;">
<textarea-autosize
v-model="item.notes"
class="text-small"
placeholder="Notes"
:min-height="30"
:max-height="350"
></textarea-autosize>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class="container-medium section">
</div>
</div>
<div class="bg-dark">
<div id="go" class="container-medium section text-white">
<h2 class="text-big">Add new section</h2>
<p>Got an other flight and/or hotel ? Add a new section to register it</p>
<div class="aligner aligner--contentEnd">
<button class="button button--primary button--mobileFull" v-on:click="add_section">Add Section</button>
</div>
</div>
</div>
</div>
<div v-else-if="journey_step>=0 && journey_data.main[journey_step_data.section] != undefined">
<div class="bg-dark text-white">
<div class="container section">
<div class="row text-center">
<div class="input col-sm-4"><input disabled :value="journey_data.main[journey_step_data.section].title + ': Day ' + journey_step_data.day" /></div>
<div class="input col-sm-2"><input placeholder="Day title" v-model="journey_data.step_title[journey_step]" /></div>
<div class="col-sm-3"></div>
<div class="right input col-sm-2 "><input disabled :value="active_date()" /></div>
</div>
<div class="row">
<div class="col-12 col-sm-12">
<l-map
:zoom=" journey_data.main[journey_step_data.section].map.zoom"
:center="journey_data.main[journey_step_data.section].map.center"
style="padding-top: 100%;"
>
<l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
></l-tile-layer>
<l-control-scale position="topright" :imperial="false" :metric="true"></l-control-scale>
<l-marker v-if="journey_data.main[journey_step_data.section].hotel &&
journey_data.main[journey_step_data.section].hotel.icon"
:lat-lng="journey_data.main[journey_step_data.section].hotel.latlon">
<l-icon>
<div v-html="generate_icon(journey_data.main[journey_step_data.section].hotel,'darkblue')"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{journey_data.main[journey_step_data.section].hotel.sname}}</h1>
<span class="row text-small text-gray">{{journey_data.main[journey_step_data.section].hotel.display_name}}</span>
<div class="row input">
<textarea-autosize
class="col-12 col-sm-10 text-small"
placeholder="Notes"
v-model="journey_data.main[journey_step_data.section].hotel.notes"
:min-height="30"
:max-height="350"
/>
</div>
</l-popup>
</l-marker>
<l-marker v-for="place in journey_data.main[journey_step_data.section].places.activities" :lat-lng="place.latlon">
<div v-if="place.step==journey_step">
<l-icon>
<div v-html="generate_icon(place)"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
<div class="row input">
<textarea-autosize
class="col-12 col-sm-10 text-small"
placeholder="Notes"
v-model="place.notes"
:min-height="30"
:max-height="350"
/>
</div>
<a class="leaflet-popup-close-button text-gray" style="bottom:9px;top:auto; " href="#rm" v-on:click.prevent="place.step=-1">-</a>
</l-popup>
</div>
<div v-else-if="place.step >= 0">
<l-icon>
<div v-html="generate_icon(place,'orange')"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
<div class="row input">
<textarea-autosize
class="col-12 col-sm-10 text-small"
placeholder="Notes"
v-model="place.notes"
:min-height="30"
:max-height="350"
/>
</div>
<a class="leaflet-popup-close-button text-gray" style="bottom:9px;top:auto; " href="#add" v-on:click.prevent="place.step=journey_step">+</a>
</l-popup>
</div>
<div v-else-if="place.step==undefined || place.step == -1">
<l-icon>
<div v-html="generate_icon(place,'red')"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
<div class="row input">
<textarea-autosize
class="col-12 col-sm-10 text-small"
placeholder="Notes"
v-model="place.notes"
:min-height="30"
:max-height="350"
/>
</div>
<a class="leaflet-popup-close-button text-gray" style="bottom:9px;top:auto; " href="#add" v-on:click.prevent="place.step=journey_step">+</a>
</l-popup>
</div>
<div v-else>
<l-icon>
<div v-html="generate_icon()"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
</l-popup>
</div>
</l-marker>
</l-map>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12">
<div class="container text-center" v-if="journey_step_data.start || journey_step_data.end">
<b>Flights</b>
<div v-if="journey_step_data.start">
<div v-for="element in journey_data.main[journey_step_data.section].flightA"><a href="#fligh" v-on:click.prevent="window.open('https://www.flightradar24.com/data/flights/'+element.id,'_blank')">{{ element.label }}</a></div>
</div>
<div v-if="journey_step_data.end">
<div v-for="element in journey_data.main[journey_step_data.section].flightB"><a href="#fligh" v-on:click.prevent="window.open('https://www.flightradar24.com/data/flights/'+element.id,'_blank')">{{ element.label }}</a></div>
</div>
</div>
<div class="container"></div>
</div>
</div>
</div>
</div>
<div class="">
<div class="container-medium section">
</div>
</div>
<div class="bg-dark">
</div>
</div>
<div class="">
<div class="container-medium section">
<div class="aligner">
<div class="input col-sm-4"><input class="" v-model="impexp" type="text" /></div>
<div class="col-sm-2"><button class="button button--primary button--mobileFull" v-on:click="import_data">Import</button></div>
<div class="col-sm-2"><button class="button button--primary button--mobileFull" v-on:click="export_data">Export</button></div>
</div>
</div>
</div>
</div>
<div v-if="vtp==0 && journey_data.main[journey_step_data.section] != undefined" v-cloak>
<div class="bg-dark text-white" v-cloak>
<div class="text-small fright" style="margin:6px 12px;"><a :href="'/'+journey_id" ><i class="fas fa-tools"></i></a></div>
<div class="container section">
<div class="aligner text-center text-white text-huge" style="margin-bottom:5px">
<div class="aligner--itemTop fleft"><a href="#prev" v-on:click.prevent="prev_step"><i class="fas fa-angle-left"></i></a></div>
<span class="container">
<div>{{journey_data.main[journey_step_data.section].title + ': Day ' + journey_step_data.day}}</div>
<div class="text-big text-gray">{{journey_data.step_title[journey_step]}}</div>
</span>
<div class="aligner--itemEnd fright"><a href="#next" v-on:click.prevent="next_step"><i class="fas fa-angle-right"></i></a></div>
</div>
<div class="row">
<div class="col-12 col-sm-12">
<l-map
:zoom=" journey_data.main[journey_step_data.section].map.zoom"
:center="journey_data.main[journey_step_data.section].map.center"
style="padding-top: 100%;"
>
<l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
></l-tile-layer>
<l-control-scale position="topright" :imperial="false" :metric="true"></l-control-scale>
<l-marker v-if="journey_data.main[journey_step_data.section].hotel &&
journey_data.main[journey_step_data.section].hotel.icon"
:lat-lng="journey_data.main[journey_step_data.section].hotel.latlon">
<l-icon>
<div v-html="generate_icon(journey_data.main[journey_step_data.section].hotel,'darkblue')"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{journey_data.main[journey_step_data.section].hotel.sname}}</h1>
<span class="row text-small text-gray">{{journey_data.main[journey_step_data.section].hotel.display_name}}</span>
<span class="row text-small text-white">{{journey_data.main[journey_step_data.section].hotel.notes}}</span>
</l-popup>
</l-marker>
<l-marker v-for="place in journey_data.main[journey_step_data.section].places.activities" :lat-lng="place.latlon" v-if="place.step==journey_step" >
<l-icon>
<div v-html="generate_icon(place)"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
<span class="row text-small text-dark">{{place.notes}}</span>
</l-popup>
</l-marker>
<l-marker v-for="place in journey_data.main[journey_step_data.section].places.activities" :lat-lng="place.latlon" v-if="place.step==undefined || place.step==-1" >
<l-icon>
<div v-html="generate_icon(place,'gray')"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
<span class="row text-small text-dark">{{place.notes}}</span>
</l-popup>
</l-marker>
<l-marker v-for="place in journey_data.main[journey_step_data.section].places.restaurants" :lat-lng.sync="place.latlon">
<l-icon>
<div v-html="generate_icon(place,'cadetblue')"></div>
</l-icon>
<l-popup>
<h1 class="row text-medium text-center">{{place.sname}}</h1>
<span class="row text-small text-gray">{{place.display_name}}</span>
<span class="row text-small text-dark">{{place.notes}}</span>
</l-popup>
</l-marker>
</l-map>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-12">
<div class="container text-center" v-if="journey_step_data.start || journey_step_data.end">
<b>Flights</b>
<div v-if="journey_step_data.start">
<div v-for="element in journey_data.main[journey_step_data.section].flightA"><a href="#fligh" v-on:click.prevent="window.open('https://www.flightradar24.com/data/flights/'+element.id,'_blank')">{{ element.label }}</a></div>
</div>
<div v-if="journey_step_data.end">
<div v-for="element in journey_data.main[journey_step_data.section].flightB"><a href="#fligh" v-on:click.prevent="window.open('https://www.flightradar24.com/data/flights/'+element.id,'_blank')">{{ element.label }}</a></div>
</div>
</div>
<div class="container"></div>
</div>
</div>
</div>
</div>
</div>
<div v-if="vtp==1" v-cloak>
<header class="header">
<div class="header-inner container">
<a href="/" class="header-logo text-dark">
<img class="header-logoImage" src="/public/img/helcel.png" alt="Helcel logo" width="40">
<span class="hide-small">HOTM</span>
</a>
<div class="input input-invis"><input class="small" :value="journey_data.name" type="text" disabled/></div>
<div class="row header-nav text-big" style="margin-bottom: 0;">
<div class="col-sm-3"><a :href="'/short/'+journey_id" ><i class="fas fa-file-contract"></i></a></div>
<div class="col-sm-3"><a :href="'/view/'+journey_id +'#0'" ><i class="fas fa-camera"></i></a></div>
</div>
</div>
</header>
<div v-for="(item,idx) in journey_data.main" :class="idx%2===0 ? 'bg-dark text-white' : ''">
<!-- <div class="bg-dark"> -->
<div class="container section">
<div class="row text-center">
<div class="input col-sm-2"><input class="" disabled :value="item.title"/></div>
<div class="input col-sm-4"><input disabled placeholder="No Dates" :value="item.dateRange? (format_date(item.dateRange[0]) + ' - '+ format_date(item.dateRange[1])):''"/></div>
<div class="input col-sm-2"><input disabled placeholder="No Hotel" :value="item.hotel.sname"/></div>
</div>
<div class="row text-center">
<div class="input col-sm-3" v-if="item.transit">
<div v-for="(item,idx) in item.transit">
<input disabled :value="item.map(v=>v.id).join(', ')"/>
</div>
</div>
<div class="input col-sm-3" v-if="item.flightA"><input disabled :value="item.flightA.map(v=>v.id).join(', ')"/></div>
<div class="input col-sm-3" v-if="item.flightB"><input disabled :value="item.flightB.map(v=>v.id).join(', ')"/></div>
</div>
<div class="row text-center">
<div class="input col-sm-8" v-if="item.places && item.places.restaurants">
<textarea-autosize
class="text-small"
placeholder="No Restaurants"
:value="item.places.restaurants.map(v=>v.sname+(v.notes?('('+v.notes+')'):'')).join(', ')"
:min-height="30"
:max-height="350"
disabled
/></div>
</div>
<div class="row text-center">
<div class="input col-sm-8" v-if="item.places && item.places.activities">
<textarea-autosize
class="text-small"
placeholder="No Activities"
:value="item.places.activities.map(v=>v.sname+(v.notes?('('+v.notes+')'):'')).join(', ')"
:min-height="30"
:max-height="350"
disabled
/></div>
</div>
<div class="row text-center">
<div class="input col-sm-8" v-if="item.notes">
<textarea-autosize
class="text-small"
placeholder="No Notes"
:value="item.notes"
:min-height="30"
:max-height="350"
disabled
/></div>
</div>
</div>
<!-- </div>
<div class="bg-white">
<div class="container section">
</div>
</div> -->
</div>
</div>
</main>
<script src="https://unpkg.com/vue@2/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue2-datepicker/index.min.js"></script>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script src="https://unpkg.com/vue2-leaflet"></script>
<script src="https://unpkg.com/leaflet.awesome-markers/dist/leaflet.awesome-markers.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/lodash"></script>
<script src="https://unpkg.com/vue-multiselect"></script>
<script src="https://unpkg.com/vue-textarea-autosize/dist/vue-textarea-autosize.umd.min.js"></script>
<script src="/public/js/main.js" type="text/javascript" charset="utf-8"></script>
<footer class="bg-dark">
<div class="container">
<div class="section text-center text-small">
<p class="text-white">
<img src="/public/img/helcel.png" alt="helcel logo" width="100"><br><br>
Built with &nbsp;&nbsp; by Helcel <br><span class="text-small text-gray">v0.0.1</span>
</p>
</div>
</div>
</footer>
</body>
</html>