PageSourceSearch

https://lesvacances.co.kr/assets/FlightSearchResultsPage-BF3ru0dt.js

js lesvacances.co.kr collected 2026-10-03 01:24:45 UTC 10,742 bytes, 1 lines download raw bytes

1import{n as N,O as j,Q as b,o as v,p as g,L as w,A as S,r as m,j as e,B as x}from"./index-BIjT-aNh.js";import{A as F}from"./arrow-left-DvZnGT50.js";import{P as p}from"./plane-jT1lZh40.js";function h(s){const t=String(s||"").match(/\(([^)]+)\)/);return t?t[1].toUpperCase():""}function f(s){return String(s||"").replace(/\([^)]*\)/g,"").trim()}const C={economy:"y",business:"c",first:"f"};function T(s,t){const a=new Date(s);if(Number.isNaN(a.getTime()))return s;a.setDate(a.getDate()+t);const c=l=>String(l).padStart(2,"0");return`${a.getFullYear()}-${c(a.getMonth()+1)}-${c(a.getDate())}`}function _(s,t){const a=new URL(s),c=(o,n)=>a.searchParams.set(o,n);t.departureDate&&c("ddate",t.departureDate),t.tripType==="roundtrip"?(c("triptype","rt"),c("rdate",t.returnDate||T(t.departureDate,3))):(c("triptype","ow"),a.searchParams.delete("rdate")),c("class",C[t.seatClass]||"y"),c("nonstoponly",t.directOnly?"on":"off");const l=Math.max(1,(t.passengers?.adults||0)+(t.passengers?.children||0)+(t.passengers?.infants||0));return c("quantity",String(l)),a.toString()}async function k(s){const t=h(s.arrival),a=f(s.arrival);if(!t&&!a)return null;const l=(await N(j(v(g,"cityDetails"),b("status","==","published")))).docs.map(d=>({id:d.id,...d.data()})),o=d=>{try{return(new URL(String(d)).searchParams.get("acity")||"").toUpperCase()}catch{return""}},n=(t?l.find(d=>d.tripcomFlights?.url&&o(d.tripcomFlights.url)===t):void 0)||(t?l.find(d=>String(d.cityCode||"").toUpperCase()===t&&d.tripcomFlights?.url):void 0)||(a?l.find(d=>String(d.nameKr||"").trim()===a&&d.tripcomFlights?.url):void 0);return n?{cityCode:String(n.cityCode||""),cityNameKr:String(n.nameKr||a),searchUrl:_(String(n.tripcomFlights.url),s),curatedFilters:Array.isArray(n.tripcomFlights.filters)?n.tripcomFlights.filters:[],flightDuration:n.flightTime?.duration||void 0,gatewayNote:n.tripcomFlights.note||void 0}:null}const $=["korean_air","budget_airline","other_airline"];async function A(s){if(!s.departureDate)return[];const t=h(s.departure),a=f(s.departure);if(t&&t!=="ICN")return[];if(!t&&a&&!/서울|인천/.test(a))return[];const c=h(s.arrival),l=f(s.arrival);let o=null;if(c){const r=await w(S(g,"vacance-flights",`ICN-${c}_${s.departureDate}`));r.exists()&&(o=r.data())}if(!o&&l){const i=(await N(j(v(g,"vacance-flights"),b("search_date","==",s.departureDate)))).docs.find(u=>String(u.data().arrival_city_kr||"").trim()===l);i&&(o=i.data())}if(!o)return[];const n=typeof o?.extracted_at?.toDate=="function"?o.extracted_at.toDate():void 0,d=[];for(const r of $){const i=o[r];!i||typeof i.price!="number"||d.push({category:r,airline:String(i.airline||""),airlineLogo:String(i.airline_logo||""),flightNumber:String(i.flight_number||""),departureTime:String(i.departure_time||""),arrivalTime:String(i.arrival_time||""),durationMins:Number(i.duration)||0,price:i.price,stops:Number(i.stops)||0,airplane:i.airplane||void 0,travelClass:i.travel_class||void 0,extractedAt:n})}return d.sort((r,i)=>r.price-i.price)}function L(s){if(!Number.isFinite(s)||s<=0)return"";const t=Math.floor(s/60),a=s%60;return t>0?`${t}시간${a>0?` ${a}분`:""}`:`${a}분`}function y(s){const t=String(s||"").match(/(\d{2}:\d{2})/);return t?t[1]:""}const R={economy:"일반석",business:"비즈니스석",first:"일등석"};function K({onPageChange:s,searchData:t}){const[a,c]=m.useState(!0),[l,o]=m.useState(null),[n,d]=m.useState([]);return m.useEffect(()=>{if(!t){c(!1),o(null);return}let r=!0;return c(!0),Promise.all([k(t),A(t)]).then(([i,u])=>{r&&(o(i),d(u),i||console.warn("✈️ [FlightSearchResults] 항공권 링크를 찾지 못했습니다:",t.arrival))}).catch(i=>{console.error("✈️ [FlightSearchResults] 항공권 정보 로드 실패:",i),r&&(o(null),d([]))}).finally(()=>{r&&c(!1)}),()=>{r=!1}},[t]),e.jsxs("div",{className:"min-h-screen page-bg",children:[e.jsxs("div",{className:"bg-white sticky top-0 z-50 border-b border-gray-200",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 max-w-7xl mx-auto relative",children:[e.jsx(x,{variant:"ghost",size:"sm",onClick:()=>s("flights-full",t),className:"p-1",children:e.jsx(F,{className:"w-5 h-5"})}),e.jsx("h1",{className:"text-xl absolute left-1/2 -translate-x-1/2",children:"검색 ê²°ê
1³¼"}),e.jsx("div",{className:"w-7","aria-hidden":!0})]}),t&&e.jsx("div",{className:"border-t border-gray-200 bg-blue-50 p-4",children:e.jsx("div",{className:"max-w-7xl mx-auto",children:e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-2",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(p,{className:"w-5 h-5 text-blue-600"}),e.jsxs("span",{className:"text-sm",children:[e.jsx("strong",{children:t.departure})," → ",e.jsx("strong",{children:t.arrival})]}),e.jsx("span",{className:"text-sm text-gray-600",children:"|"}),e.jsxs("span",{className:"text-sm text-gray-600",children:[t.departureDate,t.tripType==="roundtrip"&&t.returnDate&&` ~ ${t.returnDate}`]}),e.jsx("span",{className:"text-sm text-gray-600",children:"|"}),e.jsxs("span",{className:"text-sm text-gray-600",children:["승객 ",t.passengers.adults+t.passengers.children+t.passengers.infants,"명"]})]}),e.jsx(x,{variant:"outline",size:"sm",onClick:()=>s("flights-full",t),className:"text-xs",children:"ì¡°ê±´ 수정"})]})})})]}),e.jsx("div",{className:"max-w-3xl mx-auto px-4 py-8",children:a?e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"h-40 bg-gray-100 rounded-xl animate-pulse"}),e.jsx("div",{className:"h-24 bg-gray-100 rounded-xl animate-pulse"})]}):!l&&n.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[e.jsx(p,{className:"w-14 h-14 text-gray-300 mb-4"}),e.jsx("h3",{className:"text-lg text-gray-700 mb-2",children:"아직 준비되지 않은 노선입니다"}),e.jsxs("p",{className:"text-sm text-gray-500 mb-6",children:[t?.arrival||"도착지"," 항공권 정보를 준비 중입니다. 다른 도시로 검색해 보세요."]}),e.jsx(x,{variant:"outline",onClick:()=>s("flights-full",t),children:"검색 ì¡°ê±´ 변경"})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-xl border border-gray-200 bg-white p-5",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-4",children:[e.jsx(p,{className:"w-5 h-5 text-blue-600"}),e.jsxs("h2",{className:"text-lg font-medium text-gray-900",children:[t?.departure," → ",l?.cityNameKr||t?.arrival]})]}),e.jsxs("dl",{className:"space-y-2.5 text-sm",children:[e.jsxs("div",{className:"flex justify-between gap-4",children:[e.jsx("dt",{className:"text-gray-500 shrink-0",children:"여정"}),e.jsxs("dd",{className:"text-gray-900 text-right",children:[t?.tripType==="roundtrip"?"왕복":"편도",t?.departureDate?` · ${t.departureDate}`:"",t?.tripType==="roundtrip"&&t?.returnDate?` ~ ${t.returnDate}`:""]})]}),e.jsxs("div",{className:"flex justify-between gap-4",children:[e.jsx("dt",{className:"text-gray-500 shrink-0",children:"인원 · 좌석"}),e.jsxs("dd",{className:"text-gray-900 text-right",children:[(t?.passengers.adults||0)+(t?.passengers.children||0)+(t?.passengers.infants||0),"명 · ",R[t?.seatClass||"economy"],t?.directOnly?" · 직항만":""]})]}),l?.flightDuration&&e.jsxs("div",{className:"flex justify-between gap-4",children:[e.jsx("dt",{className:"text-gray-500 shrink-0",children:"직항 소요시간"}),e.jsx("dd",{className:"text-gray-900 text-right",children:l.flightDuration})]})]}),l?.gatewayNote&&e.jsx("p",{className:"mt-4 text-xs text-gray-600 bg-gray-50 rounded-lg p-3 leading-relaxed",children:l.gatewayNote})]}),n.length>0&&e.jsxs("div",{className:"rounded-xl border border-gray-200 bg-white p-5",children:[e.jsxs("div",{className:"flex items-baseline justify-between mb-1",children:[e.jsx("h3",{className:"text-base font-medium text-gray-900",children:"가는 편 항공권"}),e.jsxs("span",{className:"text-xs text-gray-400",children:[n.length,"ê±´"]})]}),e.jsxs("p",{className:"text-xs text-gray-500 mb-4",children:[t?.departureDate," 인천 출발 기준",n[0]?.extractedAt?` · ${n[0].extractedAt.toLocaleDateString("ko-KR")} 수집`:""]}),e.jsx("div",{className:"space-y-3",children:n.map(r=>e.jsxs("div",{className:"rounded-lg border border-gray-200 p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[r.airlineLogo&&e.jsx("img",{src:r.airlineLogo,alt:r.airline,className:"w-5 h-5 object-contain"}),e.jsx("span",{className:"text-sm font-medium text-gray-900",children:r.airline}),e.jsx("span",{className:"text-xs text-gray-400",children:r.flightNumber})]}),e.jsxs("div",{className:"flex items-end justify-between gap-3",children:[e.jsxs("div",{className:"text-sm text-gray-900",children:[e.jsx("span",{className:"font-medium",children:y(r.departureTime)}),e.jsx("span",{className:"text-gray-400 mx-1.5",children:"→"}),e.jsx("span",{className:"font-medium",children:y(r.arrivalTime)}),e.jsxs("span",{className:"block text-xs text-gray-500 mt-0.5",children:[L(r.durationMins),r.stops===0?" · 직항":` · 경유 ${r.stops}회`,r.airplane?` · ${r.airplane}`:""]})]}),e.jsxs("div",{className:"text-right shrink-0",children:[e.jsxs("span",{className:"text-base font-semibold text-blue-600",children:[r.price.toLocaleStr
1ing("ko-KR"),"원"]}),e.jsx("span",{className:"block text-[11px] text-gray-400",children:"1인 편도"})]})]})]},`${r.category}-${r.flightNumber}`))}),e.jsxs("p",{className:"mt-3 text-[11px] text-gray-500 leading-relaxed",children:["수집 시점의 편도 요금이라 실제 결제 금액과 다를 수 있습니다.",t?.tripType==="roundtrip"?" 돌아오는 편은 아래 검색에서 확인해 주세요.":""]})]}),l&&e.jsxs("div",{className:"rounded-xl border border-blue-200 bg-blue-50 p-5",children:[e.jsx("h3",{className:"text-base font-medium text-gray-900 mb-1",children:"실시간 최저가 확인"}),e.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"입력하신 조건 그대로 Trip.com 항공권 검색으로 이동합니다."}),l.curatedFilters.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1.5 mb-4",children:l.curatedFilters.map(r=>e.jsx("span",{className:"text-[11px] px-2 py-0.5 rounded-full bg-white text-blue-700 border border-blue-200",children:r},r))}),e.jsx(x,{className:"w-full",onClick:()=>window.open(l.searchUrl,"_blank","noopener,noreferrer"),children:"Trip.com에서 항공권 검색"}),e.jsx("p",{className:"mt-3 text-[11px] text-gray-500 leading-relaxed",children:"요금·좌석은 Trip.com에서 실시간으로 확인됩니다. 소아·유아가 포함된 경우 도착 페이지에서 인원 구성을 확인해 주세요."})]}),e.jsx(x,{variant:"outline",className:"w-full",onClick:()=>s("flights-full",t),children:"검색 조건 변경"})]})})]})}export{K as FlightSearchResultsPage};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.