PageSourceSearch

https://brimlab.lovable.app/assets/admin-Du3DAk2n.js

js brimlab.lovable.app collected 2026-10-03 05:35:46 UTC 129,132 bytes, 4 lines download raw bytes

1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/RichTextEditor-Tz_S8H9c.js","assets/index-w_xT3oYk.js","assets/index-D0yt-I2y.js","assets/index-C7yKKq-w.js","assets/index-DjwJWMwu.js","assets/index-BpfbCgbM.js","assets/index-Cot13XHP.js","assets/dialog-CBWYY7ox.js","assets/signup-whitelist.functions-DSyP_HPg.js","assets/news-B4XztX81.js","assets/NewsBody-CHVz0NZs.js","assets/AiImportDialog-BbByENi_.js","assets/AiProviderPanel-BsmvP-rU.js","assets/BookingAnalyticsPanel-OxrnFnZi.js","assets/AiInsightCard-CALumcE5.js","assets/BillingAnalyticsPanel-CHtsyqXw.js"])))=>i.map(i=>d[i]);
2import{c as ne,q as Y,d as k,B as R,C as M,D as F,r as o,h as te,t as y,j as e,u as je,i as X,k as Ze,E as Ye,F as Je,G as Xe,H as he,I as Pe,_ as ce}from"./index-w_xT3oYk.js";import{u as de,c as Le}from"./signup-whitelist.functions-DSyP_HPg.js";import{f as Ee,e as qe,h as Ae,j as Te,i as et,E as $e,I as Ke,a as Ie,b as tt,c as st,o as at,s as Oe,C as ge,u as He,D as rt,k as nt,l as ot,m as it,n as dt,p as lt}from"./dialog-CBWYY7ox.js";import{E as xe,f as ct}from"./news-B4XztX81.js";import{N as mt}from"./NewsBody-CHVz0NZs.js";const ut=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],xt=ne("pencil",ut);const pt=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],ht=ne("plus",pt);const gt=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],bt=ne("save",gt);const ft=[["path",{d:"M14 17H5",key:"gfn3mx"}],["path",{d:"M19 7h-9",key:"6i9tg"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}],["circle",{cx:"7",cy:"7",r:"3",key:"dfmy0x"}]],yt=ne("settings-2",ft);const vt=[["path",{d:"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",key:"1s2grr"}],["path",{d:"M20 2v4",key:"1rf3ol"}
2],["path",{d:"M22 4h-4",key:"gwowj6"}],["circle",{cx:"4",cy:"20",r:"2",key:"6kqj1y"}]],jt=ne("sparkles",vt);const Nt=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],wt=ne("trash-2",Nt);const _t=[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]],kt=ne("upload",_t),me=30*1e3,I={rooms:["admin","rooms"],roomOptions:["admin","room-options"],bookings:t=>["admin","bookings",t],blocks:["admin","blocks"],creditPools:["admin","credit-pools"],creditGrants:["admin","credit-grants"],invoices:["admin","invoices"],unbilled:t=>["admin","unbilled",t],contacts:["admin","contacts"],invoiceExtras:t=>["invoice-extras",t],invoiceBills:t=>["invoice-bills",t],analytics:(t,s)=>["admin","analytics",t,s],aiInsight:(t,s,r)=>["admin","analytics-ai",t,s,r]},St=t=>Y({queryKey:I.rooms,staleTime:me,queryFn:async()=>await t({})??[]}),Ct=()=>Y({queryKey:I.roomOptions,staleTime:300*1e3,queryFn:async()=>{const{data:t,error:s}=await k.from("rooms").select("id,code").order("sort_order");if(s)throw s;return t??[]}});async function Re(t,s){const r=Array.from(new Set(t.map(l=>l.user_id)));if(!r.length)return t;const n=await k.from("profiles").select(`id,${s}`).in("id",r),a=new Map((n.data??[]).map(l=>[l.id,l]));return t.forEach(l=>{l.profiles=a.get(l.user_id)??null}),t}const Dt=t=>Y({queryKey:I.bookings(t),staleTime:me,queryFn:async()=>{let s=k.from("bookings").select("id,room_id,user_id,start_at,end_at,status,topic,contact_name,contact_phone,rooms(code),bills(amount_hkd,status)").order("start_at",{ascending:!1}).limit(200);const r=new Date().toISOString(),n=new Date;n.setHours(0,0,0,0);const a=new Date;a.setHours(23,59,59,999),t==="upcoming"?s=s.gte("end_at",r).neq("status","cancelled"):t==="today"?s=s.gte("start_at",n.toISOString()).lte("start_at",a.toISOString()):t==="cancelled"&&(s=s.eq("status","cancelled"));const{data:l,error:m}=await s;if(m)throw m;return Re(l??[],"full_name,company_name,email")}}),Pt=()=>Y({queryKey:I.blocks,staleTime:me,queryFn:async()=>{const{data:t,error:s}=await k.from("blocked_slots").select("id,room_id,start_at,end_at,reason,rooms(code)").gte("end_at",new Date().toISOString()).order("start_at");if(s)throw s;return t??[]}}),Et=()=>Y({queryKey:I.invoices,staleTime:me,queryFn:async()=>{const{data:t,error:s}=await k.from("invoices").select("id,invoice_no,user_id,period,period_start,period_end,total_hkd,status,issued_at,due_date,paid_at,payment_method,payment_ref,payment_note,user_reported_at,user_reported_note,admin_adjustments_note").order("period",{ascending:!1}).order("invoice_no",{ascending:!1}).limit(500);if(s)throw s;return Re(t??[],"email,full_name,company_name,phone,room_no")}}),qt=t=>Y({queryKey:I.unbilled(t),staleTime:me,queryFn:async()=>{const{data:s,error:r}=await k.from("bills").select("user_id,amount_hkd,amount_override_hkd,period,invoice_id,status").eq("period",t).is("invoice_id",null);if(r)throw r;const n=s??[],a=new Map;for(const m of n){if(m.status==="cancelled")continue;const u=a.get(m.user_id)??{user_id:m.user_id,period:t,total:0,email:"",full_name:null,company_name:null};u.total+=m.amount_override_hkd??m.amount_hkd,a.set(m.user_id,u)}const l=Array.from(a.keys());if(l.length){const{data:m}=await k.from("profiles").select("id,email,full_name,company_name").in("id",l);for(const u of m??[]){const i=a.get(u.id);i&&(i.email=u.email,i.full_name=u.full_name,i.company_name=u.company_name)}}return Array.from(a.values()).filter(m=>m.total>0).sort((m,u)=>u.total-m.total)}}),At=R({method:"POST"}).middleware([M]).handler(F("2db9014fbc21af22c82f7e3f0467aea3cd8ba4b72a7988781bd3de932f9c6296")),Ne=R({method:"POST"}).middleware([M]).handler(F("7eb970d8def6b5dfd29fa4a6447f8870ec1f00f3b8c3d71be5edf176f296bd62")),Tt=R({method:"POST"}).middleware([M]).handler(F("abe8fc2ed6d5a8b2732973ed05334195ae6f770a67ba22e37d607babf0957ed8")),$t=R({method:"POST"}
2).middleware([M]).handler(F("6518d8b34ac7986c27e186d171a10d00e4f6ad03193852e6e438081f06c6e6fc")),Kt=R({method:"POST"}).middleware([M]).handler(F("b8c90a17a8c4424407e9a85124d704a57f825ef1e61d68f47ddf3ac80aee7014")),It=R({method:"POST"}).middleware([M]).handler(F("d7eaebb9fccb0b48e6e5310656c0b6647dae8b33e682966ee2dfdecdfe768992")),Ot=R({method:"POST"}).middleware([M]).handler(F("3036f82c021d52423348982b86ed8491a9eb2643e77f566971577dc0d3bc892a")),Ht=R({method:"POST"}).middleware([M]).handler(F("5c4c7dd05b319e6c649a4ce4a87653fc3c36e1095baf1abcf5f4899cc646fd6f")),Rt=R({method:"POST"}).middleware([M]).handler(F("e8fc1b9030708c2c5f11ecf8463888800bbb22c485cfc22e31e969cd5fb24401")),Mt=R({method:"POST"}).middleware([M]).handler(F("fe0b8de937a0176043e4a93997d9c9019d94ef5b52db0ecb932ad76fde513275")),Ft=[{label:"打印費 Printing",unit:1},{label:"雜費 Misc",unit:0},{label:"文具 Stationery",unit:0}];function Bt({invoice:t,billTo:s,onClose:r,onIssued:n,L:a}){const[l,m]=o.useState([]),[u,i]=o.useState([]),[d,c]=o.useState({}),[g,x]=o.useState(t.admin_adjustments_note??""),[C,D]=o.useState(!0),[_,P]=o.useState(!1),A=te(),N=()=>{A.invalidateQueries({queryKey:I.invoices}),A.invalidateQueries({queryKey:I.invoiceBills(t.id)}),A.invalidateQueries({queryKey:I.invoiceExtras(t.id)})},[w,b]=o.useState(!1),[S,j]=o.useState(!1),[E,O]=o.useState(!1),[z,ae]=o.useState(null),B=t.status==="draft"||t.status==="pending_review",W=o.useCallback(async()=>{D(!0);const[f,h]=await Promise.all([k.from("bills").select("id,hours,amount_hkd,amount_override_hkd,status,admin_note,gross_amount_hkd,credit_minutes_used,credit_hkd_deducted,bookings(start_at,end_at,topic,status,rooms(code,name,hourly_price_hkd))").eq("invoice_id",t.id).order("id"),k.from("invoice_extra_items").select("id,label,description,quantity,unit_price_hkd,amount_hkd,sort_order").eq("invoice_id",t.id).order("sort_order").order("created_at")]);if(f.error||h.error){P(!0),D(!1),y.error(f.error?.message??h.error?.message??"Load failed");return}P(!1),m(f.data??[]),i(h.data??[]),D(!1)},[t.id]);o.useEffect(()=>{W()},[W]);const K=Ee(l,t.status),v=K.reduce((f,h)=>f+qe(h),0),T=u.reduce((f,h)=>f+(d[h.id]??h.amount_hkd),0),U=v+T,G=o.useCallback((f,h)=>{c($=>{if(h===null){if(!(f in $))return $;const V={...$};return delete V[f],V}return $[f]===h?$:{...$,[f]:h}})},[]);async function re(f,h,$){try{await It({data:{billId:f.id,override:h,note:$}}),W(),N()}catch(V){y.error(V?.message??"Error")}}async function p(){b(!0);try{await Mt({data:{invoiceId:t.id,note:g}}),y.success(a("已保存","已保存","Saved"))}catch(f){y.error(f?.message??"Error")}finally{b(!1)}}async function q(f){try{await Ot({data:{invoiceId:t.id,label:f?.label??a("新增條目","新增条目","New item"),description:"",quantity:1,unitPrice:f?.unit??0}}),W(),N()}catch(h){y.error(h?.message??"Error")}}async function L(f){try{await Ht({data:{id:f.id,label:f.label,description:f.description??"",quantity:Number(f.quantity)||0,unitPrice:Math.round(Number(f.unit_price_hkd)||0)}}),W(),N()}catch(h){y.error(h?.message??"Error")}}async function J(f){const h=u;i($=>$.filter(V=>V.id!==f)),c($=>{const V={...$};return delete V[f],V});try{await Rt({data:{id:f}}),y.success(a("已刪除","已删除","Deleted")),W(),N()}catch($){i(h),y.error($?.message??"Error")}}function ee(){const f=Te({invoice:{...t,total_hkd:U},bills:K,extras:u,profile:{full_name:s.name,email:s.email,phone:s.phone,company_name:s.company,room_no:s.room},adjustmentsNote:g,totalOverride:U});ae(f),O(!0)}async function H(){if(confirm(a("確認推送?推送後用戶可見,且不可再修改條目。","确认推送?推送后用户可见,且不可再修改条目。","Confirm push? After pushing, the user can see it and items cannot be edited."))){j(!0);try{await Ne({data:{invoiceId:t.id,dueDays:14}}),y.success(a("已推送","已推送","Pushed")),n()}catch(f){y.error(f?.message??"Error")}finally{j(!1)}}}const le=f=>new Date(f).toLocaleString("zh-HK",{timeZone:"Asia/Hong_Kong",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1});return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm flex items-center justify-center p-4",onClick:r,children:e.jsxs("div",{className:"w-full max-w-5xl max-h-[92vh] overflow-y-auto bg-background border border-border",onClick:f=>f.stopPropagation(),children:[e.jsxs("div",{className:"sticky top-0 bg-background border-b border-border px-6 py-4 flex items-center justify-between z-10",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"font-mono text-[10px] uppercase tracking-[0.3em] text-muted-foreground",children:[a("編輯帳單","编辑账单","Edit Invoice")," · ",t.period]}),e.jsx("h3",{className:"mt-1 text-xl font-extrabold tracking-tight font-mono",children:t.invoice_no}),e.jsxs("p",{className:"mt-0.5 text-xs text-muted-foreground",children:[s.name,s.company?` · ${s.company}`:""]})]}),e.jsxs("div",{className:"text-right",children:[e.jsx("div",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:"TOTAL"}),e.jsxs("div",{className:"text-2xl font-extrabold",children:["HKD ",U]}),!B&&e.jsx("div",{className:"mt-1 font-mono text-[9px] uppercase tracking-widest text-amber-600",children:a("已推送 · 唯讀","已推送 · 只读","Pushed · read-only")})]})]}),e.jsxs("section",{className:"px-6 py-4",children:[e.jsxs("div",{className:"flex items-baseline justify-between mb-2",children:[e.jsxs("div",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground",children:[a("會議室條目","会议室条目","Meeting-room items")," (",K.length,")"]}),e.jsxs("div",{className:"font-mono text-xs",children:["HKD ",v]})]}),C?e.jsx("div",{className:"text-sm text-muted-foreground py-4",children:"Loading…"}):e.jsxs("div",{className:"border border-border",children:[e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 border-b border-border font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:[e.jsx("div",{className:"col-span-2",children:a("日期","日期","Date")}),e.jsx("div",{className:"col-span-1",children:a("室","室","Room")}),e.jsx("div",{className:"col-span-2",children:a("主題","主题","Topic")}),e.jsx("div",{className:"col-span-1 text-right",children:a("時長","时长","Hrs")}),e.jsx("div",{className:"col-span-1 text-right",children:a("原價","原价","Orig")}),e.jsx("div",{className:"col-span-2 text-right",children:a("調整後","调整后","Adjusted")}),e.jsx("div",{className:"col-span-3",children:a("備註","备注","Admin note")})]}),e.jsxs("div",{className:"divide-y divide-border",children:[K.map(f=>e.jsx(zt,{row:f,editable:B,onSave:re,fmtDT:le,L:a},f.id)),_&&e.jsx("div",{className:"px-3 py-6 text-center text-sm text-destructive",children:a("載入失敗,請重試","载入失败,请重试","Failed to load — please retry")}),!_&&K.length===0&&e.jsx("div",{className:"px-3 py-6 text-center text-xs text-muted-foreground",children:a("無會議室條目","无会议室条目","No meeting-room items")})]})]})]}),e.jsxs("section",{className:"px-6 py-4 border-t border-border",children:[e.jsxs("div",{className:"flex items-baseline justify-between mb-2",children:[e.jsxs("div",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground",children:[a("附加條目","附加条目","Additional items")," (",u.length,")"]}),e.jsxs("div",{className:"font-mono text-xs",children:["HKD ",T]})]}),e.jsxs("div",{className:"border border-border",children:[e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 border-b border-border font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:[e.jsx("div",{className:"col-span-3",children:a("項目","项目","Item")}),e.jsx("div",{className:"col-span-3",children:a("說明","说明","Description")}),e.jsx("div",{className:"col-span-1 text-right",children:a("數量","数量","Qty")}),e.jsx("div",{className:"col-span-2 text-right",children:a("單價","单价","Unit HKD")}),e.jsx("div",{className:"col-span-2 text-right",children:a("小計","小计","Amount")}),e.jsx("div",{className:"col-span-1"})]}),e.jsxs("div",{className:"divide-y divide-border",children:[u.map(f=>e.jsx(Ut,{row:f,editable:B,onSave:L,onDelete:J,onDraftChange:G,L:a},f.id)),u.length===0&&e.jsx("div",{className:"px-3 py-6 text-center text-xs text-muted-foreground",children:a("尚無附加條目","尚无附加条目","No additional items yet")})]})]}),B&&e.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-2",children:[e.jsxs("button",{onClick:()=>q(),className:"h-8 px-3 border border-primary bg-primary text-primary-foreground text-[11px] font-bold uppercase tracking-widest",children:["+ ",a("新增條目","新增条目","Add item")]}),e.jsx("span",{className:"text-[10px] font-mono uppercase tracking-widest text-muted-foreground",children:a("快捷:","快捷:","Presets:")}),Ft.map(f=>e.jsx("button",{onClick:()=>q(f),className:"h-8 px-3 border border-border text-[11px] hover:bg-accent",children:f.label},f.label))]})]}),e.jsxs("section",{className:"px-6 py-4 border-t border-border",children:[e.jsx("div",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground mb-2",children:a("本期調整說明(顯示在 PDF)","本期调整说明(显示在 PDF)","Adjustment note (shown on PDF)")}),e.jsx("textarea",{value:g,onChange:f=>x(f.target.value),onBlur:B?p:void 0,disabled:!B,rows:3,placeholder:a("例如:本月贈送 1 小時使用時長 …","例如:本月赠送 1 小时使用时长 …","e.g. 1 free hour granted this month …"),className:"w-full px-3 py-2 border border-border bg-background text-sm disabled:opacity-60"}),w&&e.jsx("div",{className:"mt-1 text-[10px] text-muted-foreground",children:"Saving…"})]}),e.jsxs("div",{className:"sticky bottom-0 bg-background border-t border-border px-6 py-3 flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{className:"text-xs text-muted-foreground",children:[a("會議室","会议室","Rooms")," HKD ",v," · ",a("附加","附加","Extras")," HKD ",T," = ",e.jsxs("span",{className:"font-bold text-foreground",children:["HKD ",U]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:ee,className:"h-9 px-4 border border-border text-xs font-bold uppercase tracking-widest hover:bg-accent",children:a("預覽 PDF","预览 PDF","Preview PDF")}),B&&e.jsx("button",{onClick:H,disabled:S||_||U<=0,className:"h-9 px-4 border border-primary bg-primary text-primary-foreground text-xs font-bold uppercase tracking-widest disabled:opacity-50",children:S?a("推送中…","推送中…","Pushing…"):a("推送給用戶","推送给用户","Push to user")}),e.jsx("button",{onClick:r,className:"h-9 px-4 border border-border text-xs uppercase tracking-widest",children:a("關閉","关闭","Close")})]})]})]})}),e.jsx(Ae,{open:E,onOpenChange:O,payload:z})]})}function zt({row:t,editable:s,onSave:r,fmtDT:n,L:a}){const[l,m]=o.useState(t.amount_override_hkd==null?"":String(t.amount_override_hkd)),[u,i]=o.useState(t.admin_note??""),d=(l===""?null:Number(l))!==t.amount_override_hkd||u!==(t.admin_note??""),c=l===""?t.amount_hkd:Number(l);return e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 text-xs items-center",children:[e.jsx("div",{className:"col-span-2 font-mono",children:t.bookings?n(t.bookings.start_at):"—"}),e.jsx("div",{className:"col-span-1 font-mono",children:t.bookings?.rooms?.code??"—"}),e.jsx("div",{className:"col-span-2 truncate",children:t.bookings?.topic??"—"}),e.jsx("div",{className:"col-span-1 text-right font-mono",children:Number(t.hours).toFixed(2)}),e.jsx("div",{className:"col-span-1 text-right font-mono text-muted-foreground",children:t.amount_hkd}),e.jsxs("div",{className:"col-span-2 text-right",children:[e.jsx("input",{type:"number",value:l,disabled:!s,onChange:g=>m(g.target.value),placeholder:String(t.amount_hkd),className:`w-24 h-8 px-2 border bg-background text-right text-xs font-mono ${l!==""&&Number(l)!==t.amount_hkd?"border-primary":"border-border"} disabled:opacity-60`}),e.jsxs("div",{className:"mt-0.5 text-[9px] font-mono text-muted-foreground",children:["= HKD ",c]})]}),e.jsxs("div",{className:"col-span-3 flex gap-1",children:[e.jsx("input",{value:u,disabled:!s,onChange:g=>i(g.target.value),placeholder:a("備註…","备注…","note…"),className:"flex-1 h-8 px-2 border border-border bg-background text-xs disabled:opacity-60"}),s&&d&&e.jsx("button",{onClick:()=>r(t,l===""?null:Math.round(Number(l)),u),className:"h-8 px-2 border border-primary bg-primary text-primary-foreground text-[10px] font-bold uppercase",children:a("存","存","Save")})]})]})}function Ut({row:t,editable:s,onSave:r,onDelete:n,onDraftChange:a,L:l}
2){const[m,u]=o.useState(t.label),[i,d]=o.useState(t.description??""),[c,g]=o.useState(String(t.quantity)),[x,C]=o.useState(String(t.unit_price_hkd)),D=Math.round((Number(c)||0)*(Number(x)||0));o.useEffect(()=>{a(t.id,D===t.amount_hkd?null:D)},[D,t.id,t.amount_hkd,a]),o.useEffect(()=>()=>a(t.id,null),[t.id,a]);const _=m!==t.label||i!==(t.description??"")||Number(c)!==Number(t.quantity)||Number(x)!==t.unit_price_hkd;return e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 text-xs items-center",children:[e.jsx("input",{value:m,disabled:!s,onChange:P=>u(P.target.value),className:"col-span-3 h-8 px-2 border border-border bg-background text-xs disabled:opacity-60"}),e.jsx("input",{value:i,disabled:!s,onChange:P=>d(P.target.value),className:"col-span-3 h-8 px-2 border border-border bg-background text-xs disabled:opacity-60"}),e.jsx("input",{type:"number",value:c,disabled:!s,onChange:P=>g(P.target.value),className:"col-span-1 h-8 px-2 border border-border bg-background text-right text-xs font-mono disabled:opacity-60"}),e.jsx("input",{type:"number",value:x,disabled:!s,onChange:P=>C(P.target.value),className:"col-span-2 h-8 px-2 border border-border bg-background text-right text-xs font-mono disabled:opacity-60"}),e.jsxs("div",{className:"col-span-2 text-right font-mono",children:["HKD ",D]}),e.jsxs("div",{className:"col-span-1 flex justify-end gap-1",children:[s&&_&&e.jsx("button",{onClick:()=>r({...t,label:m,description:i,quantity:Number(c)||0,unit_price_hkd:Math.round(Number(x)||0),amount_hkd:D}),className:"h-8 px-2 border border-primary bg-primary text-primary-foreground text-[10px] font-bold uppercase",children:l("存","存","Save")}),s&&e.jsx("button",{onClick:()=>n(t.id),className:"h-8 px-2 border border-destructive/50 text-destructive text-[10px] uppercase hover:bg-destructive/10",children:"×"})]})]})}function Vt(){const{lang:t}=je(),s=(u,i,d)=>t==="en"?d:t==="zh-Hans"?i:u,{data:r=[],isLoading:n,refetch:a,isFetching:l}=X({queryKey:["admin","pdf-export-failures"],staleTime:60*1e3,queryFn:async()=>{const{data:u,error:i}=await k.from("pdf_export_failures").select("id,created_at,invoice_no,stage,message,user_agent").order("created_at",{ascending:!1}).limit(50);if(i)throw i;return u??[]}}),m=u=>new Date(u).toLocaleString(t==="en"?"en-US":"zh-HK",{timeZone:"Asia/Hong_Kong",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1});return e.jsxs("section",{className:"border border-border",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-border px-4 py-3",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"font-mono text-[11px] uppercase tracking-[0.25em] text-muted-foreground",children:s("PDF 匯出失敗紀錄","PDF 导出失败记录","PDF export failures")}),e.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:s("由用戶瀏覽器自動回報,最近 50 筆(HKT)。","由用户浏览器自动回报,最近 50 条(HKT)。","Reported automatically by user browsers, latest 50 (HKT).")})]}),e.jsx("button",{onClick:()=>a(),disabled:l,className:"h-8 px-3 border border-border text-[11px] font-bold uppercase tracking-widest hover:bg-accent disabled:opacity-50",children:s("重新整理","刷新","Refresh")})]}),n?e.jsx("p",{className:"px-4 py-6 text-sm text-muted-foreground",children:s("載入中…","加载中…","Loading…")}):r.length===0?e.jsx("p",{className:"px-4 py-6 text-sm text-muted-foreground",children:s("目前沒有失敗紀錄。","目前没有失败记录。","No failures recorded.")}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{className:"bg-muted/40",children:e.jsxs("tr",{className:"text-left font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:[e.jsx("th",{className:"px-4 py-2",children:s("時間","时间","Time")}),e.jsx("th",{className:"px-4 py-2",children:s("帳單","账单","Invoice")}),e.jsx("th",{className:"px-4 py-2",children:s("階段","阶段","Stage")}),e.jsx("th",{className:"px-4 py-2",children:s("訊息","信息","Message")})]})}),e.jsx("tbody",{children:r.map(u=>e.jsxs("tr",{className:"border-t border-border align-top",children:[e.jsx("td",{className:"px-4 py-2 whitespace-nowrap",children:m(u.created_at)}),e.jsx("td",{className:"px-4 py-2 whitespace-nowrap font-mono",children:u.invoice_no??"—"}),e.jsx("td",{className:"px-4 py-2 whitespace-nowrap font-mono uppercase",children:u.stage}),e.jsxs("td",{className:"px-4 py-2",children:[e.jsx("div",{className:"max-w-[520px] break-words",children:u.message}),u.user_agent&&e.jsx("div",{className:"mt-1 max-w-[520px] break-words text-[10px] text-muted-foreground",children:u.user_agent})]})]},u.id))})]})})]})}const we="grid grid-cols-[160px_180px_100px_110px_120px_150px_110px_180px] gap-3 px-4 py-2 whitespace-nowrap";function Qt(){const t=new Date,s=new Date(Date.UTC(t.getUTCFullYear(),t.getUTCMonth()-1,1));return`${s.getUTCFullYear()}
2-${String(s.getUTCMonth()+1).padStart(2,"0")}`}function Wt({L:t}){const{lang:s}=je(),[r,n]=o.useState("pending_review"),[a,l]=o.useState(""),[m,u]=o.useState(""),[i,d]=o.useState(""),[c,g]=o.useState(null),[x,C]=o.useState(null),[D,_]=o.useState(Qt()),[P,A]=o.useState(!1),[N,w]=o.useState(null),b=te(),{data:S=[],isLoading:j}=X(Et()),{data:E=[]}=X(qt(D)),O=()=>b.invalidateQueries({queryKey:I.invoices}),z=p=>{O(),b.invalidateQueries({queryKey:I.invoiceBills(p)}),b.invalidateQueries({queryKey:I.invoiceExtras(p)})},ae=p=>b.invalidateQueries({queryKey:I.unbilled(p)});async function B(){if(confirm(t(`為週期 ${D} 生成「待處理」帳單?(需管理員確認後推送)`,`为周期 ${D} 生成「待处理」账单?(需管理员确认后推送)`,`Generate pending invoices for period ${D}? (requires admin confirmation to push)`))){A(!0);try{const p=await At({data:{period:D}});y.success(t(`已生成 ${p.count} 份待處理帳單`,`已生成 ${p.count} 份待处理账单`,`Generated ${p.count} pending invoice(s)`)),O(),ae(D)}catch(p){y.error(p?.message??"Error")}finally{A(!1)}}}async function W(p){if(confirm(t(`確認推送帳單 ${p.invoice_no} 給 ${p.profiles?.full_name??p.profiles?.email??""}?推送後用戶可見。`,`确认推送账单 ${p.invoice_no} 给 ${p.profiles?.full_name??p.profiles?.email??""}?推送后用户可见。`,`Confirm & push invoice ${p.invoice_no} to ${p.profiles?.full_name??p.profiles?.email??""}? User will see it once pushed.`))){w(p.id);try{await Ne({data:{invoiceId:p.id,dueDays:14}}),y.success(t("已推送","已推送","Pushed")),O()}catch(q){y.error(q?.message??"Error")}finally{w(null)}}}const K=o.useMemo(()=>{const p=i.trim().toLowerCase();return S.filter(q=>{if(r==="pending_review"){if(!(q.status==="pending_review"||q.status==="draft"))return!1}else if(r!=="all"&&q.status!==r)return!1;return!(a&&q.period<a||m&&q.period>m||p&&![q.invoice_no,q.profiles?.company_name??"",q.profiles?.full_name??"",q.profiles?.email??""].join(" ").toLowerCase().includes(p))})},[S,r,a,m,i]);async function v(){const p=K.map(f=>f.id),[q,L]=await Promise.all([k.from("bills").select("id,invoice_id,hours,amount_hkd,amount_override_hkd,status,gross_amount_hkd,credit_minutes_used,credit_hkd_deducted,bookings(start_at,topic,rooms(code,hourly_price_hkd))").in("invoice_id",p),k.from("invoice_extra_items").select("id,invoice_id,label,description,quantity,unit_price_hkd,amount_hkd").in("invoice_id",p)]);if(q.error)throw q.error;const J=new Map;for(const f of q.data??[]){const h=J.get(f.invoice_id)??[];h.push(f),J.set(f.invoice_id,h)}const ee=new Map;for(const f of L.data??[]){const h=ee.get(f.invoice_id)??[];h.push(f),ee.set(f.invoice_id,h)}const H=K.map(f=>({invoice:f,bills:J.get(f.id)??[],extras:ee.get(f.id)??[]})),le=t(`匯出時間 ${new Date().toLocaleString("zh-HK",{timeZone:"Asia/Hong_Kong"})} · 已套用畫面篩選(${K.length} / ${S.length})`,`导出时间 ${new Date().toLocaleString("zh-CN",{timeZone:"Asia/Hong_Kong"})} · 已应用界面筛选(${K.length} / ${S.length})`,`Exported ${new Date().toLocaleString("en-US",{timeZone:"Asia/Hong_Kong"})} · current filters applied (${K.length} / ${S.length})`);await Ie({fileName:Oe(t("帳單","账单","Invoices")),sheets:[tt(K,t,{admin:!0,note:le}),st(H,t),at(K,t)]})}const T=o.useMemo(()=>{let p=0,q=0,L=0;const J=new Date,ee=`${J.getFullYear()}-${String(J.getMonth()+1).padStart(2,"0")}`;for(const H of S)H.status==="issued"&&(p+=H.total_hkd),et(H.status,H.due_date)&&(q+=H.total_hkd),H.status==="paid"&&H.paid_at&&H.paid_at.startsWith(ee)&&(L+=H.total_hkd);return{outstanding:p,overdue:q,paidThisMonth:L}},[S]),U=p=>p==="pending_review"||p==="draft",G=S.filter(p=>U(p.status)).length,re=S.filter(p=>U(p.status)).reduce((p,q)=>p+q.total_hkd,0);return e.jsxs("div",{className:"space-y-6",children:[G>0&&e.jsxs("div",{className:"border-l-4 border-amber-500 bg-amber-500/10 px-4 py-3 flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-amber-700 dark:text-amber-400",children:t("待審批","待审批","Pending review")}),e.jsx("div",{className:"mt-1 text-sm text-foreground",children:t(`目前有 ${G} 張帳單待審批,合計 HKD ${re}。請核對會議室費用與附加費用後點擊「確認並推送」。`,`目前有 ${G} 张账单待审批,合计 HKD ${re}。请核对会议室费用与附加费用后点击「确认并推送」。`,`${G} invoice(s) awaiting review, total HKD ${re}. Verify meeting-room and additional charges, then Confirm & Push.`)})]}),r!=="pending_review"&&e.jsxs("button",{onClick:()=>n("pending_review"),className:"shrink-0 h-9 px-3 border border-amber-500 text-amber-700 dark:text-amber-400 text-[11px] font-bold uppercase tracking-widest hover:bg-amber-500/10",children:[t("跳轉","跳转","Jump")," →"]})]}),e.jsx("div",{className:"border border-border px-4 py-2 bg-amber-500/10 font-mono text-[10px] uppercase tracking-[0.2em] text-amber-700 dark:text-amber-400",children:t("每月 1 號 02:00 (HKT) 系統自動生成「待處理」帳單(含會議室費用及附加費用)。管理員需在「待處理」頁籤核對後點擊「確認並推送」,用戶才會看到帳單。","每月 1 号 02:00 (HKT) 系统自动生成「待处理」账单(含会议室费用及附加费用)。管理员需在「待处理」页签核对后点击「确认并推送」,用户才会看到账单。","On the 1st at 02:00 HKT, the system auto-generates pending invoices (meeting-room + extras). Admins must review under the Pending tab and click Confirm & Push before users can see them.")}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-3",children:[e.jsx(be,{label:t("待收款","待收款","Outstanding"),value:`HKD ${T.outstanding}`}),e.jsx(be,{label:t("逾期","逾期","Overdue"),value:`HKD ${T.overdue}
2`,tone:T.overdue>0?"danger":"default"}),e.jsx(be,{label:t("本月已收","本月已收","Paid (mo.)"),value:`HKD ${T.paidThisMonth}`}),e.jsxs("div",{className:"border border-border p-3 flex flex-col gap-2",children:[e.jsx("div",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("月結週期","月结周期","Period close")}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"month",value:D,onChange:p=>_(p.target.value),className:"flex-1 h-9 px-2 border border-border bg-background text-sm"}),e.jsxs("div",{className:"flex flex-col items-start",children:[e.jsx("button",{onClick:B,disabled:P||E.length===0,title:P?t("出帳中","出账中","Closing period"):E.length===0?t("本期沒有待出帳賬單","本期没有待出账账单","No pending bills for this period"):void 0,className:"h-9 px-3 border border-primary bg-primary text-primary-foreground text-[11px] font-bold uppercase tracking-widest disabled:opacity-40",children:t("出帳","出账","Close")}),(P||E.length===0)&&e.jsx("span",{className:"mt-1 font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:P?t("出帳中","出账中","Closing period"):t("本期沒有待出帳賬單","本期没有待出账账单","No pending bills for this period")})]})]})]})]}),E.length>0&&e.jsxs("section",{className:"border border-border",children:[e.jsxs("div",{className:"px-4 py-2 border-b border-border font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground",children:[t(`待出帳 · ${D}`,`待出账 · ${D}`,`Unbilled · ${D}`)," (",E.length,")"]}),e.jsx("div",{className:"divide-y divide-border",children:E.map(p=>e.jsxs("div",{className:"px-4 py-2 grid grid-cols-12 gap-2 text-xs items-center",children:[e.jsx("div",{className:"col-span-4 truncate",children:p.full_name??p.email}),e.jsx("div",{className:"col-span-4 truncate text-muted-foreground",children:p.company_name??"—"}),e.jsxs("div",{className:"col-span-4 text-right font-mono",children:["HKD ",p.total]})]},p.user_id))}),e.jsx("div",{className:"px-4 py-2 border-t border-border text-[11px] text-muted-foreground",children:t("出帳時,本期已有帳單的用戶會另開一張「補充帳單」,不會重複計費。","出账时,本期已有账单的用户会另开一张「补充账单」,不会重复计费。","On close, users who already have an invoice for this period get a supplementary invoice; nothing is billed twice.")})]}),e.jsx("div",{className:"flex gap-1 border-b border-border flex-wrap",children:["all","pending_review","issued","paid","void"].map(p=>e.jsxs("button",{onClick:()=>n(p),className:`px-4 py-2 font-mono text-[11px] uppercase tracking-widest border-b-2 -mb-px ${r===p?"border-primary text-foreground":"border-transparent text-muted-foreground hover:text-foreground"}`,children:[p==="all"?t("全部","全部","All"):p==="pending_review"?t("待處理","待处理","Pending"):p==="issued"?t("待付款","待付款","Unpaid"):p==="paid"?t("已付款","已付款","Paid"):t("作廢","作废","Void"),e.jsxs("span",{className:"ml-1 text-muted-foreground",children:["(",p==="all"?S.length:p==="pending_review"?S.filter(q=>q.status==="pending_review"||q.status==="draft").length:S.filter(q=>q.status===p).length,")"]})]},p))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("起始月","起始月","From")}),e.jsx("input",{type:"month",value:a,onChange:p=>l(p.target.value),className:"h-9 px-2 border border-border bg-background text-sm"})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("結束月","结束月","To")}),e.jsx("input",{type:"month",value:m,onChange:p=>u(p.target.value),className:"h-9 px-2 border border-border bg-background text-sm"})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("狀態","状态","Status")}),e.jsxs("select",{value:r,onChange:p=>n(p.target.value),className:"h-9 px-2 border border-border bg-background text-sm",children:[e.jsx("option",{value:"all",children:t("全部","全部","All")}),e.jsx("option",{value:"pending_review",children:t("待處理","待处理","Pending")}),e.jsx("option",{value:"issued",children:t("待付款","待付款","Unpaid")}),e.jsx("option",{value:"paid",children:t("已付款","已付款","Paid")}),e.jsx("option",{value:"void",children:t("作廢","作废","Void")})]})]}),e.jsxs("label",{className:"flex flex-col gap-1 flex-1 min-w-[220px]",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("搜尋","搜索","Search")}),e.jsx("input",{type:"search",value:i,onChange:p=>d(p.target.value),placeholder:t("機構 / 用戶 / Email / 編號","机构 / 用户 / Email / 编号","Org / user / email / no."),className:"h-9 px-2 border border-border bg-background text-sm w-full"})]}),e.jsx("button",{onClick:()=>{l(""),u(""),d(""),n("all")},className:"h-9 px-3 border border-border text-[11px] font-bold uppercase tracking-widest hover:bg-accent",children:t("清é
2™¤ç¯©é¸","清除筛选","Clear")}),e.jsx($e,{onExport:v,rowCount:K.length}),e.jsxs("div",{className:"h-9 flex items-center font-mono text-[11px] text-muted-foreground",children:[K.length," / ",S.length]})]}),j?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading…"}):e.jsx("div",{className:"border border-border overflow-x-auto",children:e.jsxs("div",{className:"min-w-[1180px]",children:[e.jsxs("div",{className:`${we} border-b border-border font-mono text-[10px] uppercase tracking-widest text-muted-foreground`,children:[e.jsx("div",{children:t("用戶","用户","User")}),e.jsx("div",{children:t("機構","机构","Organisation")}),e.jsx("div",{children:t("週期","周期","Period")}),e.jsx("div",{children:t("到期","到期","Due")}),e.jsx("div",{className:"text-right",children:t("金額","金额","Amount")}),e.jsx("div",{children:t("編號","编号","No.")}),e.jsx("div",{className:"text-center",children:t("狀態","状态","Status")}),e.jsx("div",{className:"text-right",children:t("操作","操作","Actions")})]}),e.jsxs("div",{className:"divide-y divide-border",children:[K.map(p=>e.jsxs("div",{className:`${we} text-xs items-center min-h-[44px] hover:bg-accent/40`,children:[e.jsx("div",{className:"truncate text-left",children:p.profiles?.full_name??p.profiles?.email??"—"}),e.jsx("div",{className:"truncate text-left text-muted-foreground",children:p.profiles?.company_name||"—"}),e.jsx("div",{className:"font-mono text-left",children:p.period}),e.jsx("div",{className:"font-mono text-left text-muted-foreground",children:p.due_date??"—"}),e.jsxs("div",{className:"text-right font-mono tabular-nums",children:["HKD ",p.total_hkd]}),e.jsx("button",{onClick:()=>g(p),className:"font-mono text-left truncate hover:underline",children:p.invoice_no}),e.jsxs("div",{className:"flex items-center justify-center gap-2",children:[p.user_reported_at&&!p.paid_at&&e.jsx("span",{className:"font-mono text-[9px] uppercase tracking-widest text-amber-600 dark:text-amber-400",title:t("已上報","已上报","Reported"),children:"●"}),e.jsx(Ke,{status:p.status,dueDate:p.due_date})]}),e.jsx("div",{className:"flex items-center justify-end gap-2",children:(p.status==="pending_review"||p.status==="draft")&&e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:()=>C(p),className:"h-7 px-2 border border-border text-[10px] font-bold uppercase tracking-widest hover:bg-accent shrink-0",children:t("編輯","编辑","Edit")}),e.jsx("button",{onClick:()=>W(p),disabled:N===p.id,className:"h-7 px-2 border border-primary bg-primary text-primary-foreground text-[10px] font-bold uppercase tracking-widest disabled:opacity-40 shrink-0",children:N===p.id?t("推送中…","推送中…","Pushing…"):t("確認並推送","确认并推送","Confirm & Push")})]})})]},p.id)),K.length===0&&e.jsx("div",{className:"px-4 py-6 text-center text-xs text-muted-foreground",children:t("沒有符合條件的帳單","没有符合条件的账单","No invoices match the filters")})]})]})}),c&&e.jsx(Gt,{invoice:c,lang:s,onClose:()=>g(null),onUpdated:()=>{O(),g(null)}}),x&&e.jsx(Bt,{invoice:{id:x.id,invoice_no:x.invoice_no,user_id:x.user_id,period:x.period,period_start:x.period_start,period_end:x.period_end,status:x.status,issued_at:x.issued_at,due_date:x.due_date,paid_at:x.paid_at,admin_adjustments_note:x.admin_adjustments_note},billTo:{name:x.profiles?.full_name||x.profiles?.email||"—",company:x.profiles?.company_name??null,email:x.profiles?.email??null,phone:x.profiles?.phone??null,room:x.profiles?.room_no??null},onClose:()=>{z(x.id),C(null)},onIssued:()=>{z(x.id),C(null)},L:t}),e.jsx(Vt,{})]})}function be({label:t,value:s,tone:r}){return e.jsxs("div",{className:`border p-3 ${r==="danger"?"border-destructive/50":"border-border"}`,children:[e.jsx("div",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t}),e.jsx("div",{className:`mt-1 text-lg font-extrabold ${r==="danger"?"text-destructive":""}`,children:s})]})}function Gt({invoice:t,lang:s,onClose:r,onUpdated:n}){const a=(v,T,U)=>s==="en"?U:s==="zh-Hans"?T:v,[l,m]=o.useState(!1),[u,i]=o.useState(!1),[d,c]=o.useState("bank_transfer"),[g,x]=o.use
2State(new Date().toISOString().slice(0,10)),[C,D]=o.useState(t.payment_ref??""),[_,P]=o.useState(t.payment_note??""),[A,N]=o.useState(!1),[w,b]=o.useState(!1),[S,j]=o.useState(null),{data:E=[]}=X({queryKey:[...I.invoiceBills(t.id),t.status],staleTime:60*1e3,queryFn:async()=>{const{data:v,error:T}=await k.from("bills").select("id,hours,amount_hkd,amount_override_hkd,status,gross_amount_hkd,credit_minutes_used,credit_hkd_deducted,bookings(start_at,end_at,topic,status,rooms(code,hourly_price_hkd))").eq("invoice_id",t.id);if(T)throw T;return Ee(v??[],t.status).map(G=>({...G,amount_hkd:qe(G)}))}}),{data:O=[]}=X({queryKey:I.invoiceExtras(t.id),staleTime:60*1e3,queryFn:async()=>{const{data:v,error:T}=await k.from("invoice_extra_items").select("id,label,description,quantity,unit_price_hkd,amount_hkd,sort_order").eq("invoice_id",t.id).order("sort_order").order("created_at");if(T)throw T;return v??[]}});async function z(){N(!0);try{const{data:v}=await k.from("profiles").select("email,full_name,phone,company_name,room_no").eq("id",t.user_id).maybeSingle();j(Te({invoice:t,bills:E,extras:O,profile:v,profileFallback:t.profiles??null,adjustmentsNote:t.admin_adjustments_note})),b(!0)}catch(v){y.error(v.message)}finally{N(!1)}}async function ae(){m(!0);try{await Ne({data:{invoiceId:t.id,dueDays:14}}),y.success(a("已發出","已发出","Issued")),n()}catch(v){y.error(v?.message??"Error")}finally{m(!1)}}async function B(){m(!0);try{await Tt({data:{invoiceId:t.id,method:d,paidAt:new Date(g+"T12:00:00+08:00").toISOString(),ref:C,note:_}}),y.success(a("已標記為已付","已标记为已付","Marked paid")),n()}catch(v){y.error(v?.message??"Error")}finally{m(!1)}}async function W(){const v=prompt(a("作廢原因?","作废原因?","Void reason?"));if(v){m(!0);try{await $t({data:{invoiceId:t.id,reason:v}}),y.success(a("已作廢","已作废","Voided")),n()}catch(T){y.error(T?.message??"Error")}finally{m(!1)}}}const K=v=>new Date(v).toLocaleString(s==="en"?"en-US":"zh-HK",{timeZone:"Asia/Hong_Kong",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1});return e.jsxs("div",{className:"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm flex items-center justify-center p-4",onClick:r,children:[e.jsxs("div",{className:"w-full max-w-3xl max-h-[90vh] overflow-y-auto bg-background border border-border",onClick:v=>v.stopPropagation(),children:[e.jsxs("div",{className:"border-b border-border px-6 py-4 flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("img",{src:Ze,alt:ge.name,className:"h-10 w-auto"}),e.jsxs("div",{children:[e.jsxs("p",{className:"font-mono text-[10px] uppercase tracking-[0.3em] text-muted-foreground",children:[t.profiles?.full_name??t.profiles?.email," · ",t.period]}),e.jsx("h3",{className:"mt-1 text-xl font-extrabold tracking-tight font-mono",children:t.invoice_no}),e.jsxs("p",{className:"mt-0.5 font-mono text-[9px] uppercase tracking-widest text-muted-foreground",children:[ge.name," · ",ge.nameLocal]})]})]}),e.jsxs("div",{className:"text-right",children:[e.jsxs("div",{className:"text-2xl font-extrabold",children:["HKD ",t.total_hkd]}),e.jsx("div",{className:"mt-1",children:e.jsx(Ke,{status:t.status,dueDate:t.due_date})})]})]}),t.user_reported_at&&e.jsxs("div",{className:"px-6 py-2 border-b border-border bg-amber-500/10 text-xs",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest mr-2",children:a("用戶已上報","用户已上报","User reported")}),K(t.user_reported_at)," · ",t.user_reported_note]}),e.jsxs("div",{className:"px-6 py-4 space-y-4",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground mb-2",children:[a("會議室費用","会议室费用","Meeting-room charges")," (",E.length,")"]}),e.jsxs("div",{className:"border border-border",children:[e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 border-b border-border font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:[e.jsx("div",{className:"col-span-4",children:a("日期","日期","Date")}),e.jsx("div",{className:"col-span-2",children:a("會議室","会议室","Room")}),e.jsx("div",{className:"col-span-4",children:a("主題","主题","Topic")}),e.jsx("div",{className:"col-span-1 text-right",children:a("時長(小時)","时长(小时)","Hours")}),e.jsx("div",{className:"col-span-1 text-right",children:a("金額","金额","Amount")})]}),e.jsxs("div",{className:"divide-y divide-border",children:[E.length===0&&e.jsx("div",{className:"px-3 py-3 text-xs text-muted-foreground",children:a("暫無會議室費用","暂无会议室费用","No meeting-room charges")}),E.map(v=>e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 text-xs",children:[e.jsx("div",{className:"col-span-4 font-mono",children:v.bookings?K(v.bookings.start_at):"—"}),e.jsx("div",{className:"col-span-2 font-mono",children:v.bookings?.rooms?.code??"—"}),e.jsx("div",{className:"col-span-4 truncate",children:v.bookings?.topic??"—"}),e.jsx("div",{className:"col-span-1 text-right font-mono",children:Number(v.hours).toFixed(2)}),e.jsxs("div",{className:"col-span-1 text-right font-mono",children:["HKD ",v.amount_hkd]})]},v.id))]}),e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 border-t border-border bg-accent/40 text-xs",children:[e.jsx("div",{className:"col-span-10 text-right font-mono uppercase tracking-widest text-muted-foreground",children:a("會議室小計","会议室小计","Room subtotal")}),e.jsxs("div",{className:"col-span-2 text-right font-mono font-bold",children:["HKD ",E.reduce((v,T)=>v+T.amount_hkd,0)]})]})]})]}),O.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground mb-2",children:[a("附加費用","附加费用","Additional charges")," (",O.length,")"]}),e.jsxs("div",{className:"border border-border",children:[e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 border-b border-border font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:[e.jsx("div",{className:"col-span-6",children:a("項目","项目","Item")}),e.jsx("div",{className:"col-span-2 text-right",children:a("數量","数量","Qty")}),e.jsx("div",{className:"col-span-2 text-right",children:a("單價","单价","Unit")}),e.jsx("div",{className:"col-span-2 text-right",children:a("金額","金额","Amount")})]}),e.jsx("div",{className:"divide-y divide-border",children:O.map(v=>e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 text-xs",children:[e.jsxs("div",{className:"col-span-6",children:[e.jsx("div",{className:"font-medium",children:v.label}),v.description&&e.jsx("div",{className:"text-muted-foreground text-[11px]",children:v.description})]}),e.jsx("div",{className:"col-span-2 text-right font-mono",children:Number(v.quantity).toFixed(2)}),e.jsxs("div",{className:"col-span-2 text-right font-mono",children:["HKD ",v.unit_price_hkd]}),e.jsxs("div",{className:"col-span-2 text-right font-mono",children:["HKD ",v.amount_hkd]})]},v.id))}),e.jsxs("div",{className:"grid grid-cols-12 gap-2 px-3 py-2 border-t border-border bg-accent/40 text-xs",children:[e.jsx("div",{className:"col-span-10 text-right font-mono uppercase tracking-widest text-muted-foreground",children:a("附加費小計","附加费小计","Extras subtotal")}),e.jsxs("div",{className:"col-span-2 text-right font-mono font-bold",children:["HKD ",O.reduce((v,T)=>v+T.amount_hkd,0)]})]})]})]}),t.admin_adjustments_note&&e.jsxs("div",{className:"border border-border bg-accent/20 px-3 py-2 text-xs",children:[e.jsx("div",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground mb-1",children:a("管理員備註","管理员备注","Admin note")}),e.jsx("div",{className:"whitespace-pre-wrap",children:t.admin_adjustments_note})]}),e.jsx("div",{className:"flex justify-end border-t border-border pt-3",children:e.jsxs("div",{className:"text-right",children:[e.jsx("div",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground",children:a("合計","合计","Grand total")}),e.jsxs("div",{className:"mt-1 text-2xl font-extrabold font-mono",children:["HKD ",t.total_hkd]})]})})]}),u&&e.jsxs("div",{className:"px-6 py-4 border-t border-border bg-accent/30 space-y-2",children:[e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsxs("label",{className:"text-xs",children:[e.jsx("span",{className:"block font-mono text-[10px] uppercase tracking-widest text-muted-foreground mb-1",children:a("方式","方式","Method")}),e.jsxs("select",{value:d,onChange:v=>c(v.target.value),className:"w-full h-9 px-2 border border-border bg-background text-sm",children:[e.jsx("option",{value:"bank_transfer",children:"Bank"}),e.jsx("option",{value:"fps",children:"FPS"}),e.jsx("option",{value:"cheque",children:"Cheque"}),e.jsx("option",{value:"cash",children:"Cash"}),e.jsx("option",{value:"other",children:"Other"})]})]}),e.jsxs("label",{className:"text-xs",children:[e.jsx("span",{className:"block font-mono text-[10px] uppercase tracking-widest text-muted-foreground mb-1",children:a("日期","日期","Date")}),e.jsx("input",{type:"date",value:g,onChange:v=>x(v.target.value),className:"w-full h-9 px-2 border border-border bg-background text-sm"})]}),e.jsxs("label",{className:"text-xs",children:[e.jsx("span",{className:"block font-mono text-[10px] uppercase tracking-widest text-muted-foreground mb-1",children:a("參考號","参考号","Ref")}),e.jsx("input",{value:C,onChange:v=>D(v.target.value),className:"w-full h-9 px-2 border border-border bg-background text-sm"})]})]}),e.jsxs("label",{className:"block text-xs",children:[e.jsx("span",{className:"block font-mono text-[10px] uppercase tracking-widest text-muted-foreground mb-1",children:a("備註","备注","Note")}
2),e.jsx("input",{value:_,onChange:v=>P(v.target.value),className:"w-full h-9 px-2 border border-border bg-background text-sm"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:B,disabled:l,className:"h-9 px-4 border border-primary bg-primary text-primary-foreground text-xs font-bold uppercase tracking-widest disabled:opacity-50",children:a("確認已付","确认已付","Confirm paid")}),e.jsx("button",{onClick:()=>i(!1),className:"h-9 px-4 border border-border text-xs uppercase tracking-widest",children:a("取消","取消","Cancel")})]})]}),e.jsxs("div",{className:"px-6 py-3 border-t border-border flex justify-between",children:[e.jsxs("div",{className:"flex gap-2",children:[(t.status==="pending_review"||t.status==="draft")&&e.jsx("button",{onClick:ae,disabled:l,className:"h-9 px-4 border border-primary bg-primary text-primary-foreground text-xs font-bold uppercase tracking-widest",children:t.status==="pending_review"?a("確認並推送","确认并推送","Confirm & Push"):a("發出帳單","发出账单","Issue")}),(t.status==="issued"||t.status==="draft"||t.status==="pending_review")&&!u&&e.jsx("button",{onClick:()=>i(!0),disabled:l,className:"h-9 px-4 border border-border text-xs font-bold uppercase tracking-widest hover:bg-accent",children:a("標記已付","标记已付","Mark paid")}),t.status!=="void"&&e.jsx("button",{onClick:W,disabled:l,className:"h-9 px-4 border border-destructive/50 text-destructive text-xs uppercase tracking-widest hover:bg-destructive/10",children:a("作廢","作废","Void")})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:z,disabled:A||E.length===0,className:"h-9 px-4 border border-border text-xs font-bold uppercase tracking-widest hover:bg-accent disabled:opacity-50",children:A?a("準備中…","准备中…","Preparing…"):a("預覽 / PDF","预览 / PDF","Preview / PDF")}),e.jsx("button",{onClick:r,className:"h-9 px-4 border border-border text-xs uppercase tracking-widest",children:a("關閉","关闭","Close")})]})]})]}),e.jsx("div",{onClick:v=>v.stopPropagation(),children:e.jsx(Ae,{open:w,onOpenChange:b,payload:S})})]})}function Zt({L:t}){const[s,r]=o.useState(""),[n,a]=o.useState(120),[l,m]=o.useState(""),[u,i]=o.useState(!1),d=te(),[c,g]=He({queries:[Y({queryKey:I.creditPools,staleTime:30*1e3,queryFn:async()=>{const{data:N,error:w}=await k.from("room_credit_pools").select("*").order("room_no");if(w)throw w;return N??[]}}),Y({queryKey:I.creditGrants,staleTime:30*1e3,queryFn:async()=>{const{data:N,error:w}=await k.from("room_credit_grants").select("id,room_no,minutes,note,created_at").order("created_at",{ascending:!1}).limit(30);if(w)throw w;return N??[]}})]}),x=c.data??[],C=g.data??[],D=c.isLoading||g.isLoading,_=()=>{d.invalidateQueries({queryKey:I.creditPools}),d.invalidateQueries({queryKey:I.creditGrants})};async function P(){if(!s.trim()||!n||n===0){y.error(t("請填寫房號與分鐘數","请填写房号与分钟数","Room and minutes required"));return}i(!0);try{await Kt({data:{roomNo:s.trim(),minutes:Number(n),note:l.trim()||""}}),y.success(t("已發放","已发放","Granted")),r(""),a(120),m(""),_()}catch(N){y.error(N?.message??"Error")}finally{i(!1)}}const A=N=>{const w=Math.floor(N/60),b=N%60;return b===0?`${w}h`:`${w}h ${b}m`};return e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"lg:col-span-1 border border-border p-5",children:[e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.2em] mb-4",children:t("發放免費額度","发放免费额度","Grant Credit")}),e.jsx("p",{className:"mb-4 text-xs text-muted-foreground leading-relaxed",children:t("額度按房號綁定,可跨月結轉直至用完。用戶預定會議室時,將按房間時薪自動抵扣,抵扣後金額計入月度帳單。","额度按房号绑定,可跨月结转直至用完。用户预定会议室时,将按房间时薪自动抵扣,抵扣后金额计入月度账单。","Credit is bound to room_no and carries over until spent. Auto-deducted per room hourly rate on booking; net amount is invoiced monthly.")}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("label",{className:"block text-xs",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("房號","房号","Room No.")}),e.jsx("input",{value:s,onChange:N=>r(N.target.value),placeholder:"e.g. 1701",className:"mt-1 w-full h-9 px-2 border border-border bg-background text-sm"})]}),e.jsxs("label",{className:"block text-xs",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("分鐘數(可負:扣減)","分钟数(可负:扣减)","Minutes (negative to deduct)")}),e.jsxs("div",{className:"mt-1 flex gap-1",children:[e.jsx("input",{type:"number",value:n,onChange:N=>a(N.target.value===""?"":Number(N.target.value)),className:"w-full h-9 px-2 border border-border bg-background text-sm"}),[60,120,180,300].map(N=>e.jsxs("button",{type:"button",onClick:()=>a(N),className:"h-9 px-2 border border-border font-mono text-[10px] hover:bg-accent",children:[N/60,"h"]},N))]})]}),e.jsxs("label",{className:"block text-xs",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("備註(可選)","备注(可选)","Note")}
2),e.jsx("input",{value:l,onChange:N=>m(N.target.value),className:"mt-1 w-full h-9 px-2 border border-border bg-background text-sm"})]}),e.jsx("button",{onClick:P,disabled:u,className:"w-full h-10 bg-primary text-primary-foreground font-mono text-xs uppercase tracking-[0.2em] disabled:opacity-40",children:t("發放","发放","Grant")})]})]}),e.jsxs("div",{className:"lg:col-span-2",children:[e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.2em] mb-4",children:t("額度池","额度池","Pools")}),D?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading…"}):x.length===0?e.jsx("div",{className:"border border-border px-6 py-10 text-center text-sm text-muted-foreground",children:t("尚無資料","尚无数据","No data")}):e.jsx("div",{className:"border border-border overflow-x-auto mb-6",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40",children:e.jsxs("tr",{className:"text-left font-mono text-[10px] uppercase tracking-[0.2em] text-muted-foreground",children:[e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("房號","房号","Room")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap text-right",children:t("已發放","已发放","Granted")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap text-right",children:t("已使用","已使用","Used")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap text-right",children:t("剩餘","剩余","Remaining")}),e.jsx("th",{className:"px-3 py-2",children:t("備註","备注","Note")})]})}),e.jsx("tbody",{className:"divide-y divide-border",children:x.map(N=>{const w=Math.max(0,N.total_granted_minutes-N.used_minutes);return e.jsxs("tr",{children:[e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:N.room_no}),e.jsx("td",{className:"px-3 py-2 text-right font-mono text-xs",children:A(N.total_granted_minutes)}),e.jsx("td",{className:"px-3 py-2 text-right font-mono text-xs",children:A(N.used_minutes)}),e.jsx("td",{className:`px-3 py-2 text-right font-mono text-xs ${w===0?"text-destructive":""}`,children:A(w)}),e.jsx("td",{className:"px-3 py-2 text-xs text-muted-foreground truncate max-w-[36ch]",children:N.notes??"—"})]},N.room_no)})})]})}),e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.2em] mb-3",children:t("最近發放流水","最近发放流水","Recent Grants")}),C.length===0?e.jsx("div",{className:"border border-border px-6 py-6 text-center text-xs text-muted-foreground",children:t("尚無記錄","尚无记录","No records")}):e.jsx("div",{className:"border border-border divide-y divide-border",children:C.map(N=>e.jsxs("div",{className:"px-4 py-2 grid grid-cols-12 gap-2 text-xs items-center",children:[e.jsx("div",{className:"col-span-3 font-mono",children:N.room_no}),e.jsxs("div",{className:`col-span-2 font-mono ${N.minutes<0?"text-destructive":""}`,children:[N.minutes>0?"+":"",A(N.minutes)]}),e.jsx("div",{className:"col-span-4 truncate text-muted-foreground",children:N.note??"—"}),e.jsx("div",{className:"col-span-3 font-mono text-[10px] text-right text-muted-foreground",children:new Date(N.created_at).toLocaleString("zh-HK",{timeZone:"Asia/Hong_Kong",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})})]},N.id))})]})]})}const ue={orgs:["admin","whitelist","orgs"],rooms:["admin","whitelist","rooms"],rules:["admin","whitelist","rules"],attempts:["admin","whitelist","attempts"]};function Yt({L:t}){const s=te(),[r,n,a,l]=He({queries:[Y({queryKey:ue.orgs,staleTime:3e4,queryFn:async()=>{const{data:g,error:x}=await k.from("organizations").select("id,name,status,note").order("name");if(x)throw x;return g??[]}}),Y({queryKey:ue.rooms,staleTime:3e4,queryFn:async()=>{const{data:g,error:x}=await k.from("org_rooms").select("id,org_id,room_no").order("room_no");if(x)throw x;return g??[]}}),Y({queryKey:ue.rules,staleTime:3e4,queryFn:async()=>{const{data:g,error:x}=await k.from("signup_rules").select("id,org_id,kind,effect,value,room_no,enabled,note,created_at").order("created_at",{ascending:!1});if(x)throw x;return g??[]}}),Y({queryKey:ue.attempts,staleTime:3e4,queryFn:async()=>{const{data:g,error:x}=await k.from("signup_attempts").select("id,email,email_domain,email_masked,source,created_at").order("created_at",{ascending:!1}).limit(30);if(x)throw x;return g??[]}})]}),m=r.data??[],u=n.data??[],i=a.data??[],d=l.data??[],c=()=>{s.invalidateQueries({queryKey:["admin","whitelist"]})};return e.jsxs("div",{className:"space-y-6",children:[e.jsx("p",{className:"text-xs text-muted-foreground leading-relaxed max-w-3xl",children:t("只有在此登記的電郵或企業網域才能註冊帳號。以組織主體為單位管理,其下可掛多個房號與多條規則;封鎖規則優
2先於允許規則。用戶完成電郵驗證後,系統才會把組織與房號寫入其帳戶並開通免費額度。","只有在此登记的邮箱或企业域名才能注册账号。以组织主体为单位管理,其下可挂多个房号与多条规则;封锁规则优先于允许规则。用户完成邮箱验证后,系统才会把组织与房号写入其账户并开通免费额度。","Only addresses or corporate domains registered here may create an account. Rules are grouped by organisation; deny rules win over allow rules. Organisation and room are written to the profile only after the address is verified.")}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"space-y-6",children:[e.jsx(Xt,{L:t,onDone:c}),e.jsx(Lt,{L:t})]}),e.jsxs("div",{className:"lg:col-span-2 space-y-4",children:[r.isLoading&&e.jsx("p",{className:"text-xs text-muted-foreground",children:t("載入中…","加载中…","Loading…")}),m.map(g=>e.jsx(es,{L:t,org:g,rooms:u.filter(x=>x.org_id===g.id),rules:i.filter(x=>x.org_id===g.id),onChanged:c},g.id))]})]}),e.jsxs("div",{className:"border border-border p-5",children:[e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.2em] mb-1",children:t("被拒註冊紀錄","被拒注册记录","Blocked sign-up attempts")}),e.jsx("p",{className:"text-xs text-muted-foreground mb-4",children:t("僅管理員可見完整電郵,可直接選擇組織一鍵加入白名單。","仅管理员可见完整邮箱,可直接选择组织一键加入白名单。","Full addresses are visible to admins only; pick an organisation to whitelist in one click.")}),d.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:t("暫無紀錄","暂无记录","No attempts")}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground border-b border-border",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left px-3 py-2",children:t("電郵","邮箱","Email")}),e.jsx("th",{className:"text-left px-3 py-2",children:t("網域","域名","Domain")}),e.jsx("th",{className:"text-left px-3 py-2",children:t("來源","来源","Source")}),e.jsx("th",{className:"text-left px-3 py-2 w-px whitespace-nowrap",children:t("時間","时间","Time")}),e.jsx("th",{className:"text-left px-3 py-2 w-px whitespace-nowrap",children:t("加入白名單","加入白名单","Whitelist")})]})}),e.jsx("tbody",{children:d.map(g=>e.jsxs("tr",{className:"border-b border-border/50",children:[e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:g.email??g.email_masked}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:g.email_domain}),e.jsx("td",{className:"px-3 py-2 font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:g.source==="direct_api"?t("直接註冊","直接注册","Direct"):t("表單預檢","表单预检","Form")}),e.jsx("td",{className:"px-3 py-2 text-xs whitespace-nowrap text-muted-foreground",children:new Date(g.created_at).toLocaleString("zh-HK",{timeZone:"Asia/Hong_Kong"})}),e.jsx("td",{className:"px-3 py-2",children:e.jsx(Jt,{L:t,email:g.email,orgs:m,onDone:c})})]},g.id))})]})]})]})}function Jt({L:t,email:s,orgs:r,onDone:n}){const[a,l]=o.useState(""),[m,u]=o.useState(!1);if(!s)return e.jsx("span",{className:"text-[10px] text-muted-foreground",children:"—"});async function i(){if(!a)return y.error(t("請先選擇組織","请先选择组织","Pick an organisation"));const d=(s??"").trim().toLowerCase();u(!0);const{error:c}=await k.from("signup_rules").insert({org_id:a,kind:"email",effect:"allow",value:d});if(u(!1),c)return c.code==="23505"?y.error(t("此電郵已被其他規則使用,請在組織卡片中調整。","此邮箱已被其他规则使用,请在组织卡片中调整。","This address is already used by another rule; adjust it on the organisation card.")):y.error(c.message);y.success(t("已加入白名單","已加入白名单","Whitelisted")),n()}return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("select",{value:a,onChange:d=>l(d.target.value),className:"h-7 border border-border bg-background px-2 text-xs max-w-[9rem]",children:[e.jsx("option",{value:"",children:t("選擇組織","选择组织","Organisation")}),r.map(d=>e.jsx("option",{value:d.id,children:d.name},d.id))]}),e.jsx("button",{disabled:m,onClick:i,className:"h-7 px-2 border border-border font-mono text-[10px] uppercase tracking-widest hover:bg-accent disabled:opacity-40 whitespace-nowrap",children:t("加白","加白","Allow")})]})}function Xt({L:t,onDone:s}
2){const[r,n]=o.useState(""),[a,l]=o.useState(""),[m,u]=o.useState(!1);async function i(){if(!r.trim())return y.error(t("請填寫名稱","请填写名称","Name required"));u(!0);const{error:d}=await k.from("organizations").insert({name:r.trim(),note:a.trim()||null});if(u(!1),d)return y.error(d.message);y.success(t("已新增組織","已新增组织","Organisation added")),n(""),l(""),s()}return e.jsxs("div",{className:"border border-border p-5",children:[e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.2em] mb-4",children:t("新增組織主體","新增组织主体","New organisation")}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("input",{value:r,onChange:d=>n(d.target.value),placeholder:t("組織名稱","组织名称","Organisation name"),className:"w-full h-9 px-2 border border-border bg-background text-sm"}),e.jsx("input",{value:a,onChange:d=>l(d.target.value),placeholder:t("備註(選填)","备注(选填)","Note (optional)"),className:"w-full h-9 px-2 border border-border bg-background text-sm"}),e.jsx("button",{onClick:i,disabled:m,className:"w-full h-9 border border-foreground font-mono text-[11px] uppercase tracking-widest hover:bg-accent disabled:opacity-40",children:t("新增","新增","Add")})]})]})}function Lt({L:t}){const s=de(Le),[r,n]=o.useState(""),[a,l]=o.useState(null),[m,u]=o.useState(!1);async function i(){if(r.trim()){u(!0);try{const d=await s({data:{email:r.trim()}});l(d)}catch{y.error(t("校驗失敗","校验失败","Check failed"))}finally{u(!1)}}}return e.jsxs("div",{className:"border border-border p-5",children:[e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.2em] mb-4",children:t("白名單校驗工具","白名单校验工具","Whitelist tester")}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("input",{value:r,onChange:d=>{n(d.target.value),l(null)},placeholder:"[email protected]",className:"w-full h-9 px-2 border border-border bg-background text-sm"}),e.jsx("button",{onClick:i,disabled:m,className:"w-full h-9 border border-border font-mono text-[11px] uppercase tracking-widest hover:bg-accent disabled:opacity-40",children:t("校驗","校验","Check")}),a&&e.jsx("div",{className:`border p-3 text-xs ${a.allowed?"border-foreground":"border-destructive text-destructive"}`,children:a.allowed?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"font-mono uppercase tracking-widest text-[10px] mb-1",children:t("允許註冊","允许注册","Allowed")}),e.jsxs("p",{children:[t("組織","组织","Organisation"),": ",a.orgName??"—",e.jsx("br",{}),t("房號","房号","Room"),": ",a.roomNo??"—"]}
2)]}):e.jsx("p",{className:"font-mono uppercase tracking-widest text-[10px]",children:t("不允許註冊","不允许注册","Not allowed")})})]})]})}function es({L:t,org:s,rooms:r,rules:n,onChanged:a}){const[l,m]=o.useState(""),[u,i]=o.useState("domain"),[d,c]=o.useState("allow"),[g,x]=o.useState(""),[C,D]=o.useState(""),[_,P]=o.useState(!1);async function A(b,S){P(!0);const{error:j}=await b();if(P(!1),j)return j.code==="23505"?y.error(t("此電郵/網域已被其他規則使用。","此邮箱/域名已被其他规则使用。","This address or domain is already used by another rule.")):y.error(j.message);y.success(S),a()}const N=b=>b.trim().toLowerCase();async function w(){const b=N(g);if(!b)return;P(!0);const{data:S,error:j}=await k.from("signup_rules").select("id,org_id,room_no,effect,enabled,organizations(name)").eq("kind",u).eq("value",b).maybeSingle();if(P(!1),j)return y.error(j.message);if(S){const E=S.organizations?.name??"—",O=S.org_id===s.id,z=t(`「${b}」已存在於組織〈${E}〉,房號〈${S.room_no??"未綁定"}〉,狀態〈${S.effect==="deny"?"封鎖":"允許"}〉。`,`「${b}」已存在于组织〈${E}〉,房号〈${S.room_no??"未绑定"}〉,状态〈${S.effect==="deny"?"封锁":"允许"}〉。`,`"${b}" already exists under organisation "${E}", room "${S.room_no??"none"}", effect "${S.effect}".`);return O?y.error(`${z} ${t("請直接在上方規則列表編輯。","请直接在上方规则列表编辑。","Edit it in the rule list above.")}`):window.confirm(`${z}
3
4${t(`是否將此規則移轉到〈${s.name}〉並套用目前設定?`,`是否将此规则移转到〈${s.name}〉并套用当前设置?`,`Move this rule to "${s.name}" and apply the current settings?`)}`)?A(async()=>await k.from("signup_rules").update({org_id:s.id,effect:d,room_no:C||null}).eq("id",S.id),t("已移轉規則","已移转规则","Rule moved")):void 0}return A(async()=>{const E=await k.from("signup_rules").insert({org_id:s.id,kind:u,effect:d,value:b,room_no:C||null});return E.error||(x(""),D("")),E},t("已新增規則","已新增规则","Rule added"))}return e.jsxs("div",{className:"border border-border p-5 space-y-5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-bold tracking-tight",children:s.name}),s.note&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:s.note})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:`font-mono text-[10px] uppercase tracking-widest px-2 py-1 border ${s.status==="active"?"border-border":"border-destructive text-destructive"}`,children:s.status==="active"?t("啟用","启用","Active"):t("停用","停用","Inactive")}),e.jsx("button",{disabled:_,onClick:()=>A(async()=>await k.from("organizations").update({status:s.status==="active"?"inactive":"active"}).eq("id",s.id),t("已更新","已更新","Updated")),className:"h-7 px-2 border border-border font-mono text-[10px] uppercase tracking-widest hover:bg-accent disabled:opacity-40",children:s.status==="active"?t("停用","停用","Disable"):t("啟用","启用","Enable")})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground mb-2",children:t("房號","房号","Rooms")}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[r.map(b=>e.jsxs("span",{className:"inline-flex items-center gap-2 border border-border px-2 py-1 font-mono text-xs",children:[b.room_no,e.jsx("button",{disabled:_,onClick:()=>A(async()=>await k.from("org_rooms").delete().eq("id",b.id),t("已刪除","已删除","Deleted")),className:"text-muted-foreground hover:text-destructive","aria-label":"delete room",children:"×"})]},b.id)),e.jsx("input",{value:l,onChange:b=>m(b.target.value),placeholder:t("新增房號","新增房号","Add room"),className:"h-8 px-2 border border-border bg-background text-xs w-32"}),e.jsx("button",{disabled:_||!l.trim(),onClick:()=>A(async()=>{const b=await k.from("org_rooms").insert({org_id:s.id,room_no:l.trim()});return b.error||m(""),b},t("已新增","已新增","Added")),className:"h-8 px-3 border border-border font-mono text-[10px] uppercase tracking-widest hover:bg-accent disabled:opacity-40",children:"+"})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground mb-2",children:t("註冊規則","注册规则","Rules")}),n.length>0&&e.jsxs("table",{className:"w-full text-sm mb-3",children:[e.jsx("thead",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground border-b border-border",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left px-2 py-1.5 w-px whitespace-nowrap",children:t("類型","类型","Type")}),e.jsx("th",{className:"text-left px-2 py-1.5",children:t("值","值","Value")}),e.jsx("th",{className:"text-left px-2 py-1.5 w-px whitespace-nowrap",children:t("房號","房号","Room")}),e.jsx("th",{className:"text-left px-2 py-1.5 w-px whitespace-nowrap",children:t("狀態","状态","State")}),e.jsx("th",{className:"px-2 py-1.5 w-px"})]})}),e.jsx("tbody",{children:n.map(b=>e.jsxs("tr",{className:"border-b border-border/50",children:[e.jsxs("td",{className:"px-2 py-1.5 font-mono text-[10px] uppercase whitespace-nowrap",children:[b.kind==="domain"?t("網域","域名","Domain"):t("電郵","邮箱","Email"),b.effect==="deny"&&e.jsx("span",{className:"ml-1 text-destructive",children:t("封鎖","封锁","Deny")})]}),e.jsx("td",{className:"px-2 py-1.5 font-mono text-xs break-all",children:b.value}),e.jsx("td",{className:"px-2 py-1.5 font-mono text-xs whitespace-nowrap",children:b.room_no??"—"}),e.jsx("td",{className:"px-2 py-1.5 whitespace-nowrap",children:e.jsx("button",{disabled:_,onClick:()=>A(async()=>await k.from("signup_rules").update({enabled:!b.enabled}).eq("id",b.id),t("已更新","已更新","Updated")),className:"font-mono text-[10px] uppercase tracking-widest border border-border px-2 py-1 hover:bg-accent disabled:opacity-40",children:b.enabled?t("啟用中","启用中","On"):t("已停用","已停用","Off")})}),e.jsx("td",{className:"px-2 py-1.5",children:e.jsx("button",{disabled:_,onClick:()=>{window.confirm(t("刪除只影響往後的註冊,已註冊帳號不受影響。確定刪除?","删除只影响往后的注册,已注册账号不受影响。确定删除?","Deleting only affects future sign-ups. Continue?"))&&A(async()=>await k.from("signup_rules").delete().eq("id",b.id),t("已刪除","已删除","Deleted"))},className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground hover:text-destructive disabled:opacity-40",children:t("刪除","删除","Delete")})})]},b.id))})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("select",{value:u,onChange:b=>i(b.target.value),className:"h-8 px-2 border border-border bg-background text-xs",children:[e.jsx("option",{value:"domain",children:t("網域","域名","Domain")}),e.jsx("option",{value:"email",children:t("電郵","邮箱","Email")})]}),e.jsxs("select",{value:d,onChange:b=>c(b.target.value),className:"h-8 px-2 border border-border bg-background text-xs",children:[e.jsx("option",{value:"allow",children:t("允許","允许","Allow")}),e.jsx("option",{value:"deny",children:t("封鎖","封锁","Deny")})]}),e.jsx("input",{value:g,onChange:b=>x(b.target.value),placeholder:u==="domain"?"crc.com.hk":"[email protected]",className:"h-8 px-2 border border-border bg-background text-xs flex-1 min-w-[180px]"}),e.jsxs("select",{value:C,onChange:b=>D(b.target.value),className:"h-8 px-2 border border-border bg-background text-xs",children:[e.jsx("option",{value:"",children:t("不綁房號","不绑房号","No room")}),r.map(b=>e.jsx("option",{value:b.room_no,children:b.room_no},b.id))]}),e.jsx("button",{disabled:_||!g.trim(),onClick:()=>{w()},className:"h-8 px-3 border border-foreground font-mono text-[10px] uppercase tracking-widest hover:bg-accent disabled:opacity-40",children:t("新增規則","新增规则","Add rule")})]})]})]})}function ts({L:t}){const[s,r]=o.useState(!1),n=te(),{data:a=[],isLoading:l}=X({queryKey:[...I.contacts,s],staleTime:30*1e3,queryFn:async()=>{let i=k.from("contact_submissions").select("*").order("created_at",{ascending:!1}).limit(200);s||(i=i.eq("status","new"));const{data:d,error:c}=await i;if(c)throw c;return d??[]}}),m=()=>n.invalidateQueries({queryKey:I.contacts});async function u(i){const d=i.status==="new"?"handled":"new",{error:c}=await k.from("contact_submissions").update({status:d,handled_at:d==="handled"?new Date().toISOString():null}).eq("id",i.id);if(c)return y.error(c.message);y.success(t("已更新","已更新","Updated")),m()}return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:t("網站聯絡表單的查詢紀錄,提交時同步寄送通知郵件。","网站联系表单的查询记录,提交时同步发送通知邮件。","Website contact form enquiries; a notification email is sent on submission.")}),e.jsxs("label",{className:"flex items-center gap-2 font-mono text-xs uppercase tracking-[0.15em] whitespace-nowrap",children:[e.jsx("input",{type:"checkbox",checked:s,onChange:i=>r(i.target.checked)}),t("顯示已處理","显示已处理","Show handled")]})]}),l?e.jsx("p",{className:"font-mono text-xs text-muted-foreground",children:"LOADING…"}):a.length===0?e.jsx("p",{className:"font-mono text-xs text-muted-foreground",children:t("暫無查詢","暂无查询","No enquiries")}):e.jsx("div",{className:"space-y-4",children:a.map(i=>e.jsxs("div",{className:"border border-border p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-bold",children:i.name}),i.company&&e.jsxs("span",{className:"text-muted-foreground",children:[" · ",i.company]}),e.jsx("span",{className:"ml-3 font-mono text-xs uppercase tracking-[0.15em] text-muted-foreground",children:i.status==="new"?t("待處理","待处理","NEW"):t("已處理","已处理","HANDLED")})]}),e.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:new Date(i.created_at).toLocaleStr
4ing("zh-HK",{timeZone:"Asia/Hong_Kong"})})]}),e.jsxs("div",{className:"mt-3 grid gap-1 text-sm",children:[e.jsx("a",{href:`mailto:${i.email}`,className:"hover:text-primary",children:i.email}),i.phone&&e.jsx("a",{href:`tel:${i.phone}`,className:"hover:text-primary",children:i.phone}),(i.headcount||i.budget_hkd_month)&&e.jsxs("div",{className:"flex flex-wrap gap-x-6 gap-y-1 text-muted-foreground",children:[i.headcount&&e.jsxs("span",{children:[t("人數","人数","Headcount"),":",i.headcount]}),i.budget_hkd_month&&e.jsxs("span",{children:[t("預算(港幣/月)","预算(港币/月)","Budget (HKD/month)"),":",i.budget_hkd_month]})]})]}),i.message&&e.jsx("p",{className:"mt-3 max-w-3xl whitespace-pre-wrap border-l-2 border-border pl-4 text-sm text-muted-foreground",children:i.message}),e.jsxs("div",{className:"mt-4 flex items-center justify-between gap-4",children:[e.jsx("span",{className:"font-mono text-[11px] uppercase tracking-[0.15em] text-muted-foreground",children:i.email_sent_at?t("通知已寄出","通知已发出","NOTIFIED"):i.email_error?t("通知失敗","通知失败","NOTIFY FAILED"):t("通知處理中","通知处理中","PENDING")}),e.jsx("button",{onClick:()=>{u(i)},className:"border border-border px-4 py-2 font-mono text-xs uppercase tracking-[0.15em] hover:bg-muted",children:i.status==="new"?t("標記已處理","标记已处理","Mark handled"):t("重新開啟","重新打开","Reopen")})]})]},i.id))})]})}var ss=Symbol.for("react.lazy"),pe=Ye[" use ".trim().toString()];function as(t){return typeof t=="object"&&t!==null&&"then"in t}function Me(t){return t!=null&&typeof t=="object"&&"$$typeof"in t&&t.$$typeof===ss&&"_payload"in t&&as(t._payload)}function Fe(t){const s=ns(t),r=o.forwardRef((n,a)=>{let{children:l,...m}=n;Me(l)&&typeof pe=="function"&&(l=pe(l._payload));const u=o.Children.toArray(l),i=u.find(is);if(i){const d=i.props.children,c=u.map(g=>g===i?o.Children.count(d)>1?o.Children.only(null):o.isValidElement(d)?d.props.children:null:g);return e.jsx(s,{...m,ref:a,children:o.isValidElement(d)?o.cloneElement(d,void 0,c):null})}return e.jsx(s,{...m,ref:a,children:l})});return r.displayName=`${t}.Slot`,r}var rs=Fe("Slot");function ns(t){const s=o.forwardRef((r,n)=>{let{children:a,...l}=r;if(Me(a)&&typeof pe=="function"&&(a=pe(a._payload)),o.isValidElement(a)){const m=ls(a),u=ds(l,a.props);return a.type!==o.Fragment&&(u.ref=n?Je(n,m):m),o.cloneElement(a,u)}return o.Children.count(a)>1?o.Children.only(null):null});return s.displayName=`${t}.SlotClone`,s}var os=Symbol("radix.slottable");function is(t){return o.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===os}function ds(t,s){const r={...s};for(const n in s){const a=t[n],l=s[n];/^on[A-Z]/.test(n)?a&&l?r[n]=(...u)=>{const i=l(...u);return a(...u),i}:a&&(r[n]=a):n==="style"?r[n]={...a,...l}:n==="className"&&(r[n]=[a,l].filter(Boolean).join(" "))}return{...t,...r}}function ls(t){let s=Object.getOwnPropertyDescriptor(t.props,"ref")?.get,r=s&&"isReactWarning"in s&&s.isReactWarning;return r?t.ref:(s=Object.getOwnPropertyDescriptor(t,"ref")?.get,r=s&&"isReactWarning"in s&&s.isReactWarning,r?t.props.ref:t.props.ref||t.ref)}const _e=t=>typeof t=="boolean"?`${t}`:t===0?"0":t,ke=Xe,Be=(t,s)=>r=>{var n;if(s?.variants==null)return ke(t,r?.class,r?.className);const{variants:a,defaultVariants:l}=s,m=Object.keys(a).map(d=>{const c=r?.[d],g=l?.[d];if(c===null)return null;const x=_e(c)||_e(g);return a[d][x]}),u=r&&Object.entries(r).reduce((d,c)=>{let[g,x]=c;return x===void 0||(d[g]=x),d},{}),i=s==null||(n=s.compoundVariants)===null||n===void 0?void 0:n.reduce((d,c)=>{let{class:g,className:x,...C}=c;return Object.entries(C).every(D=>{let[_,P]=D;return Array.isArray(P)?P.includes({...l,...u}[_]):{...l,...u}[_]===P})?[...d,g,x]:d},[]);return ke(t,m,i,r?.class,r?.className)},cs=Be("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground shadow hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",outline:"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2",sm:"h-8 rounded-md px-3 text-xs",lg:"h-10 rounded-md px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),ie=o.forwardRef(({className:t,variant:s,size:r,asChild:n=!1,...a},l)=>{const m=n?rs:"button";return e.jsx(m,{className:he(cs({variant:s,size:r,className:t})),ref:l,...a})});
4ie.displayName="Button";const oe=o.forwardRef(({className:t,type:s,...r},n)=>e.jsx("input",{type:s,className:he("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:n,...r}));oe.displayName="Input";const ze=o.forwardRef(({className:t,...s},r)=>e.jsx("textarea",{className:he("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base 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 md:text-sm",t),ref:r,...s}));ze.displayName="Textarea";var ms=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],us=ms.reduce((t,s)=>{const r=Fe(`Primitive.${s}`),n=o.forwardRef((a,l)=>{const{asChild:m,...u}=a,i=m?r:s;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),e.jsx(i,{...u,ref:l})});return n.displayName=`Primitive.${s}`,{...t,[s]:n}},{}),xs="Label",Ue=o.forwardRef((t,s)=>e.jsx(us.label,{...t,ref:s,onMouseDown:r=>{r.target.closest("button, input, select, textarea")||(t.onMouseDown?.(r),!r.defaultPrevented&&r.detail>1&&r.preventDefault())}}));Ue.displayName=xs;var Ve=Ue;const ps=Be("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),Qe=o.forwardRef(({className:t,...s},r)=>e.jsx(Ve,{ref:r,className:he(ps(),t),...s}));Qe.displayName=Ve.displayName;const hs=R({method:"GET"}).middleware([M]).handler(F("a4cab0aa434601498f2f6c8834dbf363a13902f1d3d29941e5ca993c14e15feb")),gs=R({method:"POST"}).middleware([M]).handler(F("fdccb771c7597b0be8eb73d3c0ba4bd17c5b6c485b559f9d1e3cde01badbae2f")),bs=R({method:"POST"}).middleware([M]).handler(F("d1e2d4d69eec1aeeb63bbce4ac76ab76a38f91440f6715ba4e9f4cad792fdc47")),fs=5*1024*1024;async function We(t){if(!t.type.startsWith("image/"))throw new Error("僅支援圖片檔案");if(t.size>fs)throw new Error("圖片大小不可超過 5MB");const s=(t.name.split(".").pop()??"jpg").toLowerCase().replace(/[^a-z0-9]/g,""),r=`${new Date().getFullYear()}/${crypto.randomUUID()}.${s||"jpg"}`,{error:n}=await k.storage.from("news-media").upload(r,t,{cacheControl:"31536000",contentType:t.type,upsert:!1});if(n)throw new Error(n.message);return`/api/public/news-media/${r}`}const Us=Object.freeze(Object.defineProperty({__proto__:null,uploadNewsImage:We},Symbol.toStringTag,{value:"Module"})),ys=o.lazy(()=>ce(()=>import("./RichTextEditor-Tz_S8H9c.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]))),vs=o.lazy(()=>ce(()=>import("./AiImportDialog-BbByENi_.js"),__vite__mapDeps([11,1,8,7,10,9]))),Se=()=>({slug:"",status:"draft",published_at:new Date().toISOString().slice(0,10),sort_index:0,cover_url:"",category_hant:"",category_en:"",title_hant:"",title_en:"",excerpt_hant:"",excerpt_en:"",cover_alt_hant:"",cover_alt_en:"",body_hant:xe,body_en:xe}),fe=["admin","news"];function js({L:t,onOpenAiSettings:s}){const r=de(hs),n=de(bs),a=te(),[l,m]=o.useState(null),[u,i]=o.useState(!1),{data:d=[],isLoading:c}=X({queryKey:fe,staleTime:3e4,queryFn:()=>r({data:{}})}),g=Pe({mutationFn:x=>n({data:{id:x}}),onSuccess:()=>{y.success(t("已刪除","已删除","Deleted")),a.invalidateQueries({queryKey:fe})},onError:x=>y.error(x.message)});return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{className:"space-y-2 max-w-2xl",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:t("管理前台「資訊動態」文章,支援繁體與英文分別填寫,簡體由系統自動轉換。","管理前台「资讯动态」文章,支持繁体与英文分别填写,简体由系统自动转换。","Manage the public news feed. Traditional Chinese and English are authored separately; Simplified is generated automatically.")}),e.jsx("p",{className:"text-xs text-muted-foreground",children:t("建議流程:填寫繁體 → 填寫英文 → 切至「預覽」確認排版 → 先存成草稿 → 確認無誤後改為「發布」。網址由系統自動產生,無需填寫。","建议流程:填写繁体 → 填写英文 → 切至「预览」确认排版 → 先存成草稿 → 确认无误后改为「发布」。网址由系统自动生成,无需填写。","Suggested flow: Traditional → English → check Preview → save as Draft → switch to Published. URLs are generated automatically.")})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(ie,{variant:"outline",size:"icon",title:t("AI 設定","AI 设置","AI settings"),onClick:()=>s?.(),children:e.jsx(yt,{className:"h-4 w-4"})}),e.jsxs(ie,{variant:"outline",onClick:()=>i(!0),className:"gap-2",children:[e.jsx(jt,{className:"h-4 w-4"}),t("Word 匯入(Beta)","Word 导入(Beta)","Word import (Beta)")]}),e.jsxs(ie,{onClick:()=>m(Se()),className:"gap-2",children:[e.jsx(ht,{className:"h-4 w-4"})," ",t("新增文章","新增文章","New post")]})]})]}),e.jsx("div",{className:"border border-border overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/30 text-left text-xs uppercase tracking-wider text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2",children:t("標題","标题","Title")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("分類","分类","Category")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("日期","日期","Date")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap text-center",children:t("狀態","状态","Status")}),e.jsx("th",{className:"px-3 py-2 w-px"})]})}),e.jsxs("tbody",{children:[c&&e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"px-3 py-8 text-center text-muted-foreground",children:t("載入中…","加载中…","Loading…")})}),!c&&d.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"px-3 py-8 text-center text-muted-foreground",children:t("尚無文章","尚无文章","No posts yet")})}),d.map(x=>e.jsxs("tr",{className:"border-t border-border align-top",children:[e.jsxs("td",{className:"px-3 py-3",children:[e.jsx("p",{className:"font-medium leading-snug",children:x.title_hant}),e.jsxs("p",{className:"mt-1 text-xs text-muted-foreground",children:["/news/",x.slug]})]}),e.jsx("td",{className:"px-3 py-3 whitespace-nowrap text-muted-foreground",children:x.category_hant}),e.jsx("td",{className:"px-3 py-3 whitespace-nowrap text-muted-foreground",children:x.published_at}),e.jsx("td",{className:"px-3 py-3 whitespace-nowrap text-center",children:e.jsx("span",{className:`inline-block text-xs px-2 py-1 border ${x.status==="published"?"border-primary text-primary":"border-border text-muted-foreground"}`,children:x.status==="published"?t("已發布","已发布","Published"):t("草稿","草稿","Draft")})}),e.jsxs("td",{className:"px-3 py-3 whitespace-nowrap text-right",children:[e.jsx("button",{className:"p-2 text-muted-foreground hover:text-foreground",onClick:()=>m(Ns(x)),children:e.jsx(xt,{className:"h-4 w-4"})}),e.jsx("button",{className:"p-2 text-muted-foreground hover:text-destructive",onClick:()=>{window.confirm(t("確定刪除此文章?","确定删除此文章?","Delete this post?"))&&g.mutate(x.id)},children:e.jsx(wt,{className:"h-4 w-4"})})]})]},x.id))]})]})}),l&&e.jsx(_s,{L:t,draft:l,onClose:()=>m(null),onSaved:()=>{m(null),a.invalidateQueries({queryKey:fe})}}),u&&e.jsx(o.Suspense,{fallback:null,children:e.jsx(vs,{onClose:()=>i(!1),onApply:x=>{i(!1),m({...Se(),...x})}})})]})}function Ns(t){return{id:t.id,slug:t.slug,status:t.status,published_at:t.published_at,sort_index:t.sort_index??0,cover_url:t.cover_url??"",category_hant:t.category_hant??"",category_en:t.category_en??"",title_hant:t.title_hant??"",title_en:t.title_en??"",excerpt_hant:t.excerpt_hant??"",excerpt_en:t.excerpt_en??"",cover_alt_hant:t.cover_alt_hant??"",cover_alt_en:t.cover_alt_en??"",body_hant:t.body_hant??xe,body_en:t.body_en??xe}}function ws(t,s){const n=[[!t.cover_url,"hant",s("請先上傳封面圖片","请先上传封面图片","Please upload a cover image")],[!t.category_hant.trim(),"hant",s("請填寫繁體「分類」","请填写繁体「分类」","Category (Traditional) is required")],[!t.title_hant.trim(),"hant",s("請填寫繁體「標題」","请填写繁体「标题」","Title (Traditional) is required")],[!t.excerpt_hant.trim(),"hant",s("請填寫繁體「摘要」","请填写繁体「摘要」","Excerpt (Traditional) is required")],[!t.category_en.trim(),"en",s("請填寫英文「分類」","请填写英文「分类」","Category (English) is required")],[!t.title_en.trim(),"en",s("請填寫英文「標題」","请填写英文「标题」","Title (English) is required")],[!t.excerpt_en.trim(),"en",s("請填寫英文「摘要」","请填写英文「摘要」","Excerpt (English) is required")]].find(([a])=>a);return n?{tab:n[1],message:n[2]}:null}function _s({L:t,draft:s,onClose:r,onSaved:n}
4){const[a,l]=o.useState(s),[m,u]=o.useState("hant"),[i,d]=o.useState("hant"),[c,g]=o.useState(!1),[x,C]=o.useState(!1),D=de(gs),_=(j,E)=>l(O=>({...O,[j]:E})),P=Pe({mutationFn:()=>D({data:a}),onSuccess:()=>{y.success(t("已儲存","已保存","Saved")),n()},onError:j=>y.error(j.message)}),A=()=>{const j=ws(a,t);if(j){u(j.tab),y.error(j.message);return}P.mutate()},N=o.useMemo(()=>[["hant",t("繁體中文","繁体中文","Traditional")],["en","English"],["preview",t("預覽","预览","Preview")]],[t]),w=async j=>{C(!0);try{_("cover_url",await We(j))}catch(E){y.error(E instanceof Error?E.message:"上傳失敗")}finally{C(!1)}},b=m==="en",S={category:i==="en"?a.category_en:a.category_hant,title:i==="en"?a.title_en:a.title_hant,excerpt:i==="en"?a.excerpt_en:a.excerpt_hant,coverAlt:i==="en"?a.cover_alt_en:a.cover_alt_hant,body:i==="en"?a.body_en:a.body_hant};return e.jsx(rt,{open:!0,onOpenChange:j=>!j&&r(),children:e.jsxs(nt,{className:"max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsx(ot,{children:e.jsx(it,{children:a.id?t("編輯文章","编辑文章","Edit post"):t("新增文章","新增文章","New post")})}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-4",children:[e.jsx(se,{label:t("發布日期","发布日期","Date"),hint:t("決定文章在列表中的排序與顯示日期。","决定文章在列表中的排序与显示日期。","Controls ordering and the displayed date."),children:e.jsx(oe,{type:"date",value:a.published_at,onChange:j=>_("published_at",j.target.value)})}),e.jsx(se,{label:t("狀態","状态","Status"),hint:t("草稿不會出現在前台,可隨時儲存。","草稿不会出现在前台,可随时保存。","Drafts stay hidden from the public site."),children:e.jsxs("select",{className:"h-10 w-full border border-input bg-background px-3 text-sm",value:a.status,onChange:j=>_("status",j.target.value),children:[e.jsx("option",{value:"draft",children:t("草稿","草稿","Draft")}),e.jsx("option",{value:"published",children:t("發布","发布","Published")})]})})]}),e.jsx("div",{className:"text-xs text-muted-foreground",children:a.id?e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:[t("文章網址:","文章网址:","Post URL: "),"/news/",a.slug]}),e.jsx("button",{className:"ml-3 underline underline-offset-4 hover:text-foreground",onClick:()=>g(j=>!j),children:c?t("收起進階設定","收起进阶设置","Hide advanced"):t("進階設定","进阶设置","Advanced")}),c&&e.jsxs("div",{className:"mt-2 space-y-1",children:[e.jsx(oe,{value:a.slug,onChange:j=>_("slug",j.target.value.trim().toLowerCase()),className:"max-w-md"}),e.jsx("p",{children:t("修改網址會使舊連結失效,非必要請勿更動。","修改网址会使旧链接失效,非必要请勿更动。","Changing the URL breaks existing links.")})]})]}):t("文章網址將於儲存時自動產生,無需填寫。","文章网址将于保存时自动生成,无需填写。","The URL is generated automatically on save.")}),e.jsx(se,{label:t("封面圖片","封面图片","Cover image"),hint:t("建議 3:2 橫幅、寬度 1600px 以上、單張 5MB 內,JPG / PNG。","建议 3:2 横幅、宽度 1600px 以上、单张 5MB 内,JPG / PNG。","Recommended: 3:2 landscape, 1600px+ wide, under 5MB, JPG/PNG."),children:e.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[a.cover_url&&e.jsx("img",{src:a.cover_url,alt:"",className:"h-20 w-32 object-cover bg-muted/30"}),e.jsxs("label",{className:"inline-flex items-center gap-2 border border-border px-3 py-2 text-sm cursor-pointer hover:border-primary",children:[e.jsx(kt,{className:"h-4 w-4"}),x?t("上傳中…","上传中…","Uploading…"):t("選擇圖片","选择图片","Choose image"),e.jsx("input",{type:"file",accept:"image/*",className:"hidden",onChange:j=>{const E=j.target.files?.[0];j.target.value="",E&&w(E)}})]})]})}),e.jsx("div",{className:"flex gap-1 border-b border-border",children:N.map(([j,E])=>e.jsx("button",{onClick:()=>u(j),className:`px-4 py-2 text-xs uppercase tracking-[0.2em] border-b-2 -mb-px transition-colors ${m===j?"border-primary text-foreground":"border-transparent text-muted-foreground hover:text-foreground"}`,children:E},j))}),m!=="preview"?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid sm:grid-cols-3 gap-4",children:[e.jsx(se,{label:t("分類","分类","Category"),hint:t("例:品牌動態,建議 2–6 字。","例:品牌动态,建议 2–6 字。","e.g. Brand news, keep it short."),children:e.jsx(oe,{value:b?a.category_en:a.category_hant,onChange:j=>
4_(b?"category_en":"category_hant",j.target.value),placeholder:b?"Brand news":"品牌動態"})}),e.jsx(se,{label:t("標題","标题","Title"),className:"sm:col-span-2",hint:t("建議 30 字內,過長會在列表與詳情頁自動換行。","建议 30 字内,过长会在列表与详情页自动换行。","Keep under ~70 characters."),children:e.jsx(oe,{value:b?a.title_en:a.title_hant,onChange:j=>_(b?"title_en":"title_hant",j.target.value)})})]}),e.jsx(se,{label:t("摘要","摘要","Excerpt"),hint:t("顯示於列表頁與分享預覽,建議 60–120 字。","显示于列表页与分享预览,建议 60–120 字。","Shown on the list page and link previews; 1–2 sentences."),children:e.jsx(ze,{rows:3,value:b?a.excerpt_en:a.excerpt_hant,onChange:j=>_(b?"excerpt_en":"excerpt_hant",j.target.value)})}),e.jsx(se,{label:t("封面圖說明文字","封面图说明文字","Cover caption"),hint:t("顯示在封面圖下方、置中呈現,同時作為無障礙替代文字;可留空。","显示在封面图下方、居中呈现,同时作为无障碍替代文字;可留空。","Displayed centred under the cover image and used as alt text; optional."),children:e.jsx(oe,{value:b?a.cover_alt_en:a.cover_alt_hant,onChange:j=>_(b?"cover_alt_en":"cover_alt_hant",j.target.value)})}),e.jsx(se,{label:t("內文","正文","Body"),hint:t("支援小標題、清單、引言、超連結與圖片;插入圖片後可填寫置中圖說。","支持小标题、列表、引言、超链接与图片;插入图片后可填写居中图说。","Supports headings, lists, quotes, links and images with centred captions."),children:e.jsx(o.Suspense,{fallback:e.jsx("div",{className:"h-64 border border-border animate-pulse bg-muted/20"}),children:e.jsx(ys,{value:b?a.body_en:a.body_hant,onChange:j=>_(b?"body_en":"body_hant",j)},m)})})]}):e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"text-muted-foreground",children:t("預覽語言","预览语言","Preview language")}),["hant","en"].map(j=>e.jsx("button",{onClick:()=>d(j),className:`border px-2 py-1 transition-colors ${i===j?"border-primary text-primary":"border-border text-muted-foreground hover:text-foreground"}`,children:j==="hant"?t("繁體中文","繁体中文","Traditional"):"English"},j))]}),e.jsxs("article",{className:"border border-border py-10 bg-background",children:[e.jsxs("div",{className:"max-w-2xl mx-auto px-6 pb-8",children:[e.jsxs("div",{className:"flex items-center gap-4 text-xs text-muted-foreground",children:[e.jsx("span",{className:"text-primary",children:S.category}),e.jsx("span",{className:"h-px w-8 bg-border"}),e.jsx("time",{children:ct(a.published_at,i==="en"?"en":"zh-Hant")})]}),e.jsx("h1",{className:"mt-5 text-3xl md:text-4xl font-bold leading-tight",children:S.title}),e.jsx("p",{className:"mt-6 text-sm md:text-base text-muted-foreground leading-relaxed border-l-2 border-primary pl-5",children:S.excerpt})]}),a.cover_url&&e.jsxs("figure",{className:"max-w-3xl mx-auto px-6",children:[e.jsx("img",{src:a.cover_url,alt:S.coverAlt,className:"w-full aspect-[3/2] object-cover bg-muted/30"}),S.coverAlt&&e.jsx("figcaption",{className:"mt-3 text-center text-xs text-muted-foreground",children:S.coverAlt})]}),e.jsx("div",{className:"max-w-2xl mx-auto px-6 mt-10 space-y-8",children:e.jsx(mt,{doc:S.body})})]})]}),e.jsxs(dt,{className:"gap-2",children:[e.jsx(ie,{variant:"outline",onClick:r,children:t("取消","取消","Cancel")}),e.jsxs(ie,{onClick:A,disabled:P.isPending,className:"gap-2",children:[e.jsx(bt,{className:"h-4 w-4"}),P.isPending?t("儲存中…","保存中…","Saving…"):t("儲存","保存","Save")]})]})]})})}function se({label:t,hint:s,children:r,className:n=""}){return e.jsxs("div",{className:`space-y-2 ${n}`,children:[e.jsx(Qe,{className:"text-xs text-muted-foreground",children:t}),r,s&&e.jsx("p",{className:"text-[11px] leading-relaxed text-muted-foreground/80",children:s})]})}const ks=R({method:"POST"}).middleware([M]).handler(F("b436d93ab104f71de8d960ffe3abb4e436ccb8564396e779fb4c39019c44a3f3"));R({method:"POST"}).middleware([M]).handler(F("c4762646ceb6ece2f097c7648612376ebcd74ef370bf655822581d05add02de3"));const Ss=[{key:"projector",h:"投影機",s:"投影仪",e:"Projector"},{key:"tv",h:"電視螢幕",s:"电视屏幕",e:"TV"},{key:"whiteboard",h:"白板",s:"白板",e:"Whiteboard"},{key:"video_conf",h:"視訊會議",s:"视频会议",e:"Video Conf"},{key:"phone",h:"會議電話",s:"会议电话",e:"Conference Phone"},{key:"aircon",h:"獨立冷氣",s:"独立空调",e:"A/C"},{key:"wifi",h:"高速 Wi-Fi",s:"高速 Wi-Fi",e:"High-speed Wi-Fi"}],Cs=[{key:"training",h:"培訓",s:"培训",e:"Training"},{key:"pitch",h:"路演",s:"路演",e:"Pitch"},{key:"interview",h:"面試",s:"面试",e:"Interview"},{key:"brainstorm",h:"頭腦風暴",s:"头脑风暴",e:"Brainstorm"},{key:"client",h:"客戶會議",s:"客户会议",e:"Client Meeting"},{key:"internal",h:"內部會議",s:"内部会议",e:"Internal"}];function Ds({room:t,onClose:s,onSaved:r,L:n}){const a=!t?.id,[l,m]=o.useState(t?.code??""),[u,i]=o.useState(t?.name??""),[d,c]=o.useState(t?.location??""),[g,x]=o.use
4State(t?.capacity??4),[C,D]=o.useState(t?.hourly_price_hkd??300),[_,P]=o.useState((t?.open_from??"09:00").slice(0,5)),[A,N]=o.useState((t?.open_to??"19:00").slice(0,5)),[w,b]=o.useState(t?.status??"active"),[S,j]=o.useState(t?.sort_order??0),[E,O]=o.useState(t?.config?.equipment??[]),[z,ae]=o.useState(t?.config?.use_cases??[]),[B,W]=o.useState(t?.config?.description??""),[K,v]=o.useState(t?.panel_ws_url??""),[T,U]=o.useState(t?.panel_room_id??""),[G,re]=o.useState(t?.panel_display_name??""),[p,q]=o.useState(!1),[L,J]=o.useState(!1),ee=de(ks);o.useEffect(()=>{const h=$=>$.key==="Escape"&&s();return window.addEventListener("keydown",h),()=>window.removeEventListener("keydown",h)},[s]);function H(h,$,V){$(h.includes(V)?h.filter(Ge=>Ge!==V):[...h,V])}async function le(){if(!l.trim()||!u.trim()||!g||!C){y.error(n("請填寫必填欄位","请填写必填字段","Please fill required fields"));return}q(!0);const h={code:l.trim(),name:u.trim(),location:d.trim()||null,capacity:Number(g),hourly_price_hkd:Number(C),open_from:_+":00",open_to:A+":00",status:w,sort_order:Number(S||0),config:{equipment:E,use_cases:z,description:B.trim()},panel_ws_url:K.trim()||null,panel_room_id:T.trim()||null,panel_display_name:G.trim()||null},{error:$}=a?await k.from("rooms").insert(h):await k.from("rooms").update(h).eq("id",t.id);if(q(!1),$){y.error($.message);return}y.success(n("已儲存","已保存","Saved")),r()}async function f(){if(!t?.id||!confirm(n("確認刪除該會議室?","确认删除该会议室?","Delete this room?")))return;const{error:h}=await k.from("rooms").delete().eq("id",t.id);if(h){y.error(h.message);return}y.success(n("已刪除","已删除","Deleted")),r()}return e.jsx("div",{className:"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm flex items-center justify-center p-4",onClick:s,children:e.jsxs("div",{className:"w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background border border-border",onClick:h=>h.stopPropagation(),children:[e.jsxs("div",{className:"border-b border-border px-6 py-4 flex items-center justify-between",children:[e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.3em]",children:a?n("新增會議室","新增会议室","New Room"):n("編輯會議室","编辑会议室","Edit Room")}),e.jsx("button",{onClick:s,className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground hover:text-foreground",children:n("關閉","关闭","Close")})]}),e.jsxs("div",{className:"px-6 py-5 space-y-4 text-sm",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(Q,{label:n("代碼 *","代码 *","Code *"),children:e.jsx("input",{value:l,onChange:h=>m(h.target.value),className:Z,placeholder:"M-01"})}),e.jsx(Q,{label:n("名稱 *","名称 *","Name *"),children:e.jsx("input",{value:u,onChange:h=>i(h.target.value),className:Z})}),e.jsx(Q,{label:n("位置","位置","Location"),children:e.jsx("input",{value:d??"",onChange:h=>c(h.target.value),className:Z})}),e.jsx(Q,{label:n("容納人數 *","容纳人数 *","Capacity *"),children:e.jsx("input",{type:"number",min:1,value:g,onChange:h=>x(h.target.value===""?"":Number(h.target.value)),className:Z})}),e.jsx(Q,{label:n("時薪 HKD *","时薪 HKD *","Hourly HKD *"),children:e.jsx("input",{type:"number",min:0,value:C,onChange:h=>D(h.target.value===""?"":Number(h.target.value)),className:Z})}),e.jsx(Q,{label:n("排序","排序","Order"),children:e.jsx("input",{type:"number",value:S,onChange:h=>j(h.target.value===""?"":Number(h.target.value)),className:Z})}),e.jsx(Q,{label:n("開放起","开放起","Open from"),children:e.jsx("input",{type:"time",value:_,onChange:h=>P(h.target.value),className:Z})}),e.jsx(Q,{label:n("開放止","开放止","Open to"),children:e.jsx("input",{type:"time",value:A,onChange:h=>N(h.target.value),className:Z})}),e.jsx(Q,{label:n("狀態","状态","Status"),children:e.jsxs("select",{value:w,onChange:h=>b(h.target.value),className:Z,children:[e.jsx("option",{value:"active",children:n("啟用","启用","Active")}
4),e.jsx("option",{value:"inactive",children:n("停用","停用","Inactive")}),e.jsx("option",{value:"maintenance",children:n("維護中","维护中","Maintenance")})]})})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground mb-2",children:n("設備","设备","Equipment")}),e.jsx("div",{className:"flex flex-wrap gap-2",children:Ss.map(h=>{const $=E.includes(h.key);return e.jsx("button",{type:"button",onClick:()=>H(E,O,h.key),className:`h-8 px-3 border font-mono text-[10px] uppercase tracking-widest ${$?"bg-foreground text-background border-foreground":"border-border hover:bg-accent"}`,children:n(h.h,h.s,h.e)},h.key)})})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground mb-2",children:n("用途標籤","用途标签","Use cases")}),e.jsx("div",{className:"flex flex-wrap gap-2",children:Cs.map(h=>{const $=z.includes(h.key);return e.jsx("button",{type:"button",onClick:()=>H(z,ae,h.key),className:`h-8 px-3 border font-mono text-[10px] uppercase tracking-widest ${$?"bg-foreground text-background border-foreground":"border-border hover:bg-accent"}`,children:n(h.h,h.s,h.e)},h.key)})})]}),e.jsx(Q,{label:n("描述","描述","Description"),children:e.jsx("textarea",{value:B,onChange:h=>W(h.target.value),rows:3,className:"w-full px-2.5 py-2 border border-border bg-background text-sm",placeholder:n("空間特色、佈局、備註…","空间特色、布局、备注…","Features, layout, remarks…")})}),e.jsxs("div",{className:"pt-4 border-t border-border",children:[e.jsx("p",{className:"font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground mb-1",children:n("門口面板 · Evoko","门口面板 · Evoko","Door Panel · Evoko")}),e.jsx("p",{className:"text-[11px] text-muted-foreground mb-3",children:n("面板資訊由系統自動同步(預訂變更即時推送,並每分鐘校時),一般無需手動操作。","面板信息由系统自动同步(预订变更实时推送,并每分钟校时),一般无需手动操作。","Panel data syncs automatically (instant on booking changes, plus a per-minute refresh). Manual action is normally not needed.")}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(Q,{label:n("面板 WS 位址","面板 WS 地址","Panel WS URL"),children:e.jsx("input",{value:K,onChange:h=>v(h.target.value),className:Z,placeholder:"ws://192.168.1.50:8765"})}),e.jsx(Q,{label:n("面板房間 ID","面板房间 ID","Panel Room ID"),children:e.jsx("input",{value:T,onChange:h=>U(h.target.value),className:Z,placeholder:"room-a"})}),e.jsx(Q,{label:n("門口顯示名稱","门口显示名称","Panel Display Name"),children:e.jsx("input",{value:G,onChange:h=>re(h.target.value),className:Z,placeholder:u})}),e.jsx("div",{className:"flex flex-col justify-end",children:e.jsx("button",{type:"button",disabled:!t?.id||L||!K.trim(),onClick:async()=>{if(t?.id){J(!0);try{const h=await ee({data:{roomId:t.id}});h.ok?y.success(n("已重新同步","已重新同步","Re-synced")):y.error(h.error??n("同步失敗","同步失败","Sync failed"))}catch(h){y.error(h instanceof Error?h.message:String(h))}finally{J(!1)}}},className:"h-9 px-3 border border-border font-mono text-[10px] uppercase tracking-widest text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-40",children:L?n("同步中…","同步中…","Syncing…"):n("立即重推(診斷)","立即重推(诊断)","Force re-sync (diagnostic)")})})]}),e.jsxs("p",{className:"mt-2 font-mono text-[10px] text-muted-foreground",children:[n("同步狀態","同步状态","Sync status"),":"," ",t?.panel_last_pushed_at?e.jsxs(e.Fragment,{children:[new Date(t.panel_last_pushed_at).toLocaleString(),t.panel_last_error?e.jsxs("span",{className:"text-destructive",children:[" · ",t.panel_last_error]}):e.jsxs("span",{className:"text-emerald-600",children:[" · ",n("正常","正常","OK")]})]}):e.jsx("span",{children:n("尚未同步","尚未同步","Not synced yet")})]})]})]}),e.jsxs("div",{className:"px-6 py-4 border-t border-border flex items-center justify-between",children:[a?e.jsx("span",{}):e.jsx("button",{onClick:f,className:"h-9 px-3 font-mono text-[10px] uppercase tracking-widest text-destructive hover:underline",children:n("刪除","删除","Delete")}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:s,className:"h-9 px-4 border border-border text-xs uppercase tracking-widest",children:n("取消","取消","Cancel")}),e.jsx("button",{onClick:le,disabled:p,className:"h-9 px-5 bg-primary text-primary-foreground text-xs font-bold uppercase tracking-widest disabled:opacity-50",children:p?n("儲存中…","保存中…","Saving…"):n("儲存","保存","Save")})]})]})]})})}const Z="w-full h-9 px-2 border border-border bg-background text-sm";function Q({label:t,children:s}){return e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block font-mono text-[10px] uppercase tracking-[0.25em] text-muted-foreground mb-1",children:t}),s]})}const ye=t=>Math.round((new Date(t.end_at).getTime()-new Date(t.start_at).getTime())/36e5*100)/100,ve=t=>Array.isArray(t.bills)?t.bills[0]:t.bills??void 0;function Ce(t,s){switch(t){case"booked":return s("已預訂","已预订","Booked");case"cancelled":return s("已取消","已取消","Cancelled");case"completed":return s("已完成","已完成","Completed");default:return t}}
4function Ps(t,s,r){const n=[{header:s("日期","日期","Date"),key:"date",format:"date",width:12},{header:s("開始","开始","Start"),key:"start",width:8},{header:s("結束","结束","End"),key:"end",width:8},{header:s("時長(小時)","时长(小时)","Hours"),key:"hours",format:"number",width:10},{header:s("會議室","会议室","Room"),key:"room",width:12},{header:s("預定人","预定人","Guest"),key:"guest",width:18},{header:"Email",key:"email",width:26},{header:s("機構","机构","Organisation"),key:"org",width:22},{header:s("主題","主题","Topic"),key:"topic",width:34},{header:s("聯絡人","联络人","Contact"),key:"contact",width:14},{header:s("聯絡電話","联络电话","Phone"),key:"phone",width:14},{header:s("狀態","状态","Status"),key:"status",width:12},{header:s("費用 (HKD)","费用 (HKD)","Amount (HKD)"),key:"amount",format:"money",width:14},{header:s("帳單狀態","账单状态","Bill status"),key:"billStatus",width:12}],a=d=>new Date(d).toLocaleTimeString("en-GB",{timeZone:"Asia/Hong_Kong",hour:"2-digit",minute:"2-digit",hour12:!1}),l=t.map(d=>{const c=ve(d);return{date:lt(d.start_at),start:a(d.start_at),end:a(d.end_at),hours:ye(d),room:d.rooms?.code??"—",guest:d.profiles?.full_name??d.contact_name??"—",email:d.profiles?.email??"—",org:d.profiles?.company_name??"—",topic:d.topic??"",contact:d.contact_name??"",phone:d.contact_phone??"",status:Ce(d.status,s),amount:c?Number(c.amount_hkd):null,billStatus:c?.status??"—"}}),m=new Map,u=new Map;for(const d of t){const c=ve(d),g=c?Number(c.amount_hkd):0,x=d.rooms?.code??"—",C=m.get(x)??{count:0,hours:0,amount:0};C.count+=1,C.hours+=ye(d),C.amount+=g,m.set(x,C);const D=Ce(d.status,s),_=u.get(D)??{count:0,amount:0};_.count+=1,_.amount+=g,u.set(D,_)}const i=[];i.push({group:s("依會議室","依会议室","By room")});for(const[d,c]of m)i.push({group:d,count:c.count,hours:Math.round(c.hours*100)/100,amount:Math.round(c.amount*100)/100});i.push({}),i.push({group:s("依狀態","依状态","By status")});for(const[d,c]of u)i.push({group:d,count:c.count,amount:Math.round(c.amount*100)/100});return i.push({}),i.push({group:s("合計","合计","Total"),count:t.length,hours:Math.round(t.reduce((d,c)=>d+ye(c),0)*100)/100,amount:Math.round(t.reduce((d,c)=>d+(ve(c)?.amount_hkd??0),0)*100)/100}),[{name:s("預訂明細","预订明细","Bookings"),columns:n,rows:l,note:r},{name:s("統計摘要","统计摘要","Summary"),columns:[{header:s("項目","项目","Item"),key:"group",width:22},{header:s("場次","场次","Sessions"),key:"count",format:"number",width:10},{header:s("時數","时数","Hours"),key:"hours",format:"number",width:10},{header:s("金額 (HKD)","金额 (HKD)","Amount (HKD)"),key:"amount",format:"money",width:16}],rows:i}]}const Es=R({method:"GET"}).middleware([M]).handler(F("88f124559370a7645870d037cc079651f42c568557c0a3d41e870555357bc705")),qs=o.lazy(()=>ce(()=>import("./AiProviderPanel-BsmvP-rU.js"),__vite__mapDeps([12,1,8,7,9,10]))),As=o.lazy(()=>ce(()=>import("./BookingAnalyticsPanel-OxrnFnZi.js"),__vite__mapDeps([13,1,8,14,3,7,9,10]))),Ts=o.lazy(()=>ce(()=>import("./BillingAnalyticsPanel-CHtsyqXw.js"),__vite__mapDeps([15,1,8,14,3,7,9,10])));function De({L:t,list:s,analytics:r}){const[n,a]=o.useState("list");return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"inline-flex border border-border",children:[["list",t("列表","列表","List")],["analytics",t("分析","分析","Analytics")]].map(([l,m])=>e.jsx("button",{type:"button",onClick:()=>a(l),className:`h-8 px-4 font-mono text-[11px] uppercase tracking-widest transition-colors ${n===l?"bg-primary text-primary-foreground":"text-muted-foreground hover:text-foreground"}`,children:m},l))}),n==="list"?s:e.jsx(o.Suspense,{fallback:null,children:r})]})}function $s(){const{lang:t}=je(),s=(a,l,m)=>t==="en"?m:t==="zh-Hans"?l:a,[r,n]=o.useState("rooms");return e.jsxs("div",{className:"site-container py-12",children:[e.jsx("p",{className:"font-mono text-xs uppercase tracking-[0.3em] text-muted-foreground",children:"[ ADMIN ]"}),e.jsx("h1",{className:"mt-2 text-3xl font-extrabold tracking-tight",children:s("管理後台","管理后台","Admin Console")}),e.jsx("div",{className:"mt-8 flex gap-1 border-b border-border overflow-x-auto",children:[["rooms",s("會議室","会议室","Rooms")],["bookings",s("預定總覽","预定总览","Bookings")],["blocks",s("封鎖時段","封锁时段","Blocks")],["credits",s("免費額度","免费额度","Credits")],["billing",s("帳單","账单","Billing")],["contacts",s("聯絡查詢","联系查询","Enquiries")],["news",s("資訊","资讯","News")],["whitelist",s("註冊白名單","注册白名单","Whitelist")],["ai",s("AI 設定","AI 设置","AI settings")]].map(([a,l])=>e.jsx("button",{onClick:()=>n(a),className:`px-5 py-3 font-mono text-xs uppercase tracking-[0.2em] border-b-2 -mb-px transition-colors whitespace-nowrap ${r===a?"border-primary text-foreground":"border-transparent text-muted-foreground hover:text-foreground"}`,children:l},a))}),e.jsxs("div",{className:"mt-8",children:[r==="rooms"&&e.jsx(Ks,{L:s}),r==="bookings"&&e.jsx(De,{L:s,list:e.jsx(Os,{L:s,lang:t}),analytics:e.jsx(As,{L:s,onOpenAiSettings:()=>n("ai")})}),r==="blocks"&&e.jsx(Hs,{L:s,lang:t}),r==="credits"&&e.jsx(Zt,{L:s}),r==="billing"&&e.jsx(De,{L:s,list:e.jsx(Wt,{L:s}),analytics:e.jsx(Ts,{L:s,onOpenAiSettings:()=>n("ai")})}),r==="contacts"&&e.jsx(ts,{L:s}),r==="news"&&e.jsx(js,{L:s,onOpenAiSettings:()=>n("ai")}),r==="ai"&&e.jsx(o.Suspense,{fallback:null,children:e.jsx(qs,{L:s})}),r==="whitelist"&&e.jsx(Yt,{L:s})]})]})}function Ks({L:t}
4){const[s,r]=o.useState(null),[n,a]=o.useState(!1),l=de(Es),m=te(),{data:u=[],isLoading:i}=X(St(l)),d=()=>m.invalidateQueries({queryKey:I.rooms});async function c(g,x){const{error:C}=await k.from("rooms").update({status:x}).eq("id",g.id);if(C){y.error(C.message);return}y.success(t("已更新","已更新","Updated")),d()}return i?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading…"}):e.jsxs("div",{children:[e.jsx("div",{className:"flex justify-end mb-4",children:e.jsxs("button",{onClick:()=>a(!0),className:"h-9 px-4 bg-primary text-primary-foreground font-mono text-[10px] uppercase tracking-[0.2em]",children:["+ ",t("新增會議室","新增会议室","New Room")]})}),e.jsx("div",{className:"border border-border overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40",children:e.jsxs("tr",{className:"text-left font-mono text-[10px] uppercase tracking-[0.2em] text-muted-foreground",children:[e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("代碼","代码","Code")}),e.jsx("th",{className:"px-3 py-2",children:t("名稱","名称","Name")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("容量","容量","Cap.")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("時薪","时薪","Rate")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("開放","开放","Hours")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("狀態","状态","Status")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("面板","面板","Panel")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap text-right",children:t("操作","操作","Actions")})]})}),e.jsx("tbody",{className:"divide-y divide-border",children:u.map(g=>e.jsxs("tr",{children:[e.jsx("td",{className:"px-3 py-2 font-mono",children:g.code}),e.jsx("td",{className:"px-3 py-2",children:g.name}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:g.capacity}),e.jsxs("td",{className:"px-3 py-2 font-mono text-xs",children:["HKD ",g.hourly_price_hkd]}),e.jsxs("td",{className:"px-3 py-2 font-mono text-xs",children:[g.open_from.slice(0,5),"–",g.open_to.slice(0,5)]}),e.jsx("td",{className:"px-3 py-2",children:e.jsxs("select",{value:g.status,onChange:x=>c(g,x.target.value),className:"h-8 px-2 border border-border bg-background text-xs font-mono uppercase",children:[e.jsx("option",{value:"active",children:t("啟用","启用","Active")}
4),e.jsx("option",{value:"inactive",children:t("停用","停用","Inactive")}),e.jsx("option",{value:"maintenance",children:t("維護中","维护中","Maintenance")})]})}),e.jsx("td",{className:"px-3 py-2",children:e.jsx(Is,{room:g,L:t})}),e.jsx("td",{className:"px-3 py-2 text-right",children:e.jsx("button",{onClick:()=>r(g),className:"font-mono text-[10px] uppercase tracking-widest text-primary hover:underline",children:t("編輯","编辑","Edit")})})]},g.id))})]})}),(s||n)&&e.jsx(Ds,{room:s,onClose:()=>{r(null),a(!1)},onSaved:()=>{r(null),a(!1),d()},L:t})]})}function Is({room:t,L:s}){if(!t.panel_ws_url||!t.panel_room_id)return e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:s("未配置","未配置","N/A")});const r=!t.panel_last_error,n=t.panel_last_pushed_at;return e.jsxs("span",{title:t.panel_last_error??(n?new Date(n).toLocaleString():void 0),className:"inline-flex items-center gap-1.5 font-mono text-[10px] uppercase tracking-widest",children:[e.jsx("span",{className:`inline-block h-1.5 w-1.5 rounded-full ${n?r?"bg-emerald-500":"bg-destructive":"bg-muted-foreground"}`}),n?r?s("正常","正常","Online"):s("異常","异常","Error"):s("待同步","待同步","Pending")]})}function Os({L:t,lang:s}){const[r,n]=o.useState("upcoming"),a=te(),{data:l=[],isLoading:m}=X(Dt(r)),u=()=>a.invalidateQueries({queryKey:["admin","bookings"]});async function i(c){if(!confirm(t(`確認代取消 ${c.rooms?.code} @ ${new Date(c.start_at).toLocaleString("zh-HK")}?`,`确认代取消 ${c.rooms?.code} @ ${new Date(c.start_at).toLocaleString("zh-CN")}?`,`Cancel ${c.rooms?.code} @ ${new Date(c.start_at).toLocaleString("en-US")}?`)))return;const{data:x}=await k.auth.getUser(),{error:C}=await k.from("bookings").update({status:"cancelled",cancelled_at:new Date().toISOString(),cancelled_by:x.user?.id,cancel_reason:"admin_cancelled"}).eq("id",c.id);if(C){y.error(C.message);return}y.success(t("已取消","已取消","Cancelled")),u()}const d=c=>new Date(c).toLocaleString(s==="en"?"en-US":s==="zh-Hans"?"zh-CN":"zh-HK",{timeZone:"Asia/Hong_Kong",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1});return e.jsxs("div",{children:[e.jsxs("div",{className:"flex gap-2 mb-4",children:[[["upcoming",t("即將到來","即将到来","Upcoming")],["today",t("今日","今日","Today")],["cancelled",t("已取消","已取消","Cancelled")],["all",t("全部","全部","All")]].map(([c,g])=>e.jsx("button",{onClick:()=>n(c),className:`h-8 px-3 border font-mono text-[10px] uppercase tracking-widest ${r===c?"border-primary text-primary":"border-border text-muted-foreground"}`,children:g},c)),e.jsx("div",{className:"ml-auto",children:e.jsx($e,{rowCount:l.length,onExport:async()=>{const c=t(`匯出時間 ${new Date().toLocaleString("zh-HK",{timeZone:"Asia/Hong_Kong"})} · 檢視:${r}`,`导出时间 ${new Date().toLocaleString("zh-CN",{timeZone:"Asia/Hong_Kong"})} · 视图:${r}`,`Exported ${new Date().toLocaleString("en-US",{timeZone:"Asia/Hong_Kong"})} · view: ${r}`);await Ie({fileName:Oe(t("預訂","预订","Bookings")),sheets:Ps(l,t,c)})}})})]}),m?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading…"}):l.length===0?e.jsx("div",{className:"border border-border px-6 py-10 text-center text-sm text-muted-foreground",children:t("無資料","无数据","No data")}):e.jsx("div",{className:"border border-border overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40",children:e.jsxs("tr",{className:"text-left font-mono text-[10px] uppercase tracking-[0.2em] text-muted-foreground",children:[e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("房間","房间","Room")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("時段","时段","Time")}),e.jsx("th",{className:"px-3 py-2 w-[26%]",children:t("預定人","预定人","Guest")}),e.jsx("th",{className:"px-3 py-2 w-[30%]",children:t("主題","主题","Topic")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("聯絡","联络","Contact")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("費用","费用","Bill")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap",children:t("狀態","状态","Status")}),e.jsx("th",{className:"px-3 py-2 w-px whitespace-nowrap text-right",children:t("操作","操作","Action")})]})}),e.jsx("tbody",{className:"divide-y divide-border",children:l.map(c=>{const g=Array.isArray(c.bills)?c.bills[0]:c.bills??void 0,x=c.status==="booked"&&new Date(c.end_at).getTime()>Date.now();return e.jsxs("tr",{children:[e.jsx("td",{className:"px-3 py-2 font-mono text-xs whitespace-nowrap",children:c.rooms?.code}),e.jsxs("td",{className:"px-3 py-2 font-mono text-xs whitespace-nowrap",children:[d(c.start_at),"–",new Date(c.end_at).toLocaleTimeString("zh-HK",{timeZone:"Asia/Hong_Kong",hour:"2-digit",minute:"2-digit",hour12:!1})]}),e.jsxs("td",{className:"px-3 py-2",children:[e.jsx("div",{children:c.profiles?.full_name??c.contact_name}),e.jsx("div",{className:"text-xs text-muted-foreground",children:c.profiles?.company_name??c.profiles?.email})]}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("span",{className:"line-clamp-2",children:c.topic})}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs whitespace-nowrap",children:c.contact_phone}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs whitespace-nowrap",children:g?`HKD ${g.amount_hkd}`:"—"}),e.jsx("td",{className:"px-3 py-2 font-mono text-[10px] uppercase whitespace-nowrap",children:c.status}),e.jsx("td",{className:"px-3 py-2 text-right whitespace-nowrap",children:x&&e.jsx("button",{onClick:()=>i(c),className:"font-mono text-[10px] uppercase tracking-widest text-destructive hover:underline",children:t("取消","取消","Cancel")})})]},c.id)})})]})})]})}function Hs({L:t,lang:s}){const[r,n]=o.useState(""),[a,l]=o.useState(""),[m,u]=o.useState(""),[i,d]=o.use
4State(""),c=te(),{data:g=[]}=X(Ct()),{data:x=[],isLoading:C}=X(Pt()),D=()=>c.invalidateQueries({queryKey:I.blocks}),_=r||g[0]?.id||"";async function P(){if(!_||!a||!m){y.error(t("請填寫完整資料","请填写完整资料","Fill in all fields"));return}if(new Date(a)>=new Date(m)){y.error(t("結束時間需晚於開始","结束时间需晚于开始","End must be after start"));return}const{data:w}=await k.auth.getUser(),{error:b}=await k.from("blocked_slots").insert({room_id:_,start_at:new Date(a).toISOString(),end_at:new Date(m).toISOString(),reason:i||null,created_by:w.user?.id});if(b){y.error(b.message);return}y.success(t("已封鎖","已封锁","Blocked")),l(""),u(""),d(""),D()}async function A(w){const{error:b}=await k.from("blocked_slots").delete().eq("id",w);if(b){y.error(b.message);return}y.success(t("已刪除","已删除","Removed")),D()}const N=w=>new Date(w).toLocaleString(s==="en"?"en-US":s==="zh-Hans"?"zh-CN":"zh-HK",{timeZone:"Asia/Hong_Kong",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1});return e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"lg:col-span-1 border border-border p-5",children:[e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.2em] mb-4",children:t("新增封鎖時段","新增封锁时段","New Block")}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("label",{className:"block text-xs",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("房間","房间","Room")}),e.jsx("select",{value:_,onChange:w=>n(w.target.value),className:"mt-1 w-full h-9 px-2 border border-border bg-background text-sm",children:g.map(w=>e.jsx("option",{value:w.id,children:w.code},w.id))})]}),e.jsxs("label",{className:"block text-xs",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("開始","开始","Start")}),e.jsx("input",{type:"datetime-local",value:a,onChange:w=>l(w.target.value),className:"mt-1 w-full h-9 px-2 border border-border bg-background text-sm"})]}),e.jsxs("label",{className:"block text-xs",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("結束","结束","End")}),e.jsx("input",{type:"datetime-local",value:m,onChange:w=>u(w.target.value),className:"mt-1 w-full h-9 px-2 border border-border bg-background text-sm"})]}),e.jsxs("label",{className:"block text-xs",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t("原因(可選)","原因(可选)","Reason")}),e.jsx("input",{value:i,onChange:w=>d(w.target.value),placeholder:t("維護 / 內部使用","维护 / 内部使用","Maintenance / internal"),className:"mt-1 w-full h-9 px-2 border border-border bg-background text-sm"})]}),e.jsx("button",{onClick:P,className:"w-full h-10 bg-primary text-primary-foreground font-mono text-xs uppercase tracking-[0.2em]",children:t("新增封鎖","新增封锁","Add Block")})]})]}),e.jsxs("div",{className:"lg:col-span-2",children:[e.jsx("h3",{className:"font-mono text-xs uppercase tracking-[0.2em] mb-4",children:t("目前生效","目前生效","Active Blocks")}),C?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading…"}):x.length===0?e.jsx("div",{className:"border border-border px-6 py-10 text-center text-sm text-muted-foreground",children:t("尚無封鎖時段","尚无封锁时段","No blocks")}):e.jsx("div",{className:"border border-border divide-y divide-border",children:x.map(w=>e.jsxs("div",{className:"px-4 py-3 grid grid-cols-12 gap-2 items-center text-sm",children:[e.jsx("div",{className:"col-span-2 font-mono text-xs",children:w.rooms?.code}),e.jsxs("div",{className:"col-span-5 font-mono text-xs",children:[N(w.start_at)," – ",N(w.end_at)]}),e.jsx("div",{className:"col-span-4 text-xs text-muted-foreground truncate",children:w.reason??"—"}),e.jsx("div",{className:"col-span-1 text-right",children:e.jsx("button",{onClick:()=>A(w.id),className:"font-mono text-[10px] uppercase tracking-widest text-destructive hover:underline",children:t("刪除","删除","Del")})})]},w.id))})]})]})}const Vs=Object.freeze(Object.defineProperty({__proto__:null,component:$s},Symbol.toStringTag,{value:"Module"}));
4export{ie as B,oe as I,Qe as L,jt as S,wt as T,kt as U,I as a,yt as b,Us as c,Vs as d,We as u};

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.