PageSourceSearch

https://harbor-os.com/assets/AdminTokenManagement-3bkhXsfu.js

js harbor-os.com collected 2026-09-24 14:45:52 UTC 5,231 bytes, 1 lines download raw bytes

1import{r as g,g as N,j as e,E as c,bC as f,a0 as m,e as b,G as v,L as y,aL as C}from"./vendor-BeA4siBz.js";import{C as r,d as n,a as w,b as L,c as k,I as S,g as I,B as A}from"./index-C2NQ_9nj.js";import{A as T}from"./AdminLayout-zgeex3qo.js";import"./harbor-shoppers-logo-BwiOLETu.js";import"./textarea-BzoSp81z.js";function E(){const[t,h]=g.useState(""),{data:l=[],isLoading:u}=N({queryKey:["/api/dcc/admin/wallets"]}),d=l.filter(s=>{var x,o;if(!t)return!0;const a=t.toLowerCase();return((x=s.email)==null?void 0:x.toLowerCase().includes(a))||((o=s.fullName)==null?void 0:o.toLowerCase().includes(a))||String(s.userId).includes(a)}),j=l.reduce((s,a)=>s+parseFloat(a.balance||"0"),0),p=l.filter(s=>parseFloat(s.balance||"0")>0).length,i=[...d].sort((s,a)=>parseFloat(a.balance)-parseFloat(s.balance));return e.jsx(T,{children:e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(c,{className:"h-6 w-6 text-amber-500"}),"Token Management"]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"View and manage user token balances. Credit or debit tokens and sync changes with Harbor OS."})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsx(r,{children:e.jsx(n,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-amber-100 dark:bg-amber-900/30 rounded-lg",children:e.jsx(c,{className:"h-5 w-5 text-amber-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Total Tokens in Circulation"}),e.jsx("p",{className:"text-2xl font-bold",children:j.toLocaleString()})]})]})})}),e.jsx(r,{children:e.jsx(n,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-blue-100 dark:bg-blue-900/30 rounded-lg",children:e.jsx(f,{className:"h-5 w-5 text-blue-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Wallets with Balance"}),e.jsx("p",{className:"text-2xl font-bold",children:p})]})]})})}),e.jsx(r,{children:e.jsx(n,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-green-100 dark:bg-green-900/30 rounded-lg",children:e.jsx(m,{className:"h-5 w-5 text-green-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Total Wallets"}),e.jsx("p",{className:"text-2xl font-bold",children:l.length})]})]})})})]}),e.jsxs(r,{children:[e.jsxs(w,{children:[e.jsxs(L,{className:"flex items-center gap-2",children:[e.jsx(m,{className:"h-5 w-5"}),"User Wallets"]}),e.jsx(k,{children:"Search by name, email, or user ID. Click a user to manage their tokens."})]}),e.jsxs(n,{children:[e.jsxs("div",{className:"flex items-center gap-2 mb-4",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(b,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(S,{placeholder:"Search by name, email, or user ID...",value:t,onChange:s=>h(s.target.value),className:"pl-9"})]}),e.jsxs(I,{variant:"outline",className:"whitespace-nowrap",children:[d.length," result",d.length!==1?"s":""]})]}),u?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(v,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):i.length===0?e.jsx("div",{className:"text-center py-12 text-muted-foreground",children:t?"No wallets match your search":"No wallets found"}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b bg-muted/50",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium",children:"User"}),e.jsx("th",{className:"text-right px-4 py-3 font-medium",children:"Balance"}),e.jsx("th",{className:"text-right px-4 py-3 font-medium",children:"Last Updated"}),e.jsx("th",{className:"text-right px-4 py-3 font-medium",children:"Actions"})]})}),e.jsx("tbody",{children:i.map(s=>{const a=parseFloat(s.balance);return e.jsxs("tr",{className:"border-b last:border-0 hover:bg-muted/30 transition-colors",children:[e.jsx("td",{className:"px-4 py-3",children:e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:s.fullName||"—"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s.email}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["ID: ",s.userId]})]})}),e.jsx("td",{className:"px-4 py-3 text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-1",children:[e.jsx(c,{className:"h-4 w-4 text-amber-500"}),e.jsx("span",{className:`font-mono font-bold ${a>0?"text-green-600":"text-muted-foreground"}
1`,children:a.toLocaleString()})]})}),e.jsx("td",{className:"px-4 py-3 text-right text-muted-foreground text-xs",children:s.updatedAt?new Date(s.updatedAt).toLocaleDateString():"—"}),e.jsx("td",{className:"px-4 py-3 text-right",children:e.jsx(y,{href:`/admin/user-financial/${s.userId}`,children:e.jsxs(A,{size:"sm",variant:"outline",className:"gap-1",children:["Manage ",e.jsx(C,{className:"h-3 w-3"})]})})})]},s.id)})})]})})]})]})]})})}export{E 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.