PageSourceSearch

https://quest-x.ai/_next/static/chunks/app/(admin)/admin/game-bridge/page-b6a559784a3ac11f.js

js quest-x.ai collected 2026-10-05 12:31:17 UTC 16,898 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2692],{79320:function(e,a,s){Promise.resolve().then(s.bind(s,74759))},74759:function(e,a,s){"use strict";s.r(a),s.d(a,{default:function(){return I}});var t=s(27573),l=s(7653),r=s(88146),i=s(75721),n=s(87354),c=s(51856),d=s(70844),o=s(38333),m=s(66350),u=s(33742),h=s(51356),g=s(98521),x=s(63769),p=s(16273),b=s(24012);let y=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,v={active:"qx-gb-status qx-gb-status-active",paused:"qx-gb-status qx-gb-status-pending",pending:"qx-gb-status qx-gb-status-pending",suspended:"qx-gb-status qx-gb-status-suspended"};function j(e){return e.game_title??e.title??""}function f(e){return(e.developer??e.developer_id??e.developer_user_id??"").trim()}function k(e){return e.quest_count??e.questCount??0}function N(e){return e.total_conversions??e.totalConversions??0}function w(e){return e.total_payout_xut??e.totalPayoutXut??0}let C="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-300",q=[{key:"games",label:"Total Games",icon:"/figma-admin/ic-gb-stat-games.svg",tone:"violet"},{key:"quests",label:"Total Game Quests",icon:"/figma-admin/ic-gb-stat-quests.svg",tone:"cyan"},{key:"conversions",label:"Total Conversions",icon:"/figma-admin/ic-gb-stat-conversions.svg",tone:"emerald"},{key:"paused",label:"Paused (awaiting activate)",icon:"/figma-admin/ic-gb-stat-pending.svg",tone:"amber"}],S={nakamaGameId:"",gameTitle:"",softCurrencyName:"",pointsPerPlay:"10",apiCallbackUrl:"",developerUserId:""};function I(){let[e,a]=(0,l.useState)(""),[s,I]=(0,l.useState)("all"),[_,P]=(0,l.useState)([]),[G,U]=(0,l.useState)(!0),[A,D]=(0,l.useState)(null),[Z,T]=(0,l.useState)(!1),[F,L]=(0,l.useState)(!1),[z,R]=(0,l.useState)(null),[$,M]=(0,l.useState)(null),[V,E]=(0,l.useState)(S),[O,Q]=(0,l.useState)(null),[X,B]=(0,l.useState)(!1),[H,K]=(0,l.useState)(null),W=(0,l.useCallback)(async()=>{try{let e=await (0,b.hi)("/game-bridge/admin/games");P(Array.isArray(e)?e:[])}catch{P([]),m.Am.error("Failed to load games")}finally{U(!1)}},[]);(0,l.useEffect)(()=>{W(),(0,b.hi)("/game-bridge/nakama-health").then(D).catch(()=>D({healthy:!1,error:"Failed to reach Nakama"}))},[W]);let J=async(e,a)=>{try{await navigator.clipboard.writeText(e),K(a),m.Am.success("Copied"),setTimeout(()=>K(null),1500)}catch{m.Am.error("Could not copy")}},Y=async()=>{let e=V.nakamaGameId.trim(),a=V.gameTitle.trim(),s=V.softCurrencyName.trim();if(!e||!a||!s){m.Am.warning("Please fill in all required fields");return}if(!y.test(e)){m.Am.error("Nakama Game ID must be a UUID");return}L(!0);try{let t=await (0,b.hi)("/game-bridge/admin/register",{method:"POST",body:{nakamaGameId:e,gameTitle:a,softCurrencyName:s,pointsPerPlay:parseInt(V.pointsPerPlay,10)||10,apiCallbackUrl:V.apiCallbackUrl.trim()||void 0,developerUserId:V.developerUserId.trim()||void 0}});T(!1),E(S),B(!1),Q(t),m.Am.success("Game registered (paused until activated)"),!1===t.nakamaReachable&&m.Am.message("Nakama was not reachable. The game id was saved anyway."),await W()}catch(e){m.Am.error("Failed to register game: "+e.message)}finally{L(!1)}},ee=async e=>{M(e);try{await (0,b.hi)(`/game-bridge/admin/${e}/suspend`,{method:"POST"}),m.Am.success("Game suspended"),await W()}catch(e){m.Am.error("Failed to suspend: "+e.message)}finally{M(null)}},ea=async e=>{R(e);try{await (0,b.hi)(`/game-bridge/admin/${e}/activate`,{method:"POST"}),m.Am.success("Game activated"),await W()}catch(e){m.Am.error("Failed to activate: "+e.message)}finally{R(null)}},es=_.length,et=_.reduce((e,a)=>e+k(a),0),el=_.filter(e=>"paused"===e.status).length,er=_.reduce((e,a)=>e+N(a),0),ei={games:es,quests:et,conversions:er,paused:el},en=_.filter(a=>!!(("all"===s||a.status===s)&&(!e||j(a).toLowerCase().includes(e.toLowerCase())||f(a).toLowerCase().includes(e.toLowerCase())||(a.nakama_game_id??"").toLowerCase().includes(e.toLowerCase())))),ec=[{key:"game",header:"Game",sortable:!0,sortValue:e=>j(e).toLowerCase(),cell:e=>(0,t.jsxs)("div",{className:"qx-gb-game-cell",children:[(0,t.jsx)("span",{className:"qx-gb-game-icon",children:(0,t.jsx)("img",{src:"/figma-admin/ic-gb-row-game.svg",alt:"",width:18,height:18})}),(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"qx-gb-game-name",children:j(e)}),(0,t.jsxs)("span",{className:"qx-gb-game-currency",children:[(e.soft_currency_name??e.softCurrency??"")||"points",e.nakama_game_id?` \xb7 ${function(e){let a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:8;return e?e.length<=2*a?e:`${e.slice(0,a)}…${e.slice(-4)}`:"—"}(e.nakama_game_id)}`:""]})]})]})},{key:"developer",header:"Developer",cell:e=>{let a=f(e);return(0,t.jsx)("span",{className:"qx-gb-dev",title:a||void 0,children:a||"—"})}},{key:"status",header:"Status",sortable:!0,sortValue:e=>String(e.status),cell:e=>(0,t.jsx)("span",{className:v[e.status]??"qx-gb-status",children:String(e.status).charAt(0).toUpperCase()+String(e.status).slice(1)})},{key:"quests",header:"Quests",align:"right",sortable:!0,sortValue:e=>k(e),cell:e=>(0,t.jsx)("span",{className:"qx-gb-num",children:k(e)})},{key:"conversions",header:"Conversions",align:"right",sortable:!0,sortValue:e=>N(e),cell:e=>(0,t.jsx)("span",{className:"qx-gb-num",children:N(e).toLocaleStr
1ing()})},{key:"xut",header:"Points paid",align:"right",sortable:!0,sortValue:e=>w(e),cell:e=>(0,t.jsxs)("span",{className:"qx-gb-pts",children:[w(e).toLocaleString()," pts"]})},{key:"actions",header:"Actions",cell:e=>(0,t.jsxs)("div",{className:"flex items-center gap-2",children:["paused"===e.status?(0,t.jsxs)(p.z,{size:"sm",variant:"outline",disabled:z===e.id,onClick:()=>ea(e.id),className:"gap-1",children:[z===e.id&&(0,t.jsx)(i.Z,{className:"h-3.5 w-3.5 animate-spin"}),"Activate"]}):null,"active"===e.status?(0,t.jsxs)(p.z,{size:"sm",variant:"outline",disabled:$===e.id,onClick:()=>ee(e.id),className:"gap-1",children:[$===e.id&&(0,t.jsx)(i.Z,{className:"h-3.5 w-3.5 animate-spin"}),"Suspend"]}):null,"paused"!==e.status&&"active"!==e.status?(0,t.jsx)("span",{className:"text-xs text-gray-400",children:"—"}):null]})}],ed=O?`/api/game-bridge/${O.id}/webhook`:"";return(0,t.jsxs)("div",{"data-qx-admin-gb":!0,children:[(0,t.jsxs)("nav",{className:"qx-admin-bc","aria-label":"Breadcrumb",children:[(0,t.jsxs)(r.default,{href:"/admin",children:[(0,t.jsx)("img",{src:"/figma-admin/ic-home.svg",alt:"",width:14,height:14}),"Admin"]}),(0,t.jsx)("span",{className:"qx-admin-bc-sep","aria-hidden":!0,children:">"}),(0,t.jsx)("span",{"aria-current":"page",children:"Game Bridge"})]}),(0,t.jsxs)("div",{className:"qx-gb-title-row",children:[(0,t.jsxs)("div",{className:"qx-gb-title",children:[(0,t.jsx)("span",{className:"qx-gb-title-icon","aria-hidden":!0,children:(0,t.jsx)("span",{className:"qx-gb-title-glyph"})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("h1",{children:"Game Bridge"}),(0,t.jsx)("p",{children:"Manage registered games and their quest integrations"})]})]}),(0,t.jsxs)("button",{type:"button",className:"qx-gb-register",onClick:()=>T(!0),children:[(0,t.jsx)("img",{src:"/figma-admin/ic-gb-plus.svg",alt:"",width:16,height:16}),"Register New Game"]})]}),A&&(0,t.jsxs)("div",{className:`qx-gb-health${A.healthy?" qx-gb-health-ok":""}`,role:"status",children:[(0,t.jsx)("span",{className:"qx-gb-health-icon",children:(0,t.jsx)("img",{src:"/figma-admin/ic-gb-heart.svg",alt:"",width:16,height:16})}),(0,t.jsxs)("p",{children:[(0,t.jsx)("span",{className:"qx-gb-health-label",children:"Nakama Server: "}),(0,t.jsx)("span",{className:A.healthy?"qx-gb-health-good":"qx-gb-health-bad",children:A.healthy?"Healthy":"Unhealthy"}),(0,t.jsxs)("span",{className:"qx-gb-health-ver",children:[" ","v",A.version||"unknown"]}),A.error?(0,t.jsxs)("span",{className:"qx-gb-health-err",children:[" — ",A.error]}):null]})]}),(0,t.jsx)("div",{className:"qx-gb-stats",children:q.map(e=>(0,t.jsxs)("article",{className:"qx-gb-stat","data-tone":e.tone,children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"qx-gb-stat-label",children:e.label}),(0,t.jsx)("p",{className:"qx-gb-stat-value",children:G?"—":"conversions"===e.key?er.toLocaleString():ei[e.key]})]}),(0,t.jsx)("span",{className:"qx-gb-stat-icon",children:(0,t.jsx)("img",{src:e.icon,alt:"",width:20,height:20})})]},e.key))}),(0,t.jsxs)("div",{className:"qx-gb-filters",children:[(0,t.jsxs)("div",{className:"qx-gb-search",children:[(0,t.jsx)("img",{src:"/figma-admin/ic-search.svg",alt:"",width:16,height:16}),(0,t.jsx)("input",{type:"text",placeholder:"Search games, developers, or Nakama ID...",value:e,onChange:e=>a(e.target.value),"aria-label":"Search games or developers"})]}),(0,t.jsxs)("select",{value:s,onChange:e=>I(e.target.value),"aria-label":"Filter by status",children:[(0,t.jsx)("option",{value:"all",children:"All Status"}),(0,t.jsx)("option",{value:"active",children:"Active"}),(0,t.jsx)("option",{value:"paused",children:"Paused"}),(0,t.jsx)("option",{value:"suspended",children:"Suspended"})]})]}),(0,t.jsx)("div",{className:"qx-gb-table",children:(0,t.jsx)(u.w,{columns:ec,data:en,rowKey:e=>e.id,loading:G,pageSize:15,initialSort:{key:"game",dir:"asc"},emptyState:(0,t.jsx)(h.u,{icon:(0,t.jsx)("img",{src:"/figma-admin/ic-gb-title.svg",alt:"",width:40,height:40}),title:"No games registered",description:"Register a game to bridge its economy with QuestX quests.",action:(0,t.jsxs)("button",{type:"button",className:"qx-gb-register",onClick:()=>T(!0),children:[(0,t.jsx)("img",{src:"/figma-admin/ic-gb-plus.svg",alt:"",width:16,height:16}),"Register New Game"]})})})}),(0,t.jsxs)(g.Vq,{open:Z,onClose:()=>T(!1),className:"max-w-lg",dismissible:!F,children:[(0,t.jsx)(g.fK,{title:"Register New Game",description:"Connect a Nakama game to QuestX. Starts paused until you activate it.",onClose:()=>T(!1)}),(0,t.jsxs)(g.a7,{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:C,htmlFor:"nakamaGameId",children:"Nakama Game ID *"}),(0,t.jsx)(x.I,{id:"nakamaGameId",placeholder:"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",value:V.nakamaGameId,onChange:e=>E({...V,nakamaGameId:e.target.value})})]}),(0,t.jsxs)("div",{className:"grid gap-4 sm:grid-cols-2",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:C,htmlFor:"gameTitle",children:"Game Title *"}),(0,t.jsx)(x.I,{id:"gameTitle",placeholder:"e.g., Space Blaster",value:V.gameTitle,onChange:e=>E({...V,gameTitle:e.target.value})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:C,htmlFor:"softCurrencyName",children:"Soft Currency Name *"}),(0,t.jsx)(x.I,{id:"softCurrencyName",placeholder:"e.g., Star Coins",value:V.softCurrencyName,onChange:e=>E({...V,softCurrencyName:e.target.value})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:C,htmlFor:"pointsPerPlay",children:"Points per play"}),(0,t.jsx)(x.I,{id:"pointsPerPlay",type:"number",min:0,placeholder:"10",value:V.pointsPerPlay,onChange:e=>E({...V,pointsPerPlay:e.target.value})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:C,htmlFor:"developerUserId",children:"Developer user ID (optional)"}),(0,t.jsx)(x.I,{id:"developerUserId",placeholder:"QuestX user UUID — defaults to you",value:V.developerUserId,onChange:e=>E({...V,developerUserId:e.target.value})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:C,htmlFor:"apiCallbackUrl",children:"Callback URL (optional)"}),(0,t.jsx)(x.I,{id:"apiCallbackUrl",type:"url",placeholder:"https://your-game.com/webhooks/quests",value:V.apiCallbackUrl,onChange:e=>E({...V,apiCallbackUrl:e.target.value})})]})]})]}),(0,t.jsxs)(g.cN,{children:[(0,t.jsx)(p.z,{variant:"outline",onClick:()=>T(!1),disabled:F,children:"Cancel"}),(0,t.jsxs)(p.z,{onClick:Y,disabled:F,className:"gap-2",children:[F&&(0,t.jsx)(i.Z,{className:"h-4 w-4 animate-spin"}),"Register Game"]})]})]}),(0,t.jsxs)(g.Vq,{open:!!O,onClose:()=>Q(null),className:"max-w-lg",children:[(0,t.jsx)(g.fK,{title:"Connect credentials",description:"Copy these now — webhook secret is the connect key for your game.",onClose:()=>Q(null)}),O&&(0,t.jsxs)(g.a7,{className:"space-y-3",children:[(0,t.jsxs)("p",{className:"text-xs text-amber-600 dar
1k:text-amber-400",children:["Status: ",(0,t.jsx)("strong",{children:"paused"})," until you activate it from the list."]}),[{key:"id",label:"Registration ID",value:O.id},{key:"nakama",label:"Nakama Game ID",value:O.nakama_game_id},{key:"path",label:"Webhook path",value:ed}].map(e=>(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"mb-1 block text-xs font-medium text-gray-500",children:e.label}),(0,t.jsxs)("div",{className:"flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-2 dark:border-gray-700 dark:bg-gray-800",children:[(0,t.jsx)("code",{className:"flex-1 truncate text-xs",children:e.value}),(0,t.jsx)("button",{type:"button",className:"shrink-0 rounded p-1 text-gray-400 hover:text-gray-700",onClick:()=>J(e.value,e.key),"aria-label":`Copy ${e.label}`,children:H===e.key?(0,t.jsx)(n.Z,{className:"h-4 w-4 text-green-500"}):(0,t.jsx)(c.Z,{className:"h-4 w-4"})})]})]},e.key)),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"mb-1 block text-xs font-medium text-gray-500",children:"Webhook secret"}),(0,t.jsx)("p",{className:"mb-1 text-xs text-gray-500",children:"HMAC key to sign events. Nakama Game ID is your platform UUID, not minted by QuestX."}),(0,t.jsxs)("div",{className:"flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-2 dark:border-gray-700 dark:bg-gray-800",children:[(0,t.jsx)("code",{className:"flex-1 truncate text-xs",children:X?O.credentials?.webhook_secret||O.webhook_secret:"••••••••••••••••••••••••••••"}),(0,t.jsx)("button",{type:"button",className:"shrink-0 rounded p-1 text-gray-400 hover:text-gray-700",onClick:()=>B(e=>!e),"aria-label":X?"Hide secret":"Show secret",children:X?(0,t.jsx)(d.Z,{className:"h-4 w-4"}):(0,t.jsx)(o.Z,{className:"h-4 w-4"})}),(0,t.jsx)("button",{type:"button",className:"shrink-0 rounded p-1 text-gray-400 hover:text-gray-700",onClick:()=>J(O.credentials?.webhook_secret||O.webhook_secret,"secret"),"aria-label":"Copy webhook secret",children:"secret"===H?(0,t.jsx)(n.Z,{className:"h-4 w-4 text-green-500"}):(0,t.jsx)(c.Z,{className:"h-4 w-4"})})]})]})]}),(0,t.jsx)(g.cN,{children:(0,t.jsx)(p.z,{onClick:()=>Q(null),children:"Done"})})]})]})}},63769:function(e,a,s){"use strict";s.d(a,{I:function(){return c}});var t=s(27573),l=s(7653),r=s(19369),i=s(10850);let n={default:"border-gray-200 focus-visible:border-primary-500 focus-visible:ring-primary-500/25 dark:border-white/10",invalid:"border-danger-400 focus-visible:border-danger-500 focus-visible:ring-danger-500/25 dark:border-danger-500/60"},c=l.forwardRef((e,a)=>{let{className:s,type:l,invalid:c=!1,ariaLabel:d,ariaDescribedBy:o,onCopy:m,onCut:u,onPaste:h,onDrop:g,...x}=e,p="password"===l;return(0,t.jsx)("input",{type:l,className:(0,r.cn)("flex h-11 w-full rounded-lg border bg-white px-3 py-2 text-sm text-gray-900 transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-400 focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50 sm:h-10 dark:bg-white/[0.03] dark:text-white dark:placeholder:text-gray-500",c?n.invalid:n.default,s),ref:a,"aria-label":d,"aria-describedby":o,"aria-invalid":c||void 0,onCopy:e=>{p&&i.N.onCopy(e),m?.(e)},onCut:e=>{p&&i.N.onCut(e),u?.(e)},onPaste:e=>{p&&i.N.onPaste(e),h?.(e)},onDrop:e=>{p&&i.N.onDrop(e),g?.(e)},...x})});c.displayName="Input"},10850:function(e,a,s){"use strict";s.d(a,{N:function(){return t}});let t={onCopy:e=>e.preventDefault(),onCut:e=>e.preventDefault(),onPaste:e=>e.preventDefault(),onDrop:e=>e.preventDefault()}},87354:function(e,a,s){"use strict";s.d(a,{Z:function(){return t}});let t=(0,s(2389).Z)("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]])},51856:function(e,a,s){"use strict";s.d(a,{Z:function(){return t}});let t=(0,s(2389).Z)("Copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]])},70844:function(e,a,s){"use strict";s.d(a,{Z:function(){return t}});let t=(0,s(2389).Z)("EyeOff",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]])},38333:function(e,a,s){"use strict";s.d(a,{Z:function(){return t}});let t=(0,s(2389).Z)("Eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]])}},function(e){e.O(0,[11547,16340,17787,76930,86174,24012,4871,81293,23892,1744],function(){return e(e.s=79320)}),_N_E=e.O()}]);

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.