mirror of
https://github.com/luxfi/quest.git
synced 2026-10-30 15:20:25 +00:00
Built with BASE_PATH=/quest for a GitHub project page. Served from this branch
rather than an Actions workflow: the repo's deploy.yml targets lux-build-amd64,
which has zero registered runners, and GitHub-hosted runners are refused on this
account ('recent account payments have failed'). A branch source needs neither.
Co-authored-by: Hanzo Dev <[email protected]>
1 line
12 KiB
JavaScript
1 line
12 KiB
JavaScript
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[323],{5462:(e,t,s)=>{Promise.resolve().then(s.bind(s,7826))},7826:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>d});var l=s(909),a=s(9641),n=s(491),r=s.n(n),o=s(5030),i=s(5420);let c="w-full rounded-lg border border-white/15 bg-white/[0.03] px-3 py-2 text-white placeholder:text-white/30 focus:border-white/40 focus:outline-none";function d(){let[e,t]=(0,a.useState)(i.Qn),[s,n]=(0,a.useState)(!1),d=(e,s)=>t(t=>({...t,[e]:s})),m=(e,s)=>t(t=>t.stops.length>=i.nM?t:{...t,stops:[...t.stops,{name:"",lat:e,lng:s,clue:"",points:10,radius:i.Px}]}),h=(e,s)=>t(t=>({...t,stops:t.stops.map((t,l)=>l===e?{...t,...s}:t)})),p=e=>t(t=>({...t,stops:t.stops.filter((t,s)=>s!==e)})),x=(0,a.useMemo)(()=>{if(0===e.stops.length)return"";let t=(0,i.f)(e);return"".concat(window.location.origin).concat("/quest","/play#").concat(t)},[e]),f=""!==e.name.trim()&&e.stops.length>0,g=async()=>{try{await navigator.clipboard.writeText(x),n(!0),setTimeout(()=>n(!1),2e3)}catch(e){}};return(0,l.jsxs)("main",{className:"mx-auto w-full max-w-2xl flex-1 px-6 py-10",children:[(0,l.jsx)(r(),{href:"/",className:"text-sm text-white/40 transition hover:text-white",children:"← Lux Quest"}),(0,l.jsx)("h1",{className:"mt-6 text-3xl font-semibold",children:"Make a quest"}),(0,l.jsxs)("div",{className:"mt-8 space-y-4",children:[(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1.5 block text-sm text-white/60",children:"Name"}),(0,l.jsx)("input",{className:c,value:e.name,onChange:e=>d("name",e.target.value),placeholder:"Mission murals"})]}),(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1.5 block text-sm text-white/60",children:"Where"}),(0,l.jsx)("input",{className:c,value:e.place,onChange:e=>d("place",e.target.value),placeholder:"San Francisco"})]}),(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"mb-1.5 block text-sm text-white/60",children:"Prize — what they get, and how to claim it"}),(0,l.jsx)("textarea",{className:c,rows:2,value:e.prize,onChange:e=>d("prize",e.target.value),placeholder:"Coffee at Ritual, on me. Text me a photo of the last one."}),(0,l.jsx)("span",{className:"mt-1.5 block text-xs text-white/40",children:"You award this yourself — Lux Quest never holds money or hands anything out."})]})]}),(0,l.jsxs)("section",{className:"mt-10",children:[(0,l.jsxs)("div",{className:"flex items-baseline justify-between",children:[(0,l.jsxs)("h2",{className:"text-sm uppercase tracking-widest text-white/40",children:["Stops ",e.stops.length>0&&"\xb7 ".concat((0,i.cK)(e)," pts")]}),e.stops.length>=i.nM&&(0,l.jsxs)("span",{className:"text-xs text-white/40",children:["Max ",i.nM]})]}),(0,l.jsx)("p",{className:"mt-2 text-sm text-white/50",children:"Tap the map to drop a stop."}),(0,l.jsx)(o.A,{pins:e.stops,onPick:m,className:"mt-3"}),(0,l.jsx)(u,{onAdd:m,disabled:e.stops.length>=i.nM}),(0,l.jsx)("ol",{className:"mt-5 space-y-4",children:e.stops.map((e,t)=>(0,l.jsxs)("li",{className:"rounded-xl border border-white/10 p-4",children:[(0,l.jsxs)("div",{className:"flex items-baseline justify-between",children:[(0,l.jsxs)("span",{className:"text-sm font-medium text-white/50 tabular-nums",children:["Stop ",t+1]}),(0,l.jsx)("button",{onClick:()=>p(t),className:"text-sm text-white/40 transition hover:text-white",children:"Remove"})]}),(0,l.jsxs)("div",{className:"mt-3 space-y-3",children:[(0,l.jsx)("input",{className:c,value:e.clue,onChange:e=>h(t,{clue:e.target.value}),placeholder:"Clue — this is what they see before they arrive"}),(0,l.jsx)("input",{className:c,value:e.name,onChange:e=>h(t,{name:e.target.value}),placeholder:"Answer — revealed once they get there"}),(0,l.jsxs)("div",{className:"flex gap-3",children:[(0,l.jsxs)("label",{className:"flex-1",children:[(0,l.jsx)("span",{className:"mb-1 block text-xs text-white/50",children:"Points"}),(0,l.jsx)("input",{type:"number",inputMode:"numeric",min:0,className:c,value:e.points,onChange:e=>h(t,{points:Math.max(0,Number(e.target.value)||0)})})]}),(0,l.jsxs)("label",{className:"flex-1",children:[(0,l.jsx)("span",{className:"mb-1 block text-xs text-white/50",children:"Radius (m)"}),(0,l.jsx)("input",{type:"number",inputMode:"numeric",min:10,className:c,value:e.radius,onChange:e=>h(t,{radius:Math.max(10,Number(e.target.value)||i.Px)})})]})]}),(0,l.jsxs)("p",{className:"text-xs text-white/30 tabular-nums",children:[e.lat.toFixed(5),", ",e.lng.toFixed(5)]})]})]},t))})]}),(0,l.jsxs)("label",{className:"mt-8 flex items-start gap-3",children:[(0,l.jsx)("input",{type:"checkbox",className:"mt-1",checked:e.hidden,onChange:e=>d("hidden",e.target.checked)}),(0,l.jsxs)("span",{children:[(0,l.jsx)("span",{className:"font-medium",children:"Hard mode"}),(0,l.jsx)("span",{className:"block text-sm text-white/50",children:"No pins on the map until a stop is found — the clue is all they get."})]})]}),(0,l.jsxs)("section",{className:"mt-10 border-t border-white/10 pt-8",children:[(0,l.jsx)("h2",{className:"text-sm uppercase tracking-widest text-white/40",children:"Share it"}),f?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("div",{className:"mt-3 flex gap-2",children:[(0,l.jsx)("input",{readOnly:!0,value:x,onFocus:e=>e.currentTarget.select(),className:"".concat(c," font-mono text-xs"),"aria-label":"Share link"}),(0,l.jsx)("button",{onClick:g,className:"shrink-0 rounded-lg bg-white px-4 py-2 font-medium text-black transition hover:bg-white/90",children:s?"Copied":"Copy"})]}),(0,l.jsx)("p",{className:"mt-2 text-xs text-white/40",children:"The whole quest is inside this link. Keep a copy — there is no other one."}),(0,l.jsx)("a",{href:x,target:"_blank",rel:"noopener noreferrer",className:"mt-4 inline-block text-sm underline underline-offset-4 hover:text-white",children:"Open it yourself first →"})]}):(0,l.jsx)("p",{className:"mt-3 text-sm text-white/50",children:0===e.stops.length?"Add at least one stop.":"Give it a name."})]})]})}function u(e){let{onAdd:t,disabled:s}=e,[n,r]=(0,a.useState)(""),[o,i]=(0,a.useState)(""),d=()=>{let e=n.trim().match(/^(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)$/);if(!e)return i("Paste as: 37.7749, -122.4194");let s=Number(e[1]),l=Number(e[2]);if(Math.abs(s)>90||Math.abs(l)>180)return i("That is not on the globe.");t(s,l),r(""),i("")};return(0,l.jsxs)("div",{className:"mt-3",children:[(0,l.jsxs)("div",{className:"flex gap-2",children:[(0,l.jsx)("input",{className:"".concat(c," font-mono text-sm"),value:n,disabled:s,onChange:e=>{r(e.target.value),i("")},onKeyDown:e=>"Enter"===e.key&&d(),placeholder:"or paste coordinates: 37.7749, -122.4194","aria-label":"Add a stop by coordinates"}),(0,l.jsx)("button",{onClick:d,disabled:s,className:"shrink-0 rounded-lg border border-white/20 px-4 py-2 transition hover:border-white/40 disabled:opacity-40",children:"Add"})]}),o&&(0,l.jsx)("p",{className:"mt-1.5 text-xs text-red-400",children:o})]})}},5030:(e,t,s)=>{"use strict";s.d(t,{A:()=>o});var l=s(909),a=s(9641),n=s(653);let r={lat:37.7749,lng:-122.4194};function o(e){let{pins:t,center:s,onPick:o,className:c="",height:d="h-72"}=e,u=(0,a.useRef)(null),m=(0,a.useRef)(null),h=(0,a.useRef)([]),[p,x]=(0,a.useState)(n.c_?"loading":"no-key");return((0,a.useEffect)(()=>{if(!n.c_)return;let e=!0;return(0,n.Ak)().then(()=>e&&x("ready")).catch(t=>e&&x("no-key"===t.message?"no-key":"failed")),()=>{e=!1}},[]),(0,a.useEffect)(()=>{var e;if("ready"!==p||!u.current||m.current)return;let l=window.google;m.current=new l.maps.Map(u.current,{center:null!==(e=null!=s?s:t[0])&&void 0!==e?e:r,zoom:t.length?14:12,mapTypeControl:!1,streetViewControl:!1,fullscreenControl:!1,styles:i})},[p,s,t]),(0,a.useEffect)(()=>{if("ready"!==p||!m.current||!o)return;let e=m.current.addListener("click",e=>{o(e.latLng.lat(),e.latLng.lng())});return()=>{var t;return null==e?void 0:null===(t=e.remove)||void 0===t?void 0:t.call(e)}},[p,o]),(0,a.useEffect)(()=>{if("ready"!==p||!m.current)return;let e=window.google;if(h.current.forEach(e=>e.setMap(null)),h.current=t.map((t,s)=>new e.maps.Marker({position:{lat:t.lat,lng:t.lng},map:m.current,label:{text:String(s+1),color:"#000",fontWeight:"700"},title:t.found?t.name:t.clue,icon:{path:e.maps.SymbolPath.CIRCLE,scale:14,fillColor:t.found?"#4ade80":"#ffffff",fillOpacity:1,strokeWeight:0}})),t.length>1){let s=new e.maps.LatLngBounds;t.forEach(e=>s.extend({lat:e.lat,lng:e.lng})),m.current.fitBounds(s,64)}else 1===t.length&&(m.current.setCenter(t[0]),m.current.setZoom(15))},[t,p]),"ready"===p)?(0,l.jsx)("div",{ref:u,className:"w-full rounded-xl overflow-hidden ".concat(d," ").concat(c)}):(0,l.jsxs)("div",{className:"w-full rounded-xl border border-white/15 bg-white/[0.03] p-4 ".concat(c),role:"region","aria-label":"Stops",children:[(0,l.jsxs)("p",{className:"text-sm text-white/60",children:["loading"===p&&"Loading the map…","no-key"===p&&"No map key configured — the stops and links below all work.","failed"===p&&"The map failed to load. The stops and links below all work."]}),t.length>0&&(0,l.jsx)("ol",{className:"mt-3 space-y-2",children:t.map((e,t)=>(0,l.jsxs)("li",{className:"flex items-baseline gap-2 text-sm",children:[(0,l.jsxs)("span",{className:"text-white/40 tabular-nums",children:[t+1,"."]}),(0,l.jsx)("a",{href:(0,n.dy)(e.lat,e.lng),target:"_blank",rel:"noopener noreferrer",className:"underline underline-offset-2 hover:text-white",children:e.found?e.name:e.clue||"Open in Google Maps"})]},t))}),o&&(0,l.jsx)("p",{className:"mt-3 text-xs text-white/40",children:"Without a map key you can still add stops by pasting coordinates below."})]})}let i=[{elementType:"geometry",stylers:[{color:"#212121"}]},{elementType:"labels.icon",stylers:[{visibility:"off"}]},{elementType:"labels.text.fill",stylers:[{color:"#9e9e9e"}]},{elementType:"labels.text.stroke",stylers:[{color:"#212121"}]},{featureType:"road",elementType:"geometry.fill",stylers:[{color:"#2c2c2c"}]},{featureType:"water",elementType:"geometry",stylers:[{color:"#000000"}]},{featureType:"poi",elementType:"labels.text.fill",stylers:[{color:"#757575"}]}]},653:(e,t,s)=>{"use strict";var l;s.d(t,{Ak:()=>r,c_:()=>a,dy:()=>i,oP:()=>o});let a=null!==(l=s(2280).env.NEXT_PUBLIC_GOOGLE_MAPS_KEY)&&void 0!==l?l:"",n=null;function r(){var e;return a?(null===(e=window.google)||void 0===e?void 0:e.maps)?Promise.resolve():n||(n=new Promise((e,t)=>{let s=document.createElement("script");s.src="https://maps.googleapis.com/maps/api/js?key=".concat(encodeURIComponent(a))+"&libraries=places&loading=async&v=weekly",s.async=!0,s.onload=()=>e(),s.onerror=()=>{n=null,t(Error("failed"))},document.head.appendChild(s)})):Promise.reject(Error("no-key"))}function o(e,t){return"https://www.google.com/maps/dir/?api=1&destination=".concat(e,",").concat(t)}function i(e,t){return"https://www.google.com/maps/search/?api=1&query=".concat(e,",").concat(t)}},5420:(e,t,s)=>{"use strict";s.d(t,{Px:()=>o,Qn:()=>a,Zx:()=>c,cK:()=>n,f:()=>i,nM:()=>l});let l=20;function a(){return{name:"",place:"",prize:"",stops:[],hidden:!1}}function n(e){return e.stops.reduce((e,t)=>e+t.points,0)}let r=e=>Math.round(1e5*e)/1e5,o=60;function i(e){return function(e){let t="";for(let s of e)t+=String.fromCharCode(s);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}(new TextEncoder().encode(JSON.stringify(function(e){let t={n:e.name,l:e.place,z:e.prize,s:e.stops.map(e=>({n:e.name,a:r(e.lat),o:r(e.lng),c:e.clue,p:e.points,r:e.radius}))};return e.hidden&&(t.h=1),t}(e))))}function c(e){let t=e.trim().replace(/^#/,"");if(!t)return null;try{var s,l,a;let e=JSON.parse(new TextDecoder().decode(function(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),s=atob(t+"=".repeat((4-t.length%4)%4)),l=new Uint8Array(s.length);for(let e=0;e<s.length;e++)l[e]=s.charCodeAt(e);return l}(t)));if(!e||"object"!=typeof e)return null;let n={name:String(null!==(s=e.n)&&void 0!==s?s:""),place:String(null!==(l=e.l)&&void 0!==l?l:""),prize:String(null!==(a=e.z)&&void 0!==a?a:""),hidden:1===e.h,stops:(Array.isArray(e.s)?e.s:[]).map(e=>{var t,s;return{name:String(null!==(t=null==e?void 0:e.n)&&void 0!==t?t:""),lat:Number(null==e?void 0:e.a),lng:Number(null==e?void 0:e.o),clue:String(null!==(s=null==e?void 0:e.c)&&void 0!==s?s:""),points:Number(null==e?void 0:e.p)||0,radius:Number(null==e?void 0:e.r)||o}})},r=n.stops.filter(e=>Number.isFinite(e.lat)&&Number.isFinite(e.lng)&&90>=Math.abs(e.lat)&&180>=Math.abs(e.lng));if(0===r.length)return null;return{...n,stops:r}}catch(e){return null}}}},e=>{var t=t=>e(e.s=t);e.O(0,[491,294,41,358],()=>t(5462)),_N_E=e.O()}]); |