PageSourceSearch

https://nguyentudo.me/assets/AdminSettingsPage-u8ixYaKI.js

js nguyentudo.me collected 2026-10-04 14:32:28 UTC 8,361 bytes, 1 lines download raw bytes

1import{aJ as P,r as N,W as f,aK as p,j as e,O as E,I as o,Z as H,x as I,y as R,h as y,z,F as O,G as U,s as l,n as u}from"./index-CyZ-pQAp.js";import{T as w,a as _,b as d,c,d as q,e as t}from"./table-CMi6u7Ia.js";import{S as V}from"./star-DNt5yvWY.js";import{P as G}from"./plus-BJk86tdF.js";import{P as Z}from"./pencil-CoCBYRGM.js";import{T as A}from"./trash-2-BbakTVuS.js";function se(){const m=P(),[K,g]=N.useState(!1),[j,C]=N.useState(null),[n,x]=N.useState({key:"",name:"",description:"",icon_url:""}),{data:h,isLoading:T}=f({queryKey:["admin-badges"],queryFn:async()=>{const{data:s}=await l.from("badges").select("*").order("created_at",{ascending:!1});return s||[]}}),k=p({mutationFn:async()=>{const s={key:n.key,name:n.name,description:n.description||null,icon_url:n.icon_url||null};if(j){const{error:a}=await l.from("badges").update(s).eq("id",j.id);if(a)throw a}else{const{error:a}=await l.from("badges").insert(s);if(a)throw a}},onSuccess:()=>{m.invalidateQueries({queryKey:["admin-badges"]}),u.success("Đã lưu"),g(!1)},onError:()=>u.error("Lỗi lưu")}),S=p({mutationFn:async s=>{const{error:a}=await l.from("badges").delete().eq("id",s);if(a)throw a},onSuccess:()=>{m.invalidateQueries({queryKey:["admin-badges"]}),u.success("Đã xoá")}}),{data:b,isLoading:F}=f({queryKey:["admin-levels"],queryFn:async()=>{const{data:s}=await l.from("level_thresholds").select("*").order("level");return s||[]}}),L=p({mutationFn:async({level:s,points_required:a,label:i})=>{const{error:B}=await l.from("level_thresholds").update({points_required:a,label:i}).eq("level",s);if(B)throw B},onSuccess:()=>{m.invalidateQueries({queryKey:["admin-levels"]}),u.success("Đã cập nhật level")}}),{data:v,isLoading:Q}=f({queryKey:["admin-point-settings"],queryFn:async()=>{const{data:s}=await l.from("point_settings").select("*").order("action");return s||[]}}),D=p({mutationFn:async({action:s,points:a})=>{const{error:i}=await l.from("point_settings").update({points:a}).eq("action",s);if(i)throw i},onSuccess:()=>{m.invalidateQueries({queryKey:["admin-point-settings"]}),u.success("Đã cập nhật")}}),{data:r}=f({queryKey:["app-settings-discord-admin"],queryFn:async()=>{const{data:s}=await l.from("sepay_settings").select("id, default_discord_url").limit(1).maybeSingle();return s}}),M=p({mutationFn:async s=>{if(r!=null&&r.id){const{error:a}=await l.from("sepay_settings").update({default_discord_url:s||null}).eq("id",r.id);if(a)throw a}else{const{error:a}=await l.from("sepay_settings").insert({default_discord_url:s||null});if(a)throw a}},onSuccess:()=>{m.invalidateQueries({queryKey:["app-settings-discord-admin"]}),m.invalidateQueries({queryKey:["app-settings-discord"]}),u.success("Đã lưu Discord URL")},onError:()=>u.error("Lỗi lưu")});return e.jsxs("div",{className:"max-w-5xl mx-auto space-y-8",children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Cài đặt"}),e.jsxs("div",{className:"rounded-xl bg-card border border-border p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{className:"h-5 w-5 text-primary"}),e.jsx("h2",{className:"font-semibold",children:"Google Meet URL mặc định"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Link Google Meet này sẽ tự động điền khi tạo buổi live mới (dùng cho chữa bài 1-1)."}),e.jsx(o,{placeholder:"https://meet.google.com/abc-defg-hij",defaultValue:(r==null?void 0:r.default_discord_url)||"",onBlur:s=>{const a=s.target.value.trim();a!==((r==null?void 0:r.default_discord_url)||"")&&M.mutate(a)}},(r==null?void 0:r.default_discord_url)||"empty")]}),e.jsxs("div",{className:"rounded-xl bg-card border border-border overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 p-4 pb-2",children:[e.jsx(H,{className:"h-5 w-5 text-primary"}),e.jsx("h2",{className:"font-semibold",children:"Cấu hình điểm"})]}),e.jsx("p",{className:"px-4 text-xs text-muted-foreground mb-2",children:"Số điểm nhận được cho mỗi hành động"}),e.jsxs(w,{children:[e.jsx(_,{children:e.jsxs(d,{children:[e.jsx(c,{children:"Hành động"}),e.jsx(c,{children:"Mô tả"}),e.jsx(c,{className:"w-[120px]",children:"Điểm"})]})}),e.jsxs(q,{children:[Q&&e.jsx(d,{children:e.jsx(t,{colSpan:3,className:"text-center text-muted-foreground",children:"Đang tải..."})}),v==null?void 0:v.map(s=>e.jsxs(d,{children:[e.jsx(t,{className:"font-mono text-sm",children:s.action}),e.jsx(t,{className:"text-sm text-muted-foreground",children:s.label||"—"}),e.jsx(t,{children:e.jsx(o,{type:"number",className:"w-20 h-8 text-sm",defaultValue:s.points,onBlur:a=>{const i=parseInt(a.target.value);!isNaN(i)&&i!==s.points&&D.mutate({action:s.action,points:i})}})})]},s.action))]})]})]}),e.jsxs("div",{className:"rounded-xl bg-card border border-border overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 p-4 pb-2",children:[e.jsx(V,{className:"h-5 w-5 text-primary"}),e.jsx("h2",{className:"font-semibold",children:"Cấu hình Level"})]}),e.jsx("p",{className:"px-4 text-xs text-muted-foreground mb-2",children:"Số điểm cần đạt để lên từng level"}),e.jsxs(w,{children:[e.jsx(_,{children:e.jsxs(d,{children:[e.jsx(c,{className:"w-[80px]",children:"Level"}),e.jsx(c,{children:"Tên"}),e.jsx(c,{className:"w-[140px]",children:"Điểm yêu cầu"})]})}),e.jsxs(q,{children:[F&&e.jsx(d,{children:e.jsx(t,{colSpan:3,className:"text-center text-muted-foreground",children:"Đang tải..."})}),b==null?void 0:b.map(s=>e.jsxs(d,{children:[e.jsxs(t,{className:"font-bold text-primary",children:["Lv.",s.level]}),e.jsx(t,{children:e.jsx(o,{className:"h-8 text-sm max-w-[200px]",defaultValue:s.label||"",onBlur:a=>{a.target.value!==(s.label||"")&&L.mutate({level:s.level,points_required:s.points_required,label:a.target.value})}})}),e.jsx(t,{children:e.jsx(o,{type:"number",className:"w-28 h-8 text-sm",defaultValue:s.points_required,onBlur:a=>{const i=parseInt(a.target.value);!isNaN(i)&&i!==s.points_required&&L.mutate({level:s.level,points_required:i,label:s.label||""})}})})]},s.level))]})]})]}),e.jsxs("div",{className:"rounded-xl bg-card border border-border overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 pb-2",children:[e.jsx("h2",{className:"font-semibold",children:"Quản lý Badges"}),e.jsxs(I,{open:K,onOpenChange:g,children:[e.jsx(R,{asChild:!0,children:e.jsxs(y,{size:"sm",onClick:()=>{C(null),x({key:"",name:"",description:"",icon_url:""}),g(!0)},children:[e.jsx(G,{className:"h-4 w-4 mr-1"}),"Thêm badge"]})}),e.jsxs(z,{children:[e.jsx(O,{children:e.jsx(U,{children:j?"Sửa badge":"Thêm badge mới"})}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(o,{placeholder:"Key (vd: early_bird)",value:n.key,onChange:s=>x({...n,key:s.target.value})}),e.jsx(o,{placeholder:"Tên hiển thị",value:n.name,onChange:s=>x({...n,name:s.target.value})}),e.jsx(o,{placeholder:"Mô tả",value:n.description,onChange:s=>x({...n,description:s.target.value})}),e.jsx(o,{placeholder:"Icon URL (tuỳ chọn)",value:n.icon_url,onChange:s=>x({...n,icon_url:s.target.value})}),e.jsx(y,{onClick:()=>k.mutate(),disabled:!n.key||!n.name||k.isPending,className:"w-full",children:j?"Cập nhật":"Thêm"})]})]})]})]}),e.jsxs(w,{children:[e.jsx(_,{children:e.jsxs(d,{children:[e.jsx(c,{children:"Key"}),e.jsx(c,{children:"Tên"}),e.jsx(c,{children:"Mô tả"}),e.jsx(c,{className:"w-[100px]",children:"Hành động"})]})}),e.jsxs(q,{children:[T&&e.jsx(d,{children:e.jsx(t,{colSpan:4,className:"text-center text-muted-foreground",children:"Đang tải..."})}),h==null?void 0:h.map(s=>e.jsxs(d,{children:[e.jsx(t,{className:"font-mono text-sm",children:s.key}),e.jsx(t,{className:"font-medium",children:s.name}),e.jsx(t,{className:"text-sm text-muted-foreground",children:s.description||"—"}),e.jsxs(t,{className:"flex gap-1",children:[e.jsx(y,{variant:"ghost",size:"icon",onClick:()=>{C(s),x({key:s.key,name:s.name,description:s.description||"",icon_url:s.icon_url||""}),g(!0)},children:e.jsx(Z,{className:"h-4 w-4"})}),e.jsx(y,{variant:"ghost",size:"icon",onClick:()=>S.mutate(s.id),children:e.jsx(A,{className:"h-4 w-4 text-destructive"})})]})]},s.id)),!T&&!(h!=null&&h.length)&&e.jsx(d,{children:e.jsx(t,{colSpan:4,className:"text-center text-muted-foreground",children:"Chưa có badge"})})]})]})]})]})}export{se 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.