PageSourceSearch

https://ui-helper--stoxra.replit.app/assets/forex-trade-B-AdkaHd.js

js ui-helper--stoxra.replit.app collected 2026-10-03 03:56:55 UTC 9,477 bytes, 1 lines download raw bytes

1import{cw as K,u as H,r as v,ad as G,ah as J,e as w,bh as $,j as e,bj as I,O as V,as as X,a as x,aB as E,T as q,g as B,a6 as Z,a1 as z,aw as T}from"./index-C8T3vEcn.js";import{P as W}from"./PremiumTradingChart-Q3bx4y_D.js";import"./wifi-DjaVM5V6.js";import"./wifi-off-lrizO7-p.js";import"./chart-candlestick-Drpdm06n.js";import"./minus-DkbdB_cf.js";import"./trash-2-N9IG424w.js";function U(f,h){const r=h==="JPY"?3:5;return f.toFixed(r)}function ie(){const[,f]=K("/forex/:pair"),[,h]=H(),r=(f?.pair||"EURUSD").toUpperCase(),[S,g]=v.useState("1000"),[a,F]=v.useState("BUY"),[Y,D]=v.useState(!1),{user:P,isAuthenticated:j}=G(),y=J(),{data:n}=w({queryKey:["/api/forex/price",r],queryFn:async()=>{const t=await fetch(`/api/forex/price/${r}`);if(!t.ok)throw new Error("price unavailable");return t.json()},refetchInterval:6e4,retry:!1}),{data:A=[]}=w({queryKey:["/api/holdings"],queryFn:async()=>(await T("GET","/api/holdings")).json(),enabled:j}),o=A.find(t=>t.symbol===r&&t.assetType==="FOREX"),i=n?.price||0,b=i>0,m=parseFloat(S)||0,l=o?parseFloat(o.decimalQuantity||"0"):0,d=n?.quote||"USD",{data:R}=w({queryKey:["forex-trade-spot"],queryFn:async()=>{const t=await fetch("/api/forex/top10");return t.ok?t.json():{markets:[]}},enabled:j&&d!=="USD",refetchInterval:6e4}),k=(()=>{if(d==="USD")return 1;const t=new Map;for(const c of R?.markets??[])t.set(c.symbol,c.price);const s=c=>t.get(c)??0,p=c=>{const L=s(c);return L>0?1/L:0};switch(d){case"EUR":return s("EURUSD");case"GBP":return s("GBPUSD");case"AUD":return s("AUDUSD");case"NZD":return s("NZDUSD");case"JPY":return p("USDJPY");case"CHF":return p("USDCHF");case"CAD":return p("USDCAD");default:return 0}})(),C=i*m*(k||1),u=$({mutationFn:async t=>{const s=await T("POST","/api/forex/trade",{symbol:r,type:t,quantity:m});if(!s.ok){const p=await s.json();throw new Error(p.message||"Trade failed")}return s.json()},onSuccess:()=>{D(!0),setTimeout(()=>D(!1),3e3),y.invalidateQueries({queryKey:["/api/holdings"]}),y.invalidateQueries({queryKey:["/api/auth/me"]}),y.invalidateQueries({queryKey:["/api/trades"]})}}),Q=t=>{if(!j){h("/login");return}!b||m<=0||u.mutate(t)},N=parseFloat(P?.virtualBalance||"0"),M=a==="BUY"&&C>N,O=a==="SELL"&&m>l+1e-9;return e.jsx(I,{children:e.jsxs("div",{className:"flex flex-col gap-3 sm:gap-4 h-full bg-[#0a0e17] min-h-screen p-2 sm:p-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("button",{onClick:()=>h("/forex"),className:"p-2 rounded-xl hover:bg-slate-800/50 transition-all duration-200 text-slate-400 hover:text-white","data-testid":"back-button",children:e.jsx(V,{className:"w-5 h-5"})}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-9 h-9 rounded-full bg-purple-500/20 flex items-center justify-center",children:e.jsx(X,{className:"w-4 h-4 text-purple-300"})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h1",{className:"text-base sm:text-xl font-bold text-white",children:r}),e.jsx("span",{className:"text-[10px] font-semibold bg-purple-500/15 text-purple-300 px-2 py-0.5 rounded-full border border-purple-500/20",children:"FOREX · USD"})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm mt-0.5",children:[e.jsx("span",{className:"font-mono text-sm sm:text-lg font-semibold text-white","data-testid":"text-current-price",children:U(i,d)}),n&&e.jsxs("span",{className:x("font-mono text-xs px-1.5 py-0.5 rounded-full",n.changePercent24h>=0?"text-emerald-400 bg-emerald-500/10":"text-red-400 bg-red-500/10"),children:[n.changePercent24h>=0?"+":"",n.changePercent24h.toFixed(2),"%"]})]})]})]})]}),!b&&e.jsxs("div",{className:"p-3 rounded-xl bg-amber-500/10 border border-amber-500/20 text-amber-200 text-xs flex items-center gap-2","data-testid":"price-unavailable",children:[e.jsx(E,{className:"w-4 h-4"})," Live forex price unavailable — trading is temporarily disabled."]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-3 sm:gap-4 flex-1",children:[e.jsx("div",{className:"lg:col-span-2",children:e.jsx(W,{symbol:r,name:n?.name||r,type:"stock",historyEndpoint:"/api/forex/history",height:450})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"bg-[#0f1729]/80 backdrop-blur-sm rounded-xl p-4 border border-slate-700/20",children:[e.jsx("h3",{className:"font-semibold mb-4 text-white",children:"Place Order"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 p-1 bg-[#0a0e17] rounded-xl mb-4",children:[e.jsxs("button",{onClick:()=>F("BUY"),className:x("py-2 rounded-lg font-semibold text-sm transition-all duration-300 flex items-center justify-center gap-2",a==="BUY"?"bg-emerald-600 text-white shadow-lg shadow-emerald-600/30":"text-slate-400 hover:text-slate-200"),"data-testid":"buy-tab",children:[e.jsx(q,{className:"w-4 h-4"})," BUY"]}),e.jsxs("button",{onClick:()=>F("SELL"),className:x("py-2 rounded-lg font-semibold text-sm transition-all duration-300 flex items-center justify-center gap-2",a==="SELL"?"bg-red-600 text-white shadow-lg shadow-red-600/30":"text-slate-400 hover:text-slate-200"),"data-testid":"sell-tab",children:[e.jsx(B,{className:"w-4 h-4"})," SELL"]})]}),e.jsxs("div",{className:"mb-4",children:[e.jsxs("label",{className:"text-sm text-slate-400 mb-1 block",children:["Units of ",n?.base??"base"]}),e.jsx("input",{type:"number",inputMode:"decimal",step:"100",min:"0",value:S,onChange:t=>g(t.target.value),className:"w-full h-10 bg-[#0a0e17] rounded-xl text-center font-mono text-base border border-slate-700/30 focus:outline-none focus:ring-1 focus:ring-purple-500/50 text-white","data-testid":"qty-input"}),e.jsxs("div",{className:"flex justify-between text-[11px] text-slate-500 mt-1",children:[e.jsxs("span",{children:["Held: ",l.toFixed(2)]}),a==="BUY"&&b&&e.jsx("button",{type:"button",className:"text-purple-300 hover:underline",onClick:()=>{const s=i*(k||1);s>0&&g(Math.floor(N/s).toString())},"data-testid":"btn-max-buy",children:"Max"}),a==="SELL"&&l>0&&e.jsx("button",{type:"button",className:"text-purple-300 hover:underline",onClick:()=>g(l.toFixed(2)),"data-testid":"btn-max-sell",children:"Max"})]})]}),e.jsxs("div",{className:"bg-[#0a0e17]/80 rounded-xl p-3 mb-4 border border-slate-800/50",children:[e.jsxs("div",{className:"flex justify-between text-sm mb-2",children:[e.jsx("span",{className:"text-slate-500",children:"Rate"}),e.jsx("span",{className:"font-mono text-white",children:U(i,d)})]}),e.jsxs("div",{className:"flex justify-between font-semibold border-t border-slate-700/30 pt-2",children:[e.jsx("span",{className:"text-slate-300",children:"Notional (USD)"}),e.jsxs("span",{className:x("font-mono",a==="BUY"?"text-emerald-400":"text-red-400"),"data-testid":"text-total",children:["$",C.toLocaleStr
1ing("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})]})]})]}),e.jsx("button",{onClick:()=>Q(a),disabled:!b||u.isPending||m<=0||M||O,className:x("w-full py-3 rounded-xl font-semibold transition-all duration-300 flex items-center justify-center gap-2",a==="BUY"?"bg-emerald-600 hover:bg-emerald-500 text-white disabled:bg-emerald-600/30 disabled:text-emerald-400/50":"bg-red-600 hover:bg-red-500 text-white disabled:bg-red-600/30 disabled:text-red-400/50"),"data-testid":"execute-trade",children:u.isPending?e.jsx(Z,{className:"w-4 h-4 animate-spin"}):e.jsxs(e.Fragment,{children:[a==="BUY"?e.jsx(q,{className:"w-4 h-4"}):e.jsx(B,{className:"w-4 h-4"}),a," ",r]})}),u.isError&&e.jsxs("div",{className:"mt-3 p-2.5 bg-red-500/10 border border-red-500/20 rounded-xl flex items-center gap-2 text-red-400 text-sm","data-testid":"trade-error",children:[e.jsx(E,{className:"w-4 h-4 shrink-0"}),u.error.message]}),Y&&e.jsxs("div",{className:"mt-3 p-2.5 bg-emerald-500/10 border border-emerald-500/20 rounded-xl flex items-center gap-2 text-emerald-400 text-sm","data-testid":"trade-success",children:[e.jsx(z,{className:"w-4 h-4 shrink-0"}),"Order executed successfully!"]})]}),o&&l>0&&e.jsxs("div",{className:"bg-[#0f1729]/80 backdrop-blur-sm rounded-xl p-4 border border-slate-700/20","data-testid":"position-card",children:[e.jsx("h3",{className:"font-semibold mb-3 text-white",children:"Your Position"}),e.jsxs("div",{className:"space-y-2 text-sm",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Units"}),e.jsx("span",{className:"font-mono text-white",children:l.toFixed(2)})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Avg. Rate"}),e.jsx("span",{className:"font-mono text-white",children:U(parseFloat(o.averagePrice),d)})]}),e.jsxs("div",{className:"flex justify-between border-t border-slate-700/30 pt-2",children:[e.jsx("span",{className:"text-slate-400",children:"Unrealized P&L"}),e.jsxs("span",{className:x("font-mono font-semibold",i-parseFloat(o.averagePrice)>=0?"text-emerald-400":"text-red-400"),children:[(i-parseFloat(o.averagePrice))*l>=0?"+":"",((i-parseFloat(o.averagePrice))*l).toLocaleString("en-US",{minimumFractionDigits:2})," ",d]})]})]})]}),P&&e.jsx("div",{className:"bg-[#0f1729]/80 backdrop-blur-sm rounded-xl p-4 border border-slate-700/20",children:e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-slate-500 text-sm",children:"Available Balance"}),e.jsxs("span",{className:"font-mono font-semibold text-white","data-testid":"text-balance",children:["$",N.toLocaleString("en-US",{minimumFractionDigits:2})]})]})})]})]})]})})}export{ie as default};

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.