Spaces:
Running
Running
Download flights.html from Wayed11/wheelie-app: direct link, hf CLI and curl.
- Browser
- Download file 17.3 kB
-
https://huggingface.co/spaces/Wayed11/wheelie-app/resolve/main/flights.html
- Command line
-
hf download hf://spaces/Wayed11/wheelie-app/flights.html
-
curl -L -o flights.html https://huggingface.co/spaces/Wayed11/wheelie-app/resolve/main/flights.html
17.3 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> | |
| <title>Fly with Wheelie</title> | |
| <meta name="theme-color" content="#000000"> | |
| <link rel="icon" type="image/png" href="wheelie-icon.png?v=2"> | |
| <link rel="apple-touch-icon" href="wheelie-icon.png?v=2"> | |
| <style> | |
| :root{--pink:#FF6FB5;--blue:#5BC0F8;--ok:#1fd1a0;--card:#111116;--line:rgba(255,255,255,.12);--dim:#a1a1aa;color-scheme:dark} | |
| *{box-sizing:border-box;-webkit-tap-highlight-color:transparent} | |
| html,body{margin:0;background:#000;color:#fff;font:17px/1.45 -apple-system,BlinkMacSystemFont,"SF Pro Text",system-ui,sans-serif} | |
| body{padding:calc(env(safe-area-inset-top) + 12px) 16px calc(env(safe-area-inset-bottom) + 40px);max-width:640px;margin:0 auto} | |
| button,input,select{font:inherit;color:inherit} | |
| a{color:var(--blue)} | |
| .top{display:flex;align-items:center;gap:12px;margin-bottom:18px} | |
| .back{width:46px;height:46px;border-radius:50%;border:1px solid var(--line);background:#121218;display:flex;align-items:center;justify-content:center;font-size:24px;color:#fff;text-decoration:none;flex:none} | |
| .av{flex:0 0 52px;height:52px;border-radius:50%;padding:3px;background:conic-gradient(var(--pink) 0 50%,var(--blue) 50% 100%)} | |
| .av img{width:100%;height:100%;border-radius:50%;object-fit:cover;border:2px solid #000;display:block} | |
| .av.talk{animation:tk .6s ease-in-out infinite}@keyframes tk{50%{transform:scale(1.08)}} | |
| .top b{display:block;font-size:24px;font-weight:800;letter-spacing:-.4px} | |
| .top small{display:block;color:var(--dim);font-size:15px} | |
| .card{background:var(--card);border:1px solid var(--line);border-radius:24px;padding:16px;margin-bottom:16px} | |
| label.l{display:block;font-size:14px;font-weight:700;color:var(--dim);margin:0 0 6px 4px;letter-spacing:.3px;text-transform:uppercase} | |
| .fld{position:relative;margin-bottom:12px} | |
| .fld input,.fld select{width:100%;height:58px;border-radius:16px;border:1px solid rgba(255,255,255,.18);background:#0b0b10;padding:0 16px;font-size:18px;outline:none} | |
| .fld input:focus{border-color:var(--pink);box-shadow:0 0 0 3px rgba(255,111,181,.25)} | |
| .sug{position:absolute;left:0;right:0;top:62px;z-index:5;background:#16161d;border:1px solid var(--line);border-radius:16px;overflow:hidden;display:none} | |
| .sug.on{display:block} | |
| .sug button{display:flex;gap:12px;align-items:center;width:100%;text-align:left;border:0;background:none;padding:12px 14px;border-bottom:1px solid var(--line);min-height:58px} | |
| .sug button:last-child{border-bottom:0} | |
| .sug .code{flex:0 0 52px;height:36px;border-radius:10px;background:#000;border:1px solid var(--blue);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:14px;color:var(--blue)} | |
| .sug b{display:block;font-size:16px}.sug small{display:block;color:var(--dim);font-size:13px} | |
| .row{display:flex;gap:10px}.row>*{flex:1;min-width:0} | |
| .swap{flex:0 0 auto;align-self:center;width:46px;height:46px;border-radius:50%;border:1px solid var(--line);background:#16161d;font-size:20px;margin:-4px auto 8px;display:flex;align-items:center;justify-content:center} | |
| .chips{display:flex;gap:8px;flex-wrap:wrap;margin:2px 0 12px} | |
| .chip{height:42px;border-radius:999px;border:1px solid var(--line);background:#16161d;padding:0 16px;font-weight:600;font-size:15px} | |
| .chip.on{border-color:var(--pink);box-shadow:inset 0 0 0 1px var(--pink)} | |
| .go{width:100%;height:62px;border-radius:20px;border:0;background:var(--pink);color:#000;font-weight:800;font-size:19px} | |
| .go:active{transform:scale(.98)} | |
| h2{font-size:22px;margin:26px 4px 10px;letter-spacing:-.3px} | |
| .say{display:flex;gap:10px;align-items:flex-start;margin:0 0 14px} | |
| .say .av{flex-basis:40px;height:40px} | |
| .say p{margin:0;background:#16161d;border:1px solid var(--line);border-radius:4px 18px 18px 18px;padding:10px 12px;font-size:16px} | |
| .fl{display:block;background:var(--card);border:1px solid var(--line);border-radius:22px;padding:16px;margin-bottom:12px;text-decoration:none;color:#fff} | |
| .fl.best{border-color:transparent;box-shadow:0 0 0 2px var(--pink),0 0 0 4px var(--blue)} | |
| .fl .h{display:flex;justify-content:space-between;align-items:baseline;gap:10px} | |
| .fl .p{font-size:30px;font-weight:800;letter-spacing:-.5px} | |
| .fl .al{font-weight:700;font-size:17px;text-align:right} | |
| .fl .r{font-size:18px;font-weight:700;margin-top:6px;font-variant-numeric:tabular-nums} | |
| .fl .m{color:var(--dim);font-size:15px;margin-top:2px} | |
| .fl .bk{display:flex;align-items:center;justify-content:center;height:52px;border-radius:16px;background:var(--blue);color:#000;font-weight:800;margin-top:12px} | |
| .tag{display:inline-block;font-size:12px;font-weight:800;letter-spacing:.4px;padding:4px 8px;border-radius:8px;background:var(--pink);color:#000;margin-bottom:8px} | |
| .note{color:var(--dim);font-size:14px;margin:4px 4px 0} | |
| .loading{display:flex;gap:10px;align-items:center;color:#ddd;padding:16px 4px} | |
| .spin{width:22px;height:22px;border-radius:50%;border:3px solid #333;border-top-color:var(--pink);border-right-color:var(--blue);animation:sp .9s linear infinite}@keyframes sp{to{transform:rotate(360deg)}} | |
| .help .al2{display:flex;align-items:center;gap:12px;padding:12px 0;border-top:1px solid var(--line)} | |
| .help .al2:first-of-type{border-top:0} | |
| .help .al2 b{display:block;font-size:17px} | |
| .help .al2 small{display:block;color:var(--dim);font-size:14px} | |
| .help .al2 .ph{margin-left:auto;flex:none;height:46px;border-radius:14px;background:var(--ok);color:#000;font-weight:800;padding:0 14px;display:flex;align-items:center;text-decoration:none;font-size:15px} | |
| .tips li{margin:0 0 10px;font-size:16px} | |
| .tips{padding-left:22px;margin:6px 0 0} | |
| details{background:var(--card);border:1px solid var(--line);border-radius:22px;padding:4px 16px;margin-bottom:12px} | |
| summary{list-style:none;cursor:pointer;padding:14px 0;font-weight:800;font-size:18px;display:flex;align-items:center;gap:10px} | |
| summary::-webkit-details-marker{display:none} | |
| summary::after{content:"›";margin-left:auto;transform:rotate(90deg);color:var(--dim);font-size:22px;transition:transform .2s} | |
| details[open] summary::after{transform:rotate(-90deg)} | |
| @media (prefers-reduced-motion:reduce){*{animation:none;transition:none}} | |
| </style> | |
| </head> | |
| <body> | |
| <div class="top"> | |
| <a class="back" href="trips.html" aria-label="Back to Trips">‹</a> | |
| <div class="av" id="hAv"><img src="wheelie.jpg" alt=""></div> | |
| <div><b>Fly with Wheelie</b><small>Find a flight, then get wheelchair help lined up.</small></div> | |
| </div> | |
| <section class="card" aria-label="Search flights"> | |
| <div class="fld"><label class="l" for="from">From</label><input id="from" autocomplete="off" placeholder="City or airport" value="Santa Ana (SNA)"><div class="sug" id="sFrom" role="listbox"></div></div> | |
| <button class="swap" id="swap" aria-label="Swap from and to">⇅</button> | |
| <div class="fld"><label class="l" for="to">To</label><input id="to" autocomplete="off" placeholder="Where are you flying?"><div class="sug" id="sTo" role="listbox"></div></div> | |
| <label class="l">When</label> | |
| <div class="chips" id="when"></div> | |
| <div class="fld" id="dayWrap" style="display:none"><input type="date" id="day" aria-label="Pick a day"></div> | |
| <div class="chips"><button class="chip" id="direct" aria-pressed="false">✈️ Nonstop only</button></div> | |
| <button class="go" id="go">Find flights</button> | |
| </section> | |
| <div id="out" aria-live="polite"></div> | |
| <h2>Wheelchair help at the airport</h2> | |
| <details open> | |
| <summary>♿ How to get help, step by step</summary> | |
| <ol class="tips"> | |
| <li><b>When you book,</b> add "wheelchair assistance" to your reservation, then call the airline's accessibility line below to confirm it.</li> | |
| <li><b>Flying with your own power chair?</b> Tell the airline the make, model, weight and battery type. Some airlines ask for this at least 48 hours before you fly.</li> | |
| <li><b>Keep your own chair to the gate.</b> Ask to "gate check" it, so you ride it right up to the plane door, and ask for it back at the plane door when you land.</li> | |
| <li><b>Need help getting to your seat?</b> Ask for an aisle chair and boarding help. People with disabilities can board first.</li> | |
| <li><b>Protect your chair.</b> Take photos of it before you fly, tape on simple instructions for folding and moving it, and take off loose parts like the joystick or cushion and bring them on board.</li> | |
| <li><b>If something goes wrong,</b> ask for the airline's CRO (Complaints Resolution Official). Every U.S. airline must have one on duty.</li> | |
| </ol> | |
| </details> | |
| <details> | |
| <summary>📞 Airline accessibility lines</summary> | |
| <div class="help" id="help"></div> | |
| <p class="note">Some airlines don't have a separate accessibility line, so the number is their main help line. Just ask for accessibility or special assistance.</p> | |
| </details> | |
| <details> | |
| <summary>🇺🇸 Know your rights</summary> | |
| <ul class="tips"> | |
| <li>Under the Air Carrier Access Act, U.S. airlines can't refuse you because of a disability, and wheelchair help is free.</li> | |
| <li>The U.S. Department of Transportation runs a free disability hotline for air travelers: <a href="tel:18007784838">1-800-778-4838</a>.</li> | |
| </ul> | |
| </details> | |
| <script> | |
| (function(){ | |
| ; | |
| var FN='https://yzzxvjrzniuhxebqqrsy.supabase.co/functions/v1/flights'; | |
| var VOICE='https://yzzxvjrzniuhxebqqrsy.supabase.co/functions/v1/readpage?text='; | |
| var $=function(i){return document.getElementById(i)}; | |
| function esc(s){return String(s==null?'':s).replace(/[&<>"']/g,function(c){return '&#'+c.charCodeAt(0)+';'})} | |
| function ls(k,v){try{if(v===undefined)return JSON.parse(localStorage.getItem(k)||'null');localStorage.setItem(k,JSON.stringify(v))}catch(e){return null}} | |
| var AL={AA:['American Airlines','8004337300','(800) 433-7300'],DL:['Delta','4042093434','(404) 209-3434'],UA:['United','8002282744','(800) 228-2744'],WN:['Southwest','8004359792','(800) 435-9792'],AS:['Alaska Airlines','8005030101','(800) 503-0101'],B6:['JetBlue','8005382583','(800) 538-2583'],NK:['Spirit','8557283555','(855) 728-3555'],F9:['Frontier','8014019004','(801) 401-9004'],HA:['Hawaiian Airlines','8003675320','(800) 367-5320'],G4:['Allegiant','7025058888','(702) 505-8888'],SY:['Sun Country','6519052737','(651) 905-2737'],XP:['Avelo','3466169500','(346) 616-9500']}; | |
| function aname(c){return AL[c]?AL[c][0]:c} | |
| /* voice */ | |
| var aud=new Audio(),last=''; | |
| aud.addEventListener('playing',function(){$('hAv').classList.add('talk');var s=document.querySelector('.say .av');s&&s.classList.add('talk')}); | |
| ['ended','pause','error'].forEach(function(e){aud.addEventListener(e,function(){document.querySelectorAll('.av.talk').forEach(function(x){x.classList.remove('talk')})})}); | |
| document.addEventListener('click',function u(){try{aud.src='data:audio/wav;base64,UklGRiYAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YQIAAAAAAA==';aud.play().catch(function(){})}catch(e){}document.removeEventListener('click',u)},true); | |
| function say(t){last=t;fetch(VOICE+encodeURIComponent(t)).then(function(r){return r.json()}).then(function(j){if(last!==t||!j||!j.url)return;aud.src=j.url;aud.play().catch(function(){})}).catch(function(){})} | |
| /* help list */ | |
| $('help').innerHTML=Object.keys(AL).map(function(k){var a=AL[k];return '<div class="al2"><div><b>'+a[0]+'</b><small>'+a[2]+'</small></div><a class="ph" href="tel:1'+a[1]+'" aria-label="Call '+a[0]+' accessibility">📞 Call</a></div>'}).join(''); | |
| /* places */ | |
| var sel={from:ls('wFlyFrom')||{code:'SNA',label:'Santa Ana (SNA)'},to:null},tm=0; | |
| $('from').value=sel.from.label; | |
| function lbl(p){return (p.type==='airport'?p.city:p.name)+' ('+p.code+')'} | |
| function sug(which){ | |
| var inp=$(which),box=$(which==='from'?'sFrom':'sTo'); | |
| inp.addEventListener('input',function(){sel[which]=null;clearTimeout(tm);var q=inp.value.trim();if(q.length<2){box.classList.remove('on');return} | |
| tm=setTimeout(function(){fetch(FN+'?q='+encodeURIComponent(q)).then(function(r){return r.json()}).then(function(d){var L=d.places||[];if(!L.length){box.classList.remove('on');return} | |
| box.innerHTML=L.map(function(p,i){return '<button data-i="'+i+'"><span class="code">'+esc(p.code)+'</span><span><b>'+esc(p.type==='airport'?p.name:p.name+' (all airports)')+'</b><small>'+esc([p.city!==p.name?p.city:'',p.state,p.country].filter(Boolean).join(', '))+'</small></span></button>'}).join(''); | |
| box.classList.add('on');[].forEach.call(box.children,function(b){b.onclick=function(){var p=L[+b.dataset.i];sel[which]={code:p.code,label:lbl(p)};inp.value=sel[which].label;box.classList.remove('on');if(which==='from')ls('wFlyFrom',sel.from)}})}).catch(function(){})},250)}); | |
| inp.addEventListener('focus',function(){inp.select()}); | |
| } | |
| sug('from');sug('to'); | |
| document.addEventListener('click',function(e){if(!e.target.closest('.fld'))document.querySelectorAll('.sug').forEach(function(s){s.classList.remove('on')})}); | |
| $('swap').onclick=function(){var a=sel.from,b=sel.to;sel.from=b;sel.to=a;$('from').value=b?b.label:'';$('to').value=a?a.label:''}; | |
| /* when */ | |
| var MO=['January','February','March','April','May','June','July','August','September','October','November','December']; | |
| var now=new Date(),when=null,months=[]; | |
| for(var i=0;i<4;i++){var d=new Date(now.getFullYear(),now.getMonth()+i,1);months.push([d.getFullYear()+'-'+('0'+(d.getMonth()+1)).slice(-2),MO[d.getMonth()]])} | |
| $('when').innerHTML=months.map(function(m,i){return '<button class="chip'+(i===0?' on':'')+'" data-v="'+m[0]+'">'+(i===0?'This month':m[1])+'</button>'}).join('')+'<button class="chip" data-v="day">Pick a day</button>'; | |
| when=months[0][0]; | |
| [].forEach.call($('when').children,function(c){c.onclick=function(){[].forEach.call($('when').children,function(x){x.classList.remove('on')});c.classList.add('on');if(c.dataset.v==='day'){$('dayWrap').style.display='';if(!$('day').value){var t=new Date(Date.now()+7*864e5);$('day').value=t.toISOString().slice(0,10)}when='day'}else{$('dayWrap').style.display='none';when=c.dataset.v}}}); | |
| $('day').min=new Date().toISOString().slice(0,10); | |
| var direct=false;$('direct').onclick=function(){direct=!direct;this.classList.toggle('on',direct);this.setAttribute('aria-pressed',direct)}; | |
| /* search */ | |
| function dLong(iso){var d=new Date(iso.slice(0,10)+'T12:00:00');return d.toLocaleDateString('en-US',{weekday:'short',month:'short',day:'numeric'})} | |
| function localTime(iso){var m=iso.match(/T(\d{2}):(\d{2})/);if(!m)return '';var h=+m[1],mi=m[2],ap=h>=12?'PM':'AM';h=h%12||12;return h+':'+mi+' '+ap} | |
| function dur(m){var h=Math.floor(m/60),r=m%60;return (h?h+' hr ':'')+(r?r+' min':'')} | |
| $('go').onclick=function(){ | |
| if(!sel.from){$('from').focus();say('Where are you flying from? Type your city or airport.');return} | |
| if(!sel.to){$('to').focus();say('Where are we flying to? Type the city or airport.');return} | |
| var date=when==='day'?$('day').value:when;if(!date){say('Pick a day first.');return} | |
| var out=$('out');out.innerHTML='<div class="loading"><div class="spin"></div>Finding flights…</div>'; | |
| out.scrollIntoView({behavior:'smooth',block:'start'}); | |
| fetch(FN+'?from='+sel.from.code+'&to='+sel.to.code+'&date='+date+(direct?'&direct=1':'')).then(function(r){return r.json()}).then(function(d){ | |
| var L=(d.flights||[]).slice(0,12); | |
| if(d.error||!L.length){out.innerHTML='<div class="card"><b>No flights found for that search.</b><p class="note" style="margin:6px 0 0">Try another month, "All airports" for your city, or turn off Nonstop only.</p></div>';say('I couldn’t find flights for that. Try another month or a nearby airport.');return} | |
| var b=L[0],cheap='The best price I found is $'+b.price+' on '+aname(b.airline)+', '+dLong(b.depart)+', '+(b.stops?b.stops+(b.stops>1?' stops':' stop'):'nonstop')+'.'; | |
| out.innerHTML='<h2>Flights from '+esc(sel.from.code)+' to '+esc(sel.to.code)+'</h2><div class="say"><div class="av"><img src="wheelie.jpg" alt=""></div><p>'+esc(cheap)+' When you book, add wheelchair help. I listed every airline’s number below.</p></div>'+ | |
| L.map(function(f,i){return '<a class="fl'+(i===0?' best':'')+'" href="'+esc(f.book)+'" target="_blank" rel="noopener" aria-label="'+esc(aname(f.airline)+', $'+f.price+', '+dLong(f.depart))+'">'+(i===0?'<span class="tag">BEST PRICE</span>':'')+ | |
| '<div class="h"><span class="p">$'+f.price+'</span><span class="al">'+esc(aname(f.airline))+'<br><small style="color:#a1a1aa;font-weight:500">Flight '+esc(f.number)+'</small></span></div>'+ | |
| '<div class="r">'+esc(f.from)+' → '+esc(f.to)+'</div><div class="m">'+dLong(f.depart)+' · leaves '+localTime(f.depart)+' · '+(f.stops?f.stops+(f.stops>1?' stops':' stop'):'Nonstop')+(f.minutes?' · '+dur(f.minutes):'')+'</div>'+ | |
| (AL[f.airline]?'<div class="m">♿ Wheelchair help: '+AL[f.airline][2]+'</div>':'')+'<span class="bk">Book this flight ›</span></a>'}).join('')+ | |
| '<p class="note">Prices are the latest fares travelers found, in U.S. dollars. You’ll see the final price before you pay.</p>'; | |
| say(cheap); | |
| }).catch(function(){out.innerHTML='<div class="card"><b>I couldn’t reach flight search.</b><p class="note" style="margin:6px 0 0">Check your connection and try again.</p></div>'}); | |
| }; | |
| say('Where are we flying? Pick your airports and when, and I’ll find the best price.'); | |
| })(); | |
| </script> | |
| <script src="wicons.js?v=1"></script> | |
| </body> | |
| </html> | |