const gen_id = (length)=>{ var result = ''; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const len = characters.length; for (let i = 0; i < length; i++ ) { result += characters.charAt(Math.floor(Math.random() * len)); } return result; } const query_nominatim = (q,f)=>{ const ENDPOINT = '/api/place/'+q; return axios.get(ENDPOINT).then(res=>res.data).then(res=>res.filter(f)); } const query_flight = (q)=>{ const ENDPOINT = '/api/flight/'+q; return axios.get(ENDPOINT).then(res=>res.data); } const is_restauration_type = (t)=>{ const arr = ["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"]; return arr.indexOf(t)!=-1; } const is_attraction_type = (item)=>{ const arr = ["tourism"]; return arr.indexOf(item.category)!=-1; } const icon_type = (item)=>{ let t = item.type const arr = ["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"]; if(arr.indexOf(t)!=-1){ return 'utensils'; }else if(t=='hotel'){ return 'bed'; }else if(t=='museum'){ return 'landmark'; }else if(t=='peak'){ return 'mountain'; }else if(t=='parking'){ return 'parking'; }else if(t=='water' || t=='river'){ return 'water'; }else if(t=='community_centre'){ return 'building'; }else if(t=='attraction'){ return 'landmark'; }else if(t=='information'){ return 'landmark'; }else if(t=='bridge'){ return 'archway'; }else if(t=='a'){ return ''; }else if(t=='a'){ return ''; }else{ console.log(item.category, item.type); return 'question'; } } Vue.component('l-map', window.Vue2Leaflet.LMap); Vue.component('l-tile-layer', window.Vue2Leaflet.LTileLayer); Vue.component('l-marker', window.Vue2Leaflet.LMarker); Vue.component('l-icon', window.Vue2Leaflet.LIcon); Vue.component('l-popup', window.Vue2Leaflet.LPopup); Vue.component('l-tooltip', window.Vue2Leaflet.LTooltip); Vue.component('l-control-scale', window.Vue2Leaflet.LControlScale); Vue.use(window.VueTextareaAutosize) Vue.component('multiselect', window.VueMultiselect.default) const app = new Vue({ el: '#app', data: { journey_id : window.location.pathname.split('/').at(-1) || gen_id(16), journey_step: window.location.hash.slice(1)==""?((window.location.pathname.split('/').at(1)=='view')?0:-1):parseInt(window.location.hash.slice(1)), journey_step_data: {day:-1, section:-1}, journey_data : { name: "New Journey", main:[], step_title:[], }, view: window.location.pathname.split('/').at(1)=='view', query:{hotel:[],flight:[],nominatim:[]}, querying:{hotel:false,flight:false,place:false,food:false}, impexp:"", }, methods: { start_journey: function(event){ window.location.href = '/'+this.journey_id; }, add_section: function(event){ if(this.journey_data.main===undefined) this.journey_data.main=[]; this.journey_data.main.push({map:{zoom:2}, hotel:{latlon:[0,0]},places:{restaurants:[],places:[]}}); }, next_step: function(){ this.journey_step+=1; this.journey_step_data = this.step_convert(this.journey_step); if(this.journey_step_data.section==-1) this.prev_step(); window.location.hash = '#' + this.journey_step; }, prev_step: function(){ this.journey_step-=1; if(this.journey_step<-1) this.journey_step=-1; if(this.journey_step==-1 && this.view) this.journey_step=0; this.journey_step_data = this.step_convert(this.journey_step); window.location.hash = '#' + this.journey_step; }, first_step: function(){ this.journey_step=-1; this.journey_step_data = {day:-1, section:-1}; window.location.hash = ''; }, step_convert: function(step){ let steps_left = step+1; for(let e in this.journey_data.main){ if(this.journey_data.main[e].dateRange && (this.journey_data.main[e].dateRange[0]-(new Date(0))) != 0){ let cd = (this.journey_data.main[e].dateRange[1]-this.journey_data.main[e].dateRange[0])/(1000*60*60*24); if(cd>=steps_left){ return {day: steps_left, section:e,start: (steps_left==1), end: (steps_left==cd)}; }else{ steps_left -= cd; } }else{ steps_left -= 1; } if(steps_left==0){ return {day:0,section:e, start:true,end:true}; } } return {day:-1, section:-1}; }, rm_section: function(idx){ this.journey_data.main.splice(idx,1); }, search_nominatim: function(txt,f){ if(txt==""){ this.query.nominatim=[]; return Promise.resolve([]); } return query_nominatim(txt,f) .then((results) =>{ results.forEach(r=>{ r.latlon=[parseFloat(r.lat),parseFloat(r.lon)]; r.sname=r.display_name.split(',')[0]; }) this.query.nominatim=results; }); }, search_flight: function(txt){ if(txt=="") return; this.querying.flight=true; query_flight(txt.replace(" ", "")) .then((results) =>{ if(results.results==""){ this.query.flight=[];this.querying.flight=false;return; } this.query.flight=results.results; this.querying.flight=false; }); }, generate_icon: function(item,fcolor){ return L.AwesomeMarkers.icon({ icon: icon_type(item) || 'star', prefix: 'fa', markerColor: fcolor || item.color || 'blue'} ).createIcon().outerHTML }, save_data: function(){ this.impexp = window.btoa(JSON.stringify(this.journey_data)); axios.post('/api/'+this.journey_id, this.journey_data).then(response => { console.log("Saved...") }).catch(error => { console.warn('Error! Could not reach the API.') }) }, import_data:function(){ this.journey_data = JSON.parse(window.atob(this.impexp)); }, export_data:function(){ this.impexp = window.btoa(JSON.stringify(this.journey_data)); }, filter_selected:function(list,step){ return list.filter(e=>(step?(e.step==this.journey_step):(e.step>=0))) }, filter_unselected:function(list){ return list.filter(e=>(e.step==undefined || e.step<0)) }, remove_item:function(list,idx){ list[idx].step=-1; list.splice(idx, 1); }, log:function(e){console.log(e)}, }, created: function () { axios.get('/api/'+this.journey_id).then(response =>{ app.journey_data = response.data; for(let e of app.journey_data.main){ if(e.dateRange && e.dateRange.length===2){ e.dateRange[0]= new Date(e.dateRange[0]); e.dateRange[1]= new Date(e.dateRange[1]); } } this.journey_step_data = this.step_convert(this.journey_step); }); this.debounceSave = _.debounce(this.save_data, 500) this.debounceSearch = {"hotel":_.debounce((q)=>{this.querying.hotel=true;this.search_nominatim(q,(r)=>(r.type=="hotel")).then((r)=>{this.querying.hotel=false});}, 500), "restaurants":_.debounce((q)=>{this.querying.food=true;this.search_nominatim(q,(r)=>(is_restauration_type(r.type))).then((r)=>{this.querying.food=false});}, 500), "places":_.debounce((q)=>{this.querying.place=true;this.search_nominatim(q,(r)=>(true)).then((r)=>{this.querying.place=false});}, 500), "other":_.debounce((q)=>{this.querying.any=true;this.search_nominatim(q,(r)=>(true)).then((r)=>{this.querying.any=false});}, 500), "flight":_.debounce((q)=>this.search_flight(q), 500) } }, watch: { journey_data: { handler:function (ndata, odata){ this.debounceSave() if(ndata.main.length == odata.main.length){ for(let d in ndata.main){ if(ndata.main[d].hotel != odata.main[d].hotel){ if(ndata.main[d].hotel.latlon){ this.journey_data.main[d].map.center=ndata.main[d].hotel.latlon; } } } } }, deep: true, }, }, })