2 lines
10 KiB
JavaScript
2 lines
10 KiB
JavaScript
import{r,j as e,e as xe}from"./react-vendor-CgzNJrV9.js";import{_ as fe,Z as pe,u as ue,a as he,F as je,b as g,c as N,d as y,e as b,I as C,f as w,o as ge,s as A}from"./form-BzHbu9bJ.js";import{c as l,b as F,u as Ne,B as m,a as h}from"./index-474mTIgd.js";import{B as ye}from"./badge-CsEfIQQ2.js";import{S as k}from"./spinner-DH1syOsQ.js";import{W as be,Y as we,Z as _,_ as ve,X as De,$ as z,a0 as B,a1 as S,a2 as Re,a3 as Te,a4 as Ce,a5 as E,a6 as H,a7 as O,a8 as L,a9 as P,aa as I,A as Ae,m as ke}from"./ui-vendor-CdH1UOKW.js";import{n as i}from"./notify-Zesh5czd.js";function Fe(a){return fe(pe,a)}const M=r.forwardRef(({className:a,...s},t)=>e.jsx("textarea",{className:l("flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",a),ref:t,...s}));M.displayName="Textarea";const Z=r.forwardRef(({className:a,...s},t)=>e.jsx("div",{className:"relative w-full overflow-auto",children:e.jsx("table",{ref:t,className:l("w-full caption-bottom text-sm",a),...s})}));Z.displayName="Table";const V=r.forwardRef(({className:a,...s},t)=>e.jsx("thead",{ref:t,className:l("[&_tr]:border-b",a),...s}));V.displayName="TableHeader";const W=r.forwardRef(({className:a,...s},t)=>e.jsx("tbody",{ref:t,className:l("[&_tr:last-child]:border-0",a),...s}));W.displayName="TableBody";const v=r.forwardRef(({className:a,...s},t)=>e.jsx("tr",{ref:t,className:l("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",a),...s}));v.displayName="TableRow";const d=r.forwardRef(({className:a,...s},t)=>e.jsx("th",{ref:t,className:l("h-10 px-3 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",a),...s}));d.displayName="TableHead";const c=r.forwardRef(({className:a,...s},t)=>e.jsx("td",{ref:t,className:l("p-3 align-middle [&:has([role=checkbox])]:pr-0",a),...s}));c.displayName="TableCell";const _e=be,ze=we,X=r.forwardRef(({className:a,...s},t)=>e.jsx(B,{ref:t,className:l("fixed inset-0 z-[110] bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",a),...s}));X.displayName=B.displayName;const Y=r.forwardRef(({className:a,children:s,...t},x)=>e.jsxs(ze,{children:[e.jsx(X,{}),e.jsxs(_,{ref:x,className:l("fixed left-[50%] top-[50%] z-[110] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",a),...t,children:[s,e.jsxs(ve,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[e.jsx(De,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:"关闭"})]})]})]}));Y.displayName=_.displayName;const $=({className:a,...s})=>e.jsx("div",{className:l("flex flex-col space-y-1.5 text-center sm:text-left",a),...s});$.displayName="DialogHeader";const q=({className:a,...s})=>e.jsx("div",{className:l("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",a),...s});q.displayName="DialogFooter";const G=r.forwardRef(({className:a,...s},t)=>e.jsx(z,{ref:t,className:l("text-lg font-semibold leading-none tracking-tight",a),...s}));G.displayName=z.displayName;const Be=r.forwardRef(({className:a,...s},t)=>e.jsx(S,{ref:t,className:l("text-sm text-muted-foreground",a),...s}));Be.displayName=S.displayName;const Se=Re,Ee=Te,He=Ce,J=r.forwardRef(({className:a,...s},t)=>e.jsx(I,{className:l("fixed inset-0 z-[110] bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",a),...s,ref:t}));J.displayName=I.displayName;const K=r.forwardRef(({className:a,...s},t)=>e.jsxs(He,{children:[e.jsx(J,{}),e.jsx(E,{ref:t,className:l("fixed left-[50%] top-[50%] z-[110] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",a),...s})]}));K.displayName=E.displayName;const Q=({className:a,...s})=>e.jsx("div",{className:l("flex flex-col space-y-2 text-center sm:text-left",a),...s});Q.displayName="AlertDialogHeader";const U=({className:a,...s})=>e.jsx("div",{className:l("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",a),...s});U.displayName="AlertDialogFooter";const ee=r.forwardRef(({className:a,...s},t)=>e.jsx(H,{ref:t,className:l("text-lg font-semibold",a),...s}));ee.displayName=H.displayName;const ae=r.forwardRef(({className:a,...s},t)=>e.jsx(O,{ref:t,className:l("text-sm text-muted-foreground",a),...s}));ae.displayName=O.displayName;const se=r.forwardRef(({className:a,...s},t)=>e.jsx(P,{ref:t,className:l(F(),a),...s}));se.displayName=P.displayName;const te=r.forwardRef(({className:a,...s},t)=>e.jsx(L,{ref:t,className:l(F({variant:"outline"}),"mt-2 sm:mt-0",a),...s}));te.displayName=L.displayName;const Oe=ge({name:A().min(1,"请输入名称").max(64),description:A().max(500).optional(),sort_order:Fe().min(0)});function Xe(){const a=xe(),{user:s,loading:t}=Ne(),[x,oe]=r.useState([]),[re,D]=r.useState(!0),[le,f]=r.useState(!1),[u,R]=r.useState(null),[ne,T]=r.useState(!1),n=ue({resolver:he(Oe),defaultValues:{name:"",description:"",sort_order:1}}),j=()=>{D(!0),h.boards().then(o=>oe(o.boards??[])).catch(o=>i.error(o.message)).finally(()=>D(!1))};r.useEffect(()=>{if(!t){if(!s){a("/login");return}if(s.role!=="admin"){a("/"),i.warning("需要管理员权限");return}j()}},[s,t,a]);const ie=()=>{R(null),n.reset({name:"",description:"",sort_order:x.length+1}),f(!0)},de=o=>{R(o),n.reset({name:o.name,description:o.description??"",sort_order:o.sort_order}),f(!0)},ce=async o=>{T(!0);try{u?(await h.updateBoard(u.id,o),i.success("板块已更新")):(await h.createBoard(o),i.success("板块已创建")),f(!1),j(),window.dispatchEvent(new Event("boards-refresh"))}catch(p){i.error(p instanceof Error?p.message:"操作失败")}finally{T(!1)}},me=async o=>{try{await h.deleteBoard(o),i.success("板块已删除"),j(),window.dispatchEvent(new Event("boards-refresh"))}catch(p){i.error(p instanceof Error?p.message:"删除失败")}};return t?e.jsx("div",{className:"flex justify-center py-16",children:e.jsx(k,{size:"lg"})}):!s||s.role!=="admin"?null:e.jsxs("div",{className:"page-wrap",children:[e.jsxs("div",{className:"page-inner-wide",children:[e.jsxs(m,{variant:"ghost",className:"mb-3",onClick:()=>a("/"),children:[e.jsx(Ae,{}),"返回"]}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:20},children:[e.jsxs("div",{children:[e.jsx("h1",{className:"page-title",children:"板块管理"}),e.jsx("p",{className:"page-desc",children:"创建、编辑或删除论坛板块,用户发帖前需先有板块"})]}),e.jsxs(m,{onClick:ie,children:[e.jsx(ke,{}),"新建板块"]})]}),e.jsx("div",{className:"section-card",style:{padding:0,overflow:"hidden"},children:re?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(k,{size:"lg"})}):e.jsxs(e.Fragment,{children:[e.jsxs(Z,{children:[e.jsx(V,{children:e.jsxs(v,{children:[e.jsx(d,{className:"w-[60px]",children:"ID"}),e.jsx(d,{children:"名称"}),e.jsx(d,{children:"简介"}),e.jsx(d,{className:"w-[70px]",children:"排序"}),e.jsx(d,{className:"w-[80px]",children:"帖子数"}),e.jsx(d,{className:"w-[160px]",children:"操作"})]})}),e.jsx(W,{children:x.map(o=>e.jsxs(v,{children:[e.jsx(c,{children:o.id}),e.jsx(c,{children:e.jsx("strong",{children:o.name})}),e.jsx(c,{className:"max-w-[200px] truncate",children:o.description}),e.jsx(c,{children:o.sort_order}),e.jsx(c,{children:e.jsx(ye,{variant:"secondary",children:o.post_count??0})}),e.jsx(c,{children:e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(m,{variant:"ghost",size:"sm",onClick:()=>de(o),children:"编辑"}),e.jsxs(Se,{children:[e.jsx(Ee,{asChild:!0,children:e.jsx(m,{variant:"ghost",size:"sm",className:"text-destructive hover:text-destructive",children:"删除"})}),e.jsxs(K,{children:[e.jsxs(Q,{children:[e.jsx(ee,{children:"确定删除该板块?"}),e.jsx(ae,{children:"删除后该板块下的帖子将无法通过板块筛选,此操作不可撤销。"})]}),e.jsxs(U,{children:[e.jsx(te,{children:"取消"}),e.jsx(se,{onClick:()=>me(o.id),children:"删除"})]})]})]})]})})]},o.id))})]}),x.length===0&&e.jsx("div",{className:"empty-state",children:e.jsx("p",{children:"还没有板块,点击右上角创建第一个"})})]})})]}),e.jsx(_e,{open:le,onOpenChange:f,children:e.jsxs(Y,{children:[e.jsx($,{children:e.jsx(G,{children:u?"编辑板块":"新建板块"})}),e.jsx(je,{...n,children:e.jsxs("form",{onSubmit:n.handleSubmit(ce),className:"space-y-4",children:[e.jsx(g,{control:n.control,name:"name",render:({field:o})=>e.jsxs(N,{children:[e.jsx(y,{children:"板块名称"}),e.jsx(b,{children:e.jsx(C,{maxLength:64,placeholder:"如:技术交流",...o})}),e.jsx(w,{})]})}),e.jsx(g,{control:n.control,name:"description",render:({field:o})=>e.jsxs(N,{children:[e.jsx(y,{children:"简介"}),e.jsx(b,{children:e.jsx(M,{rows:3,maxLength:500,placeholder:"板块说明(可选)",...o})}),e.jsx(w,{})]})}),e.jsx(g,{control:n.control,name:"sort_order",render:({field:o})=>e.jsxs(N,{children:[e.jsx(y,{children:"排序"}),e.jsx(b,{children:e.jsx(C,{type:"number",min:0,...o})}),e.jsx(w,{})]})}),e.jsxs(q,{children:[e.jsx(m,{type:"button",variant:"outline",onClick:()=>f(!1),children:"取消"}),e.jsx(m,{type:"submit",loading:ne,children:u?"保存":"创建"})]})]})})]})})]})}export{Xe as default};
|