Gliding Logbook
Saving...
Enter
Welcome to your LogbookTotal Flights: 0 Total Hours: 0:00 Average Flight Time: 0:00 Last Glider: N/A Your FlightsTotal Flights: 0 Export to ExcelAdd FlightDate: Glider: Glider Type: Instructor: Solo? Yes No Time (hh:mm) Departure: Arrival: Distance: Launch Type: Crew Capacity: Thermals caught: Notes: Save FlightProfile & SettingsName:GlidersAdd GliderInstructorsAdd InstructorSettingsTheme Color:StatisticsTotal Flights: 0 Total Hours: 0:00 Average Flight Time: 0:00 Average Height: N/A m Share FlightCloseEditDeleteShare `;
list.appendChild(div);
});
}
function deleteFlight(i){if(confirm('Delete flight?')){flights.splice(i,1);saveAll();updateFlightList();updateStats();}}
function editFlight(i){showPage('add-flight-page');const f=flights[i];document.getElementById('flight-date').value=f.date;document.getElementById('flight-glider').value=f.glider;document.getElementById('flight-glider-type').value=f.gliderType;document.getElementById('flight-instructor').value=f.instructor;document.getElementById('flight-solo').value=f.solo;document.getElementById('flight-time').value=f.time;document.getElementById('flight-departure').value=f.departure;document.getElementById('flight-arrival').value=f.arrival;document.getElementById('flight-distance').value=f.distance;document.getElementById('flight-launch').value=f.launch;document.getElementById('flight-crew').value=f.crew;document.getElementById('flight-thermals').value=f.thermals;document.getElementById('flight-notes').value=f.notes;flights.splice(i,1);}
// Gliders/Instructors
function addGlider(){const g=document.getElementById('new-glider').value;const t=document.getElementById('new-glider-type').value;if(!g) return;gliders.push({name:g,type:t});saveAll();updateProfile();document.getElementById('new-glider').value='';document.getElementById('new-glider-type').value='';}
function addInstructor(){const ins=document.getElementById('new-instructor').value;if(!ins) return;instructors.push(ins);saveAll();updateProfile();document.getElementById('new-instructor').value='';}
function updateProfile(){
const gList=document.getElementById('gliders-list'); gList.innerHTML=''; gliders.forEach((g,i)=>{const li=document.createElement('li');li.textContent=`${g.name} (${g.type})`;gList.appendChild(li);});
const iList=document.getElementById('instructors-list'); iList.innerHTML=''; instructors.forEach((i)=>{const li=document.createElement('li');li.textContent=i;iList.appendChild(li);});
const gliderSelect=document.getElementById('flight-glider'); gliderSelect.innerHTML=''; gliders.forEach(g=>{const opt=document.createElement('option');opt.value=g.name;opt.textContent=g.name;gliderSelect.appendChild(opt);});
const insSelect=document.getElementById('flight-instructor'); insSelect.innerHTML=''; instructors.forEach(ins=>{const opt=document.createElement('option');opt.value=ins;opt.textContent=ins;insSelect.appendChild(opt);});
}
// Achievements
function unlockAchievement(text,test=false){
const overlay=document.getElementById('achievement-overlay');
document.getElementById('achievement-text').textContent=text;
document.getElementById('achievement-instruction').textContent='Click anywhere to continue';
overlay.style.display='flex';
const audio=new Audio('https://www.soundjay.com/button/beep-07.mp3');
audio.play();
}
function closeAchievement(){document.getElementById('achievement-overlay').style.display='none';}
// Share
function shareFlight(i){
const f=flights[i];
const content=document.getElementById('share-content');
content.innerHTML=`Date: ${f.date} Glider: ${f.glider} Type: ${f.gliderType} Instructor: ${f.instructor||'None'} Solo: ${f.solo} Time: ${f.time} Departure: ${f.departure} Arrival: ${f.arrival} Distance: ${f.distance} Launch Type: ${f.launch} Crew: ${f.crew} Thermals: ${f.thermals} Notes: ${f.notes} `; document.getElementById('share-overlay').style.display='flex'; } function closeShare(){document.getElementById('share-overlay').style.display='none';} // Theme function setThemeColor(color){document.documentElement.style.setProperty('--primary-blue',color);document.documentElement.style.setProperty('--light-blue',color);document.documentElement.style.setProperty('--hover-blue',color);} function updateStats(){document.getElementById('total-flights').textContent=flights.length;let totalMins=flights.reduce((a,f)=>{const t=f.time.split(':');return a+parseInt(t[0])*60+parseInt(t[1]);},0);let hrs=Math.floor(totalMins/60);let mins=totalMins%60;document.getElementById('total-hours').textContent=`${hrs}:${mins.toString().padStart(2,'0')}`;document.getElementById('avg-time').textContent=flights.length?`${Math.floor(totalMins/flights.length/60)}:${Math.floor(totalMins/flights.length%60).toString().padStart(2,'0')}`:'0:00';document.getElementById('last-glider').textContent=flights.length?flights[flights.length-1].glider:'N/A';updateProfile();} function initCharts(){updateStats();} // Excel Export function exportToExcel(){ if(!flights.length){alert("No flights to export."); return;} const ws_data=[["Flight Number","Date","Glider","Type","Departure","Arrival","Launch Type","Crew Capacity","PIC Name","Flight Time","Remarks"]]; flights.forEach((f,i)=>{ ws_data.push([i+1,f.date,f.glider,f.gliderType,f.departure,f.arrival,f.launch,f.crew,f.instructor,f.time,f.notes]); }); const wb=XLSX.utils.book_new(); const ws=XLSX.utils.aoa_to_sheet(ws_data); XLSX.utils.book_append_sheet(wb,ws,"Flights"); XLSX.writeFile(wb,"Glider_Logbook.xlsx"); } |