PageSourceSearch

https://southwarktaxi.co.uk/assets/SENDTransportPage-CIUMBHad.js

js southwarktaxi.co.uk collected 2026-10-06 19:00:41 UTC 18,840 bytes, 1 lines download raw bytes

1import{r,j as a}from"./vendor-react-CV6oP_vj.js";import{c as Ae,bw as C}from"./index-BjRWPOnn.js";import"./domainRegistry-Bf_6a07y.js";import"./schoolRunCover-e2Jduwf2.js";import{v as Ie}from"./locationData-DD4iXC23.js";import"./index-CydbsIlz.js";import"./types-CGO4AJdh.js";import"./tiktokVideoPackageContent-CvuxLGxb.js";const _e=/^(\d{4})-(\d{2})-(\d{2})$/,qe=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function Re(e,s){return new Date(Date.UTC(e,s,0)).getUTCDate()}function O(e){if(typeof e!="string")return!1;const s=_e.exec(e);if(!s)return!1;const n=Number(s[1]),o=Number(s[2]),i=Number(s[3]);return o>=1&&o<=12&&i>=1&&i<=Re(n,o)}function ae(e,s){if(!O(e))throw new Error("Start date must be YYYY-MM-DD");if(!O(s))throw new Error("End date must be YYYY-MM-DD");if(s<e)throw new Error("End date must be on or after start date")}function se(e){return new Date(`${e}T00:00:00.000Z`)}function Fe(e){const s=se(e).getUTCDay();return s===0?7:s}function Oe(e){const s=se(e);return s.setUTCDate(s.getUTCDate()+1),s.toISOString().slice(0,10)}function Ye(e,s,n){if(!e.trim())throw new Error("parentId is required");if(!O(n))throw new Error("serviceDate must be YYYY-MM-DD");return`${e}:${s}:${n}`}function Ue(e,s,n,o={}){ae(e,s);const i=new Set(n),c=new Set(o.bankHolidays??[]),d=[];for(let m=e;m<=s;m=Oe(m))i.has(Fe(m))&&(o.excludeBankHolidays&&c.has(m)||d.push(m));return d}function X(e,s){if(!e.from.trim()||!e.to.trim())throw new Error(`${s} route is required`);if(!qe.test(e.time))throw new Error(`${s} time must be HH:mm`)}function He(e){if(ae(e.startDate,e.endDate),!e.parentId.trim())throw new Error("parentId is required");if(!Array.isArray(e.weekdays)||!e.weekdays.length)throw new Error("At least one weekday is required");if(new Set(e.weekdays).size!==e.weekdays.length||e.weekdays.some(i=>!Number.isInteger(i)||i<1||i>7))throw new Error("Invalid weekday");X(e.am,"AM"),e.pm&&X(e.pm,"PM");const s=e.journeyType==="one_off"?[e.startDate]:Ue(e.startDate,e.endDate,e.weekdays,{bankHolidays:e.bankHolidays,excludeBankHolidays:e.excludeBankHolidays}),n=s.flatMap(i=>["AM","PM"].filter(c=>c==="AM"||e.pm).map(c=>{const d=e[c.toLowerCase()];if(!d)throw new Error(`${c} leg is required`);return{...d,legType:c,parentId:e.parentId,serviceDate:i,idempotencyKey:Ye(e.parentId,c,i)}})),o=e.wheelchair?.required&&e.wheelchair.preference==="remain_seated";return{serviceDates:s,legs:n,paymentStatus:o?"hard_stop":"ready",...o?{paymentBlockReason:"wheelchair_remain_seated_requires_confirmation"}:{}}}const $e={pa:new Set(["yes","no","unsure"]),sameDriver:new Set(["required","preferred","no_preference"]),additionalBoardingTime:new Set(["yes","no","unsure"]),wheelchair:new Set(["no","transfer_possible"])},F=(e,s,n=1e3)=>{if(typeof e!="string"||e.length>n)throw new Error(`${s}
1 is invalid`);return e.trim()};function Be(e){if(!e||typeof e!="object")throw new Error("SEND operational requirements are required");const s=e,n=c=>{const d=s[c];if(typeof d!="string"||!$e[c].has(d))throw new Error(`${c} is invalid`);return d},o=s.handover;if(typeof o!="boolean")throw new Error("handover is invalid");const i=F(s.handoverInstructions,"handoverInstructions");if(o&&!i)throw new Error("handoverInstructions are required when handover is true");return{pa:n("pa"),sameDriver:n("sameDriver"),handover:o,handoverInstructions:o?i:"",additionalBoardingTime:n("additionalBoardingTime"),communication:F(s.communication,"communication"),organisationName:F(s.organisationName,"organisationName"),wheelchair:n("wheelchair")}}const Le="We are currently unable to accept online bookings where the passenger needs to remain seated in a wheelchair while travelling.",We="WHEELCHAIR-ACCESSIBLE VEHICLE REQUIRED",Ve="";function ze(e){const s=e.replace(/^\/|\/$/g,"").split("/");return s[0]!=="special-educational-needs-and-disabilities-trans
1port"?null:s.length===3?{region:s[1],location:s[2]}:s.length===4?{region:s[1],location:s[2],area:s[3]}:null}function ee(e){return e!=="remain_seated"}function Ge(e){const s=[],n=Number(e.passengers);return(!Number.isInteger(n)||n<1||n>16)&&s.push("Passenger count must be between 1 and 16."),e.bookingFor||s.push("Choose who you are booking for."),(!e.fullName?.trim()||!e.mobile?.trim()||!e.email?.trim())&&s.push("Enter your full name, mobile number and email address."),e.vehicleType||s.push("Choose a vehicle class."),e.bookingFor==="organisation"&&!e.organisationName?.trim()&&s.push("Enter the organisation or care provider name."),e.bookingFor==="organisation"&&!e.organisationContact?.trim()&&s.push("Enter an organisation contact."),e.handover||s.push("Choose whether a handover is needed."),e.handover==="yes"&&!e.instructions?.trim()&&s.push("Enter handover instructions."),e.boardingTime||s.push("Choose whether additional boarding time is needed."),(!e.amFrom||!e.amTo||!e.amTime)&&s.push("Complete all AM pickup, destination and time fields."),(!e.amPostcode||!e.amToPostcode)&&s.push("Select AM pickup and destination addresses with postcodes."),(e.journeyType==="one-off"||e.journeyType==="one_off")&&!e.startDate&&s.push("Choose a date for the one-off journey."),e.journeyType==="recurring"&&(!e.startDate||!e.endDate||!e.weekdays?.length)&&s.push("Choose a recurring date range and at least one day."),e.pmReturn&&(!e.pmFrom||!e.pmTo||!e.pmTime)&&s.push("Complete all PM return journey fields."),e.pmReturn&&(!e.pmPostcode||!e.pmToPostcode)&&s.push("Select PM pickup and destination addresses with postcodes."),s}function Je(e){if(!e.place)throw new Error("Location is required");const s=o=>(o||"").trim().slice(0,240),n=e.journeyType==="one-off"||e.journeyType==="one_off";return{region:s(e.place.region),city:s(e.place.location),...e.place.area?{area:s(e.place.area)}:{},journeyType:n?"one_off":e.journeyType,...n?{date:s(e.startDate)}:{startDate:s(e.startDate),endDate:s(e.endDate),weekdays:e.weekdays},am:{from:s(e.amFrom),to:s(e.amTo),time:s(e.amTime),pickupPostcode:s(e.amPostcode),dropoffPostcode:s(e.amToPostcode)},...e.pmReturn?{pm:{from:s(e.pmFrom),to:s(e.pmTo),time:s(e.pmTime),pickupPostcode:s(e.pmPostcode),dropoffPostcode:s(e.pmToPostcode)}}:{},passengers:Number(e.passengers),vehicleType:e.vehicleType,bookingFor:e.bookingFor,fullName:s(e.fullName),mobile:s(e.mobile),email:s(e.email),organisationName:s(e.organisationName),organisationContact:s(e.organisationContact),...Be({pa:e.pa,sameDriver:e.driver==="no-preference"?"no_preference":e.driver,handover:e.handover==="yes",handoverInstructions:e.instructions,additionalBoardingTime:e.boardingTime,communication:s(e.communication),organisationName:s(e.organisationName),wheelchair:e.wheelchair})}}function Ke(e,s){if(!e||!s||typeof s!="object"||typeof s.checkoutUrl!="string")return null;try{const n=s.checkoutUrl;if(!/^https?:\/\//i.test(n))return null;const o=new URL(n);return!["http:","https:"].includes(o.protocol)||o.username||o.password?null:o.href}catch{return null}}function Qe(e){if(!e)return"";let s=e;try{s=decodeURIComponent(e)}catch{return""}return/^[a-z0-9]+(?:-[a-z0-9]+)*$/i.test(s)?s.split("-").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" "):""}const l="w-full rounded-lg border border-gray-700 bg-gray-900 px-3 py-2.5 text-white placeholder:text-gray-500",Ze=[{value:1,label:"Mon"},{value:2,label:"Tue"},{value:3,label:"Wed"},{value:4,label:"Thu"},{value:5,label:"Fri"},{value:6,label:"Sat"},{value:7,label:"Sun"}];function ia(){const e=Ae(),s=ze(window.location.pathname),[n,o]=r.useState("child"),[i,c]=r.useState(""),[d,m]=r.useState(""),[g,te]=r.useState("recurring"),[b,re]=r.useState(!0),[x,Y]=r.useState(""),[y,ne]=r.useState(""),[h,oe]=r.useState([1,2,3,4,5]),[f,ie]=r.useState(""),[U,le]=r.useState(""),[j,ce]=r.useState(""),[H,de]=r.useState(""),[v,ue]=r.useState(""),[w,me]=r.useState(""),[$,he]=r.useState(""),[N,pe]=r.useState(""),[B,ge]=r.useState(""),[S,xe]=r.useState(""),[D,be]=r.useState("1"),[L,ye]=r.useState("unsure"),[W,fe]=r.useState("no-preference"),[k,V]=r.useState(""),[P,je]=r.useState(""),[M,ve]=r.useState(""),[z,we]=r.useState(""),[p,Ne]=r.useState("no"),[A,Se]=r.useState(""),[I,ke]=r.useState(""),[_,Te]=r.useState(""),[q,Ee]=r.useState("saloon"),[R,G]=r.useState("idle"),[J,K]=r.useState(""),T=r.useMemo(()=>
1{if(g!=="recurring"||!b||!x||!y||!h.length||!f||!j||!v||!w||!N||!S)return null;try{return He({parentId:"send-draft-preview",startDate:x,endDate:y,weekdays:h,am:{legType:"AM",from:f,to:j,time:v},pm:{legType:"PM",from:w,to:N,time:S},wheelchair:{required:p!=="no",preference:p==="remain_seated"?"remain_seated":"transfer"}})}catch{return null}},[g,b,x,y,h,f,j,v,w,N,S,p]);async function Ce(){if(!ee(p))return;const t=Ge({passengers:D,fullName:A,mobile:I,email:_,vehicleType:q,bookingFor:n,organisationName:i,organisationContact:d,handover:k,instructions:P,boardingTime:M,journeyType:g,startDate:x,endDate:y,weekdays:h,amFrom:f,amTo:j,amTime:v,amPostcode:U,amToPostcode:H,pmReturn:b,pmFrom:w,pmTo:N,pmTime:S,pmPostcode:$,pmToPostcode:B});if(t.length){De(t);return}G("submitting"),K("");try{const u=Je({place:s,bookingFor:n,fullName:A,mobile:I,email:_,vehicleType:q,organisationName:i,organisationContact:d,journeyType:g,startDate:x,endDate:y,weekdays:h,amFrom:f,amTo:j,amTime:v,pmFrom:w,pmTo:N,pmTime:S,pmReturn:b,amPostcode:U,amToPostcode:H,pmPostcode:$,pmToPostcode:B,passengers:D,pa:L,driver:W,handover:k,instructions:P,boardingTime:M,communication:z,wheelchair:p}),E=await fetch("/api/send/checkout",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}),Me=await E.json().catch(()=>null),Z=Ke(E.ok,Me);if(!Z)throw new Error("We could not prepare your secure checkout. Please try again.");window.location.assign(Z)}catch(u){G("error"),K(u instanceof Error?u.message:"We could not prepare your secure checkout. Please try again.")}}const[Q,De]=r.useState([]),Pe=Qe(s?.area||s?.location);return a.jsx("main",{className:"min-h-screen bg-black text-white",children:a.jsxs("div",{className:"mx-auto max-w-3xl px-4 py-8 sm:py-12",children:[a.jsxs("h1",{className:"text-3xl font-bold sm:text-4xl",children:["Special Educational Needs & Disabilities (SEND) Transport in ",Pe||"the local area"]}),a.jsx("p",{className:"mt-3 text-gray-400",children:"Plan transport details for a passenger with special educational needs and disabilities."}),a.jsxs("form",{className:"mt-8 space-y-7",onSubmit:t=>{t.preventDefault(),Ce()},children:[a.jsxs("section",{className:"rounded-xl border border-gray-800 bg-gray-950 p-5 space-y-4",children:[a.jsx("h2",{className:"text-xl font-semibold",children:"Journey details"}),a.jsxs("div",{className:"grid gap-4 sm:grid-cols-3",children:[a.jsxs("label",{children:["Full name",a.jsx("input",{className:l,value:A,onChange:t=>Se(t.target.value),required:!0})]}),a.jsxs("label",{children:["Mobile number",a.jsx("input",{className:l,type:"tel",value:I,onChange:t=>ke(t.target.value),required:!0})]}),a.jsxs("label",{children:["Email address",a.jsx("input",{className:l,type:"email",value:_,onChange:t=>Te(t.target.value),required:!0})]})]}),a.jsxs("label",{children:["Vehicle class",a.jsx("select",{className:l,value:q,onChange:t=>Ee(t.target.value),required:!0,children:Ie.map(t=>a.jsx("option",{value:t.type,children:t.name},t.type))})]}),a.jsxs("fieldset",{children:[a.jsx("legend",{className:"mb-2 font-medium",children:"Who are you booking for?"}),a.jsx("div",{className:"flex flex-wrap gap-4",children:[["self","Myself"],["child","Child / family"],["student","Student"],["school","School / college"],["organisation","Organisation / care provider"],["other","Other"]].map(([t,u])=>a.jsxs("label",{className:"flex gap-2",children:[a.jsx("input",{type:"radio",name:"bookingFor",value:t,checked:n===t,onChange:()=>o(t)}),u]},t))})]}),n==="organisation"&&a.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[a.jsxs("label",{children:["Organisation or care provider name",a.jsx("input",{className:l,value:i,onChange:t=>c(t.target.value),required:!0})]}),a.jsxs("label",{children:["Contact name or details",a.jsx("input",{className:l,value:d,onChange:t=>m(t.target.value),required:!0})]})]}),a.jsxs("fieldset",{children:[a.jsx("legend",{className:"mb-2 font-medium",children:"Is this a one-off or recurring journey?"}),a.jsx("div",{className:"flex gap-5",children:[["one-off","One-off"],["recurring","Recurring"]].map(([t,u])=>a.jsxs("label",{className:"flex gap-2",children:[a.jsx("input",{type:"radio",name:"journeyType",value:t,checked:g===t,onChange:()=>te(t)}),u]},t))})]}),g==="one-off"&&a.jsxs("label",{children:["Date",a.jsx("input",{className:l,type:"date",value:x,onChange:t=>Y(t.target.value),required:!0})]}),g==="recurring"&&a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[a.jsxs("label",{children:["Start date",a.jsx("input",{className:l,type:"date",value:x,onChange:t=>Y(t.target.value),required:!0})]}),a.jsxs("label",{children:["End date",a.jsx("input",{className:l,type:"date",value:y,onChange:t=>ne(t.target.value),required:!0})]})]}),a.jsxs("fieldset",{children:[a.jsx("legend",{className:"mb-2 font-medium",children:"Days"}),a.jsx("div",{className:"flex flex-wrap gap-3",children:Ze.map(t=>a.jsxs("label",{className:"flex gap-1.5",children:[a.jsx("input",{type:"checkbox",checked:h.includes(t.value),onChange:u=>oe(u.target.checked?[...h,t.value].sort():h.filter(E=>E!==t.value))}),t.label]},t.value))})]})]})]}),a.jsxs("section",{className:"rounded-xl border border-gray-800 bg-gray-950 p-5 space-y-4",children:[a.jsx("h2",{className:"text-xl font-semibold",children:"Pickup and destination"}),a.jsxs("div",{className:"grid gap-3 border-b border-gray-800 pb-4 sm:grid-cols-3",children:[a.jsx("h3",{className:"font-semibold",children:"AM journey"}),a.jsx(C,{value:f,onChange:ie,onSelect:t=>le(t.postcode||""),placeholder:"AM pickup address"}),a.jsx(C,{value:j,onChange:ce,onSelect:t=>de(t.postcode||""),placeholder:"AM destination address"}),a.jsxs("label",{children:["Time",a.jsx("input",{className:l,type:"time",value:v,onCh
1ange:t=>ue(t.target.value)})]})]}),b&&a.jsxs("div",{className:"grid gap-3 border-b border-gray-800 pb-4 sm:grid-cols-3",children:[a.jsx("h3",{className:"font-semibold",children:"PM journey"}),a.jsx(C,{value:w,onChange:me,onSelect:t=>he(t.postcode||""),placeholder:"PM pickup address"}),a.jsx(C,{value:N,onChange:pe,onSelect:t=>ge(t.postcode||""),placeholder:"PM destination address"}),a.jsxs("label",{children:["Time",a.jsx("input",{className:l,type:"time",value:S,onChange:t=>xe(t.target.value)})]})]}),a.jsxs("label",{className:"flex gap-2",children:[a.jsx("input",{type:"checkbox",checked:b,onChange:t=>re(t.target.checked)})," Include a PM return journey"]}),T&&a.jsxs("p",{className:"rounded-lg bg-gray-900 p-3 text-sm text-gray-300","data-testid":"recurrence-preview",children:["Preview: ",T.serviceDates.length," dates, ",T.legs.length," legs (",T.serviceDates[0]," to ",T.serviceDates.at(-1),")."]})]}),a.jsxs("section",{className:"rounded-xl border border-gray-800 bg-gray-950 p-5 space-y-4",children:[a.jsx("h2",{className:"text-xl font-semibold",children:"Passenger requirements"}),a.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[a.jsxs("label",{children:["Passenger count",a.jsx("input",{className:l,type:"number",min:"1",max:"16",value:D,onChange:t=>be(t.target.value),required:!0})]}),a.jsxs("label",{children:["Passenger assistant (PA)",a.jsxs("select",{className:l,value:L,onChange:t=>ye(t.target.value),children:[a.jsx("option",{value:"yes",children:"Yes"}),a.jsx("option",{value:"no",children:"No"}),a.jsx("option",{value:"unsure",children:"Unsure"})]})]}),a.jsxs("label",{children:["Same driver",a.jsxs("select",{className:l,value:W,onChange:t=>fe(t.target.value),children:[a.jsx("option",{value:"required",children:"Required"}),a.jsx("option",{value:"preferred",children:"Preferred"}),a.jsx("option",{value:"no-preference",children:"No preference"})]})]}),a.jsxs("label",{children:["Additional boarding time needed?",a.jsxs("select",{className:l,value:M,onChange:t=>ve(t.target.value),children:[a.jsx("option",{value:"",children:"Select"}),a.jsx("option",{value:"yes",children:"Yes"}),a.jsx("option",{value:"no",children:"No"}),a.jsx("option",{value:"unsure",children:"Unsure"})]})]})]}),a.jsxs("fieldset",{children:[a.jsx("legend",{className:"mb-2 font-medium",children:"Is a handover needed?"}),a.jsxs("div",{className:"flex gap-5",children:[a.jsxs("label",{className:"flex gap-2",children:[a.jsx("input",{type:"radio",name:"handover",value:"yes",checked:k==="yes",onChange:()=>V("yes")}),"Yes"]}),a.jsxs("label",{className:"flex gap-2",children:[a.jsx("input",{type:"radio",name:"handover",value:"no",checked:k==="no",onChange:()=>V("no")}),"No"]})]})]}),k==="yes"&&a.jsxs("label",{children:["Private instructions",a.jsx("textarea",{className:l,value:P,onChange:t=>je(t.target.value),rows:2})]}),a.jsxs("label",{children:["Communication needs",a.jsx("textarea",{className:l,value:z,onChange:t=>we(t.target.value),rows:2,placeholder:"Keep this concise"})]}),a.jsxs("fieldset",{children:[a.jsx("legend",{className:"mb-2 font-medium",children:"Does the passenger need to remain seated in their wheelchair during travel?"}),a.jsx("div",{className:"flex gap-5",children:[["no","No"],["transfer_possible","No, can transfer"],["remain_seated","Yes"]].map(([t,u])=>a.jsxs("label",{className:"flex gap-2",children:[a.jsx("input",{type:"radio",name:"wheelchair",value:t,checked:p===t,onChange:()=>Ne(t)}),u]},t))})]}),p==="remain_seated"&&a.jsxs("div",{role:"alert",className:"rounded-lg border border-red-700 bg-red-950/40 p-3 text-red-200",children:[a.jsx("h3",{className:"font-semibold",children:We}),a.jsx("p",{children:Le}),a.jsx("p",{children:Ve})]})]}),a.jsx("p",{className:"text-sm text-gray-400",children:"Ordinary booking details and payment are completed on the standard secure booking flow."}),Q.length>0&&a.jsx("ul",{role:"alert",className:"list-disc rounded-lg border border-red-700 bg-red-950/40 p-3 pl-7 text-red-200",children:Q.map(t=>a.jsx("li",{children:t},t))}),J&&a.jsx("p",{role:"alert",className:"rounded-lg border border-red-700 bg-red-950/40 p-3 text-red-200",children:J}),R==="submitting"&&a.jsx("p",{role:"status","aria-live":"polite",className:"text-sm text-gray-300",children:"Preparing secure checkout…"}),a.jsx("button",{type:"submit",disabled:!ee(p)||R==="submitting",className:"w-full rounded-lg bg-primary px-5 py-3 font-bold text-black disabled:cursor-not-allowed disabled:opacity-40",children:R==="submitting"?"Preparing…":"Continue to secure booking"})]}),a.jsxs("p",{className:"mt-8 text-center text-sm text-gray-500",children:[e.brandName," will use these details to help prepare your booking."]})]})})}export{Ve as SEND_REMAIN_SEATED_CONTACT_MESSAGE,We as SEND_REMAIN_SEATED_STOP_HEADING,Le as SEND_REMAIN_SEATED_STOP_MESSAGE,ee as canContinueSEND,Ke as checkoutRedirectFromResponse,Je as createSENDCheckoutRequest,ia as default,ze as parseSENDPath,Ge as validateSENDForm};

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.