PageSourceSearch

https://go853c.manus.space/assets/AdminPushNotifications-DJAULJrp.js

js go853c.manus.space collected 2026-10-03 05:04:13 UTC 54,669 bytes, 1 lines download raw bytes

1import{r as l,j as s,J as R,a1 as V,F as B,t as b,e as J,aQ as u,aR as p,a8 as Q,T as ts,a9 as K,bb as E,bc as I,bf as $,ag as N,R as O,g,at as _,ae as H,C as es}from"./index-DxpMJHht.js";import{A as ns}from"./AdminLayout-0d316vlG.js";import{I as U}from"./input-BM87a4su.js";import{L as A}from"./label-N5PEA7-o.js";import{T as G}from"./textarea-s21c5pGe.js";import{B as v}from"./badge-DsT5f29h.js";import{S as z,a as w,b as k,c as D,d as n}from"./select-DmrdHioO.js";import{D as X,a as q,b as W,c as Y,d as Z}from"./useComposition-XW7wi1uU.js";import{S as L}from"./send-C64nbNl-.js";import{H as cs}from"./history-CNsqc5g5.js";import{P as ds}from"./pen-Q0pRHZRj.js";import{T as os}from"./trash-2-BXORPUbj.js";import"./users-pO4YXYoT.js";import"./message-square-BL6WhYih.js";import"./credit-card-CBqiWxzd.js";import"./scroll-text-S2xX2Zri.js";import"./brain-BILY2OXr.js";import"./shield-check-B-c2fWxU.js";import"./code-xml-CbOybmm2.js";import"./link-2-CKikx1IH.js";import"./index-DpvxDjfc.js";import"./index-B3jfGoxH.js";import"./index-Dd2B6ZeX.js";import"./usePersistFn-D0m5YWYz.js";const ls=[{id:"dashboard",label:"設備統計",icon:s.jsx(V,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:44",size:16})},{id:"channels",label:"通道與測試",icon:s.jsx(R,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:45",size:16})},{id:"send",label:"發送通知",icon:s.jsx(L,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:46",size:16})},{id:"history",label:"推送歷史",icon:s.jsx(cs,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:47",size:16})},{id:"templates",label:"通知模板",icon:s.jsx(B,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:48",size:16})}];function _s(){const[a,r]=l.useState("dashboard");return s.jsx(ns,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:60",children:s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:61",className:"space-y-6",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:63",children:[s.jsxs("h1",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:64",className:"text-2xl font-bold flex items-center gap-2",children:[s.jsx(R,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:65",size:24,className:"text-orange-500"}),"推送通知管理"]}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:68",className:"text-muted-foreground mt-1",children:"管理推送通知的發送、查看歷史記錄和設備統計"})]}),s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:74",className:"flex gap-1 p-1 bg-muted rounded-lg w-fit",children:ls.map(d=>s.jsxs("button",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:76",onClick:()=>r(d.id),className:`flex items-center gap-1.5 px-4 py-2 rounded-md text-sm font-medium transition-colors ${a===d.id?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"}`,children:[d.icon,d.label]},d.id))}),a==="dashboard"&&s.jsx(rs,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:92"}),a==="channels"&&s.jsx(ms,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:93"}),a==="send"&&s.jsx(xs,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:94"}),a==="history"&&s.jsx(hs,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:95"}),a==="templates"&&s.jsx(us,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:96"})]})})}function ms(){const[a,r]=l.useState("none"),[d,c]=l.useState(!1),{data:x,refetch:f}=b.admin.pushNotifications.getTokenStats.useQuery(),{data:o,isLoading:C,refetch:P}=b.admin.pushNotifications.getJpushTestCandidates.useQuery(),j=b.admin.pushNotifications.testJpushReadiness.useMutation({onSuccess:e=>{e.ok?g.success(`${e.message}(${e.latencyMs}ms)`):g.error(e.message)},onError:e=>g.error(`JPush 唯讀檢查失敗:${e.message}`)}),h=b.admin.pushNotifications.sendControlledJpushTest.useMutation({onSuccess:e=>{c(!1),e.success?g.success(e.message):g.error(e.message)},onError:e=>{c(!1),g.error(`JPush 受控測試失敗:${e.message}`)}}),i=o?.find(e=>e.id===Number(a)),y=x?.byPlatform.find(e=>e.platform==="jpush")?.count??0,S=x?.byPlatform.find(e=>e.platform==="fcm")?.count??0;return s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:133",className:"space-y-6",children:[s.jsxs(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:134",className:"border-orange-200 bg-orange-50/40",children:[s.jsxs(E,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:135",children:[s.jsxs(I,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:136",className:"text-base flex items-center gap-2",children:[s.jsx(R,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:137",size:18,className:"text-orange-500"}),"推送通道管理"]}),s.jsx($,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:140",children:"管理員可核對 JPush/FCM 通道與對指定 JPush 裝置進行一次受控測試;不顯示金鑰或 Registration ID。"})]}),s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:144",className:"space-y-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:145",className:"grid grid-cols-1 md:grid-cols-3 gap-3",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:146",className:"rounded-lg border bg-white p-3",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:147",className:"text-xs text-muted-foreground",children:"JPush 有效已註冊裝置"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:148",className:"text-2xl font-semibold text-orange-600",children:y})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:150",className:"rounded-lg border bg-white p-3",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:151",className:"text-xs text-muted-foreground",children:"FCM 有效已註冊裝置"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:152",className:"text-2xl font-semibold text-blue-600",children:S})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:154",className:"rounded-lg border bg-white p-3",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:155",className:"text-xs text-muted-foreground",children:"現行原生通道"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:156",className:"text-sm font-medium mt
1-1",children:"JPush 原生 SDK + Expo Push;iOS/Android 原生安裝包均已啟用"})]})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:160",className:"flex flex-wrap items-center gap-3",children:[s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:161",variant:"outline",onClick:()=>j.mutate(),disabled:j.isPending,children:[j.isPending?s.jsx(J,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:166",size:15,className:"animate-spin mr-1"}):s.jsx(O,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:166",size:15,className:"mr-1"}),"JPush 唯讀連通檢查"]}),s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:169",variant:"outline",onClick:()=>{f(),P()},disabled:C,children:[s.jsx(O,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:174",size:15,className:"mr-1"})," 刷新裝置狀態"]}),s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:176",className:"text-xs text-muted-foreground",children:"唯讀檢查不會發送通知或更改設定。"})]})]})]}),s.jsxs(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:181",children:[s.jsxs(E,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:182",children:[s.jsxs(I,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:183",className:"text-base flex items-center gap-2",children:[s.jsx(V,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:183",size:18}),"指定 JPush 測試裝置"]}),s.jsx($,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:184",children:"只列出已上報且仍有效的 JPush 裝置;不顯示 Registration ID。請只選擇你已確認持有的測試設備。"})]}),s.jsx(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:186",className:"space-y-4",children:y===0?s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:188",className:"rounded-md border border-amber-200 bg-amber-50 px-3 py-3 text-sm text-amber-800",children:"尚未有 JPush Registration ID 上報。請在已安裝 iOS build 9 或 Android versionCode 5 的實機開啟通知權限、登入並重新開啟 App 一次,之後按「刷新裝置狀態」。"}):s.jsxs(s.Fragment,{children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:193",className:"space-y-1.5 max-w-xl",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:194",children:"測試裝置"}),s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:195",value:a,onValueChange:r,children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:196",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:196",placeholder:"選擇已確認的測試裝置"})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:197",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:198",value:"none",children:"請選擇裝置"}),o?.map(e=>s.jsxs(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:200",value:String(e.id),children:["使用者 #",e.userId," · ",e.deviceType.toUpperCase()," · ",e.deviceInfo||"未提供型號"]},e.id))]})]})]}),i&&s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:208",className:"rounded-md border bg-muted/30 px-3 py-3 text-sm",children:[s.jsxs("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:209",className:"font-medium",children:["即將只向使用者 #",i.userId," 的 ",i.deviceType.toUpperCase()," 指定裝置送出 1 則固定測試通知。"]}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:210",className:"text-xs text-muted-foreground mt-1",children:"不會向其他裝置、全體用戶或站內通知發送;不改用戶偏好。"})]}),s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:213",className:"bg-orange-500 hover:bg-orange-600",disabled:!i||h.isPending,onClick:()=>c(!0),children:[s.jsx(L,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:218",size:15,className:"mr-1"})," 發送一次受控 JPush 測試"]})]})})]}),s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:225",className:"border-blue-200 bg-blue-50/40",children:s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:226",className:"pt-5 text-sm text-blue-900 space-y-1.5",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:227",className:"font-medium",children:"原ç”
1ŸæŽ¥å…¥ç‹€æ…‹"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:228",children:"JPush 已包含在 Android versionCode 5 與 iOS build 9 的原生安裝包。登入後僅在裝置已授權通知時,上報 JPush Registration ID 及綁定帳戶 alias;Expo Go 與 OTA 不會加入或替換 JPush 原生程式碼。"})]})}),s.jsx(X,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:232",open:d,onOpenChange:c,children:s.jsxs(q,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:233",className:"max-w-md",children:[s.jsx(W,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:234",children:s.jsx(Y,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:234",children:"確認受控 JPush 測試"})}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:235",className:"text-sm text-muted-foreground",children:"此操作會向選定的一個 JPush 裝置發送固定測試通知,並留下去敏紀錄;不會對全體用戶廣播。"}),s.jsxs(Z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:236",children:[s.jsx(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:237",variant:"outline",onClick:()=>c(!1),children:"取消"}),s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:238",className:"bg-orange-500 hover:bg-orange-600",disabled:!i||h.isPending,onClick:()=>h.mutate({tokenId:i.id,confirmation:"SEND_JPUSH_TEST"}),children:[h.isPending?s.jsx(J,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:243",size:15,className:"animate-spin mr-1"}):s.jsx(L,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:243",size:15,className:"mr-1"}),"確認發送 1 則測試"]})]})]})})]})}function rs(){const{data:a,isLoading:r,refetch:d}=b.admin.pushNotifications.getTokenStats.useQuery();return r?s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:261",className:"flex items-center justify-center py-20",children:[s.jsx(J,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:262",className:"animate-spin mr-2"})," 載入統計數據..."]}):s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:268",className:"space-y-6",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:270",className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4",children:[s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:271",children:s.jsx(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:272",className:"pt-6",children:s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:273",className:"flex items-center justify-between",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:274",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:275",className:"text-sm text-muted-foreground",children:"總設備數"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:276",className:"text-3xl font-bold",children:a?.total||0})]}),s.jsx(V,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:278",size:32,className:"text-muted-foreground/30"})]})})}),s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:282",children:s.jsx(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:283",className:"pt-6",children:s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:284",className:"flex items-center justify-between",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:285",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:286",className:"text-sm text-muted-foreground",children:"活躍設備"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:287",className:"text-3xl font-bold text-green-600",children:a?.active||0})]}),s.jsx(Q,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:289",size:32,className:"text-green-500/30"})]})})}),s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:293",children:s.jsx(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:294",className:"pt-6",children:s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:295",className:"flex items-center justify-between",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:296",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:297",className:"text-sm text-muted-foreground",children:"7日新增"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:298",className:"text-3xl font-bold text-blue-600",children:a?.recentRegistrations||0})]}),s.jsx(ts,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:300",size:32,className:"text-blue-500/30"})]})})}),s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:304",children:s.jsx(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:305",className:"pt-6",children:s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:306",className:"flex items-center justify-between",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:307",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:308",className:"text-sm text-muted-foreground",children:"失效設備"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:309",className:"text-3xl font-bold text-gray-400",children:(a?.total||0)-(a?.active||0)})]}),s.jsx(K,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:311",size:32,className:"text-gray-300/30"})]})})})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:318",className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s.jsxs(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:319",children:[s.jsxs(E,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:320",children:[s.jsx(I,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:321",className:"text-base",children:"推送平台分佈"}),s.jsx($,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:322",children:"各推送服務的活躍設備數量"})]}),s.jsx(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:324",children:a?.byPlatform&&a.byPlatform.length>0?s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:326",className:"space-y-3",children:a.byPlatform.map(c=>s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:328",className:"flex items-center justify-between",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:329",className:"flex items-center gap-2",children:[s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:330",variant:"outline",className:"uppercase",children:c.platform}),s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:331",className:"text-sm text-muted-foreground",children:c.platform==="expo"?"Expo Push":c.platform==="fcm"?"Firebase"
1:"極光推送"})]}),s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:335",className:"font-semibold",children:c.count})]},c.platform))}):s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:340",className:"text-muted-foreground text-sm",children:"暫無數據"})})]}),s.jsxs(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:345",children:[s.jsxs(E,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:346",children:[s.jsx(I,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:347",className:"text-base",children:"設備類型分佈"}),s.jsx($,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:348",children:"iOS 與 Android 設備比例"})]}),s.jsx(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:350",children:a?.byDeviceType&&a.byDeviceType.length>0?s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:352",className:"space-y-3",children:a.byDeviceType.map(c=>{const x=a.active||1,f=Math.round(c.count/x*100);return s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:357",className:"space-y-1",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:358",className:"flex items-center justify-between text-sm",children:[s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:359",className:"capitalize font-medium",children:c.deviceType}),s.jsxs("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:360",children:[c.count," (",f,"%)"]})]}),s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:362",className:"h-2 bg-muted rounded-full overflow-hidden",children:s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:363",className:`h-full rounded-full ${c.deviceType==="ios"?"bg-blue-500":"bg-green-500"}`,style:{width:`${f}%`}})})]},c.deviceType)})}):s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:373",className:"text-muted-foreground text-sm",children:"暫無數據"})})]})]}),s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:379",className:"flex justify-end",children:s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:380",variant:"outline",size:"sm",onClick:()=>d(),children:[s.jsx(O,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:381",size:14,className:"mr-1"})," 刷新數據"]})})]})}function xs(){const[a,r]=l.useState(""),[d,c]=l.useState(""),[x,f]=l.useState("system"),[o,C]=l.useState("all"),[P,j]=l.useState(""),[h,i]=l.useState(""),[y,S]=l.useState(null),e=b.useUtils(),{data:t}=b.admin.pushNotifications.getTemplates.useQuery({activeOnly:!0}),{data:F}=b.admin.pushNotifications.getTokenStats.useQuery(),T=b.admin.pushNotifications.sendManual.useMutation({onSuccess:m=>{g.success(`推送成功!目標 ${m.targetCount} 個用戶,成功 ${m.sent},失敗 ${m.failed}`),r(""),c(""),i(""),S(null),e.admin.pushNotifications.getHistory.invalidate()},onError:m=>{g.error(`推送失敗: ${m.message}`)}}),ss=m=>{if(m==="none"){S(null);return}const M=t?.find(as=>as.id===Number(m));M&&(S(M.id),r(M.title),c(M.body),i(M.actionUrl||""),M.defaultTargetType&&C(M.defaultTargetType),g.info(`已套用模板「${M.name}」`))},is=()=>{if(!a.trim()||!d.trim()){g.error("請填寫標題和內容");return}T.mutate({title:a.trim(),body:d.trim(),notificationType:x,targetType:o,targetDetail:P||void 0,actionUrl:h||void 0,templateId:y||void 0})};return s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:449",className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:451",className:"lg:col-span-2 space-y-4",children:s.jsxs(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:452",children:[s.jsxs(E,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:453",children:[s.jsxs(I,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:454",className:"text-base flex items-center gap-2",children:[s.jsx(L,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:455",size:18,className:"text-orange-500"}),"發送推送通知"]}),s.jsx($,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:458",children:"填寫通知內容並選擇目標用戶,點擊發送即可推送"})]}),s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:460",className:"space-y-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:462",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:463",children:"快捷模板"}),s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:464",value:y?.toString()||"none",onValueChange:ss,children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:465",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:466",placeholder:"選擇模板自動填充..."})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:468",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:469",value:"none",children:"不使用模板"}),t?.map(m=>s.jsxs(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:471",value:m.id.toString(),children:[m.name," (",m.category,")"]},m.id))]})]})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:480",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:481",children:"通知標題 *"}),s.jsx(U,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:482",value:a,onChange:m=>
1r(m.target.value),placeholder:"例:系統維護通知",maxLength:200}),s.jsxs("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:488",className:"text-xs text-muted-foreground",children:[a.length,"/200"]})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:492",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:493",children:"通知內容 *"}),s.jsx(G,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:494",value:d,onChange:m=>c(m.target.value),placeholder:"通知正文內容...",rows:4})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:503",className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:504",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:505",children:"通知類型"}),s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:506",value:x,onValueChange:f,children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:507",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:508"})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:510",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:511",value:"system",children:"系統通知"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:512",value:"promotion",children:"促銷活動"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:513",value:"new_listing",children:"新盤上架"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:514",value:"price_drop",children:"降價提醒"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:515",value:"appointment_reminder",children:"預約提醒"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:516",value:"custom",children:"自定義"})]})]})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:521",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:522",children:"目標用戶"}),s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:523",value:o,onValueChange:C,children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:524",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:525"})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:527",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:528",value:"all",children:"全體用戶"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:529",value:"userType",children:"按用戶類型"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:530",value:"specific",children:"指定用戶"})]})]})]})]}),o==="userType"&&s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:538",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:539",children:"用戶類型"}),s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:540",value:P||"personal",onValueChange:j,children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:541",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:542"})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:544",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:545",value:"personal",children:"個人用戶"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:546",value:"company",children:"公司用戶"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:547",value:"developer",children:"開發商"})]})]})]}),o==="specific"&&s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:554",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:555",children:"指定用戶 ID(JSON 數組)"}),s.jsx(U,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:556",value:P,onChange:m=>
1j(m.target.value),placeholder:"例:[1, 2, 3]"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:561",className:"text-xs text-muted-foreground",children:"輸入用戶 ID 數組,格式:[1, 2, 3]"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:566",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:567",children:"跳轉連結(可選)"}),s.jsx(U,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:568",value:h,onChange:m=>i(m.target.value),placeholder:"例:/detail/123 或 /member/subscription"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:573",className:"text-xs text-muted-foreground",children:"用戶點擊通知後跳轉的頁面路徑"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:577",className:"flex items-center gap-4 pt-2",children:[s.jsx(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:578",onClick:is,disabled:T.isPending||!a.trim()||!d.trim(),className:"bg-orange-500 hover:bg-orange-600",children:T.isPending?s.jsxs(s.Fragment,{children:[s.jsx(J,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:584",size:16,className:"animate-spin mr-1"})," 發送中..."]}):s.jsxs(s.Fragment,{children:[s.jsx(L,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:586",size:16,className:"mr-1"})," 確認發送"]})}),s.jsxs("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:589",className:"text-sm text-muted-foreground",children:["預計推送至 ",s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:590",className:"font-semibold text-foreground",children:F?.active||0})," 個活躍設備"]})]})]})]})}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:598",className:"space-y-4",children:[s.jsxs(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:599",children:[s.jsx(E,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:600",children:s.jsx(I,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:601",className:"text-base",children:"發送須知"})}),s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:603",className:"space-y-3 text-sm text-muted-foreground",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:604",className:"flex items-start gap-2",children:[s.jsx(_,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:605",size:16,className:"text-amber-500 mt-0.5 shrink-0"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:606",children:"推送通知將同時發送至用戶的所有活躍設備(FCM + JPush + Expo)"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:608",className:"flex items-start gap-2",children:[s.jsx(_,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:609",size:16,className:"text-amber-500 mt-0.5 shrink-0"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:610",children:"全體推送會同時創建站內通知,用戶可在 APP 通知中心查看"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:612",className:"flex items-start gap-2",children:[s.jsx(_,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:613",size:16,className:"text-amber-500 mt-0.5 shrink-0"}),s.jsxs("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:614",children:["模板中的 ","{{variable}}"," 佔位符需手動替換為實際值"]})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:616",className:"flex items-start gap-2",children:[s.jsx(_,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:617",size:16,className:"text-amber-500 mt-0.5 shrink-0"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:618",children:"大批量推送(1000+ 用戶)可能需要 30-60 秒完成"})]})]})]}),s.jsxs(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:623",children:[s.jsx(E,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:624",children:s.jsx(I,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:625",className:"text-base",children:"通知類型說明"})}),s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:627",className:"space-y-2 text-sm",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:628",className:"flex items-center gap-2",children:[s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:629",variant:"outline",className:"text-xs",children:"系統"}),s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:630",className:"text-muted-foreground",children:"維護公告、版本更新"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:632",className:"flex items-center gap-2",children:[s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:633",variant:"outline",className:"text-xs",children:"促éŠ
1·"}),s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:634",className:"text-muted-foreground",children:"限時優惠、活動推廣"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:636",className:"flex items-center gap-2",children:[s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:637",variant:"outline",className:"text-xs",children:"新盤"}),s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:638",className:"text-muted-foreground",children:"新樓盤上架通知"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:640",className:"flex items-center gap-2",children:[s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:641",variant:"outline",className:"text-xs",children:"降價"}),s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:642",className:"text-muted-foreground",children:"收藏樓盤降價提醒"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:644",className:"flex items-center gap-2",children:[s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:645",variant:"outline",className:"text-xs",children:"預約"}),s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:646",className:"text-muted-foreground",children:"睇樓預約提醒"})]})]})]})]})]})}function hs(){const[a,r]=l.useState(1),[d,c]=l.useState(""),[x,f]=l.useState(""),{data:o,isLoading:C,refetch:P}=b.admin.pushNotifications.getHistory.useQuery({page:a,pageSize:20,status:d||void 0,triggerSource:x||void 0}),j=i=>{switch(i){case"completed":return s.jsxs(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:672",className:"bg-green-100 text-green-700",children:[s.jsx(Q,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:672",size:12,className:"mr-1"}),"已完成"]});case"failed":return s.jsxs(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:673",className:"bg-red-100 text-red-700",children:[s.jsx(K,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:673",size:12,className:"mr-1"}),"失敗"]});case"sending":return s.jsxs(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:674",className:"bg-blue-100 text-blue-700",children:[s.jsx(J,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:674",size:12,className:"mr-1 animate-spin"}),"發送中"]});case"pending":return s.jsxs(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:675",className:"bg-gray-100 text-gray-700",children:[s.jsx(es,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:675",size:12,className:"mr-1"}),"排隊中"]});default:return s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:676",variant:"outline",children:i})}},h=i=>{switch(i){case"all":return"全體用戶";case"userType":return"按類型";case"specific":return"指定用戶";default:return i}};return s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:690",className:"space-y-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:692",className:"flex items-center gap-3 flex-wrap",children:[s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:693",value:d||"all_status",onValueChange:i=>{c(i==="all_status"?"":i),r(1)},children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:694",className:"w-[140px]",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:695",placeholder:"狀態篩選"})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:697",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:698",value:"all_status",children:"全部狀態"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:699",value:"completed",children:"已完成"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:700",value:"failed",children:"失敗"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:701",value:"sending",children:"發送中"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:702",value:"pending",children:"排隊中"})]})]}),s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:706",value:x||"all_trigger",onValueChange:i=>{f(i==="all_trigger"?"":i),r(1)},children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:707",className:"w-[140px]",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:708",placeholder:"觸發方式"})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:710",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:711",value:"all_trigger",children:"全部來源"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:712",value:"manual",children:"手動發送"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:713",value:"auto",children:"自動觸發"})]})]}),s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:71
17",variant:"outline",size:"sm",onClick:()=>P(),children:[s.jsx(O,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:718",size:14,className:"mr-1"})," 刷新"]}),s.jsxs("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:721",className:"text-sm text-muted-foreground ml-auto",children:["共 ",o?.total||0," 條記錄"]})]}),C?s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:728",className:"flex items-center justify-center py-20",children:[s.jsx(J,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:729",className:"animate-spin mr-2"})," 載入中..."]}):o?.items.length?s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:739",className:"space-y-3",children:o.items.map(i=>s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:741",className:"hover:shadow-sm transition-shadow",children:s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:742",className:"py-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:743",className:"flex items-start justify-between gap-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:744",className:"flex-1 min-w-0",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:745",className:"flex items-center gap-2 mb-1",children:[j(i.status),s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:747",variant:"outline",className:"text-xs",children:i.triggerSource==="manual"?"手動":"自動"}),s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:750",variant:"outline",className:"text-xs",children:h(i.targetType)})]}),s.jsx("h4",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:754",className:"font-medium truncate",children:i.title}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:755",className:"text-sm text-muted-foreground line-clamp-1 mt-0.5",children:i.body})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:757",className:"text-right text-sm shrink-0",children:[s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:758",className:"text-muted-foreground",children:new Date(i.createdAt).toLocaleString("zh-HK")}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:761",className:"flex items-center gap-3 mt-1 justify-end",children:[s.jsxs("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:762",className:"text-xs",children:["目標 ",s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:763",className:"font-semibold",children:i.targetCount})]}),s.jsxs("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:765",className:"text-xs text-green-600",children:["成功 ",s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:766",className:"font-semibold",children:i.totalSent})]}),i.totalFailed>0&&s.jsxs("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:769",className:"text-xs text-red-600",children:["失敗 ",s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:770",className:"font-semibold",children:i.totalFailed})]})]}),i.adminUsername&&s.jsxs("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:775",className:"text-xs text-muted-foreground mt-0.5",children:["操作人:",i.adminUsername]})]})]}),i.errorMessage&&s.jsxs("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:782",className:"text-xs text-red-500 mt-2 bg-red-50 p-2 rounded",children:["錯誤:",i.errorMessage]})]})},i.id))}):s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:732",children:s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:733",className:"py-16 text-center text-muted-foreground",children:[s.jsx(R,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:734",size:48,className:"mx-auto mb-4 opacity-30"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:735",children:"暫無推送記錄"})]})}),o&&o.total>20&&s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:794",className:"flex items-center justify-center gap-2 pt-4",children:[s.jsx(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:795",variant:"outline",size:"sm",disabled:a<=1,onClick:()=>r(a-1),children:"上一頁"}),s.jsxs("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:803",className:"text-sm text-muted-foreground",children:["第 ",a," / ",Math.ceil(o.total/20)," 頁"]}),s.jsx(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:806",variant:"outline",size:"sm",disabled:a>=Math.ceil(o.total/20),onClick:()=>r(a+1),children:"下一頁"})]})]})}function us(){const[a,r]=l.useState(!1),[d,c]=l.useState(!1),[x,f]=l.useState(null),{data:o,isLoading:C,refetch:P}=b.admin.pushNotifications.getTemplates.useQuery({activeOnly:!a}),j=b.admin.pushNotifications.createTemplate.useMutation({onSuccess:()=>{g.success("模板創建成功"),P(),c(!1)},onError:t=>g.error(t.message)}),h=b.admin.pushNotifications.updateTemplate.useMutation({onSuccess:()=>{g.success("模板更新成功"),P(),c(!1)},onError:t=>g.error(t.message)}),i=b.admin.pushNotifications.deleteTemplate.useMutation({onSuccess:()=>{g.success("模板已刪除"),P()},onError:t=>g.error(t.message)}),y=()=>{f(null),c(!0)},S=t=>{f(t),c(!0)},e=t=>{switch(t){case"system":return"系統";case"promotion":return"促銷";case"new_listing":return"新盤";case"maintenance":return"維護";
1case"custom":return"自定義";default:return t}};return s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:867",className:"space-y-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:868",className:"flex items-center justify-between",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:869",className:"flex items-center gap-3",children:[s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:870",onClick:y,size:"sm",children:[s.jsx(H,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:871",size:14,className:"mr-1"})," 新增模板"]}),s.jsxs("label",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:873",className:"flex items-center gap-2 text-sm text-muted-foreground cursor-pointer",children:[s.jsx("input",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:874",type:"checkbox",checked:a,onChange:t=>r(t.target.checked),className:"rounded"}),"顯示已停用模板"]})]}),s.jsxs("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:883",className:"text-sm text-muted-foreground",children:[o?.length||0," 個模板"]})]}),C?s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:887",className:"flex items-center justify-center py-20",children:[s.jsx(J,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:888",className:"animate-spin mr-2"})," 載入中..."]}):o?.length?s.jsx("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:901",className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:o.map(t=>s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:903",className:`${t.isActive?"":"opacity-50"}`,children:s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:904",className:"pt-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:905",className:"flex items-start justify-between mb-2",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:906",children:[s.jsx("h4",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:907",className:"font-medium",children:t.name}),s.jsx(v,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:908",variant:"outline",className:"text-xs mt-1",children:e(t.category)})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:910",className:"flex items-center gap-1",children:[s.jsx(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:911",variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>S(t),children:s.jsx(ds,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:912",size:14})}),s.jsx(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:914",variant:"ghost",size:"icon",className:"h-7 w-7 text-red-500 hover:text-red-700",onClick:()=>{confirm(`確定刪除模板「${t.name}」?`)&&i.mutate({id:t.id})},children:s.jsx(os,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:924",size:14})})]})]}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:928",className:"text-sm font-medium text-foreground/80 mb-1",children:t.title}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:929",className:"text-xs text-muted-foreground line-clamp-2",children:t.body}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:930",className:"flex items-center justify-between mt-3 pt-2 border-t text-xs text-muted-foreground",children:[s.jsxs("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:931",children:["使用 ",t.usageCount," 次"]}),t.actionUrl&&s.jsx("span",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:932",className:"truncate max-w-[150px]",children:t.actionUrl})]})]})},t.id))}):s.jsx(u,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:891",children:s.jsxs(p,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:892",className:"py-16 text-center text-muted-foreground",children:[s.jsx(B,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:893",size:48,className:"mx-auto mb-4 opacity-30"}),s.jsx("p",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:894",children:"暫無通知模板"}),s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:895",onClick:y,variant:"outline",className:"mt-4",children:[s.jsx(H,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:896",size:14,className:"mr-1"})," 創建第一個模板"]})]})}),s.jsx(ps,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:941",open:d,onClose:()=>c(!1),template:x,onSave:t=>{x?h.mutate({id:x.id,...t}):j.mutate(t)},isPending:j.isPending||h.isPending})]})}function ps({open:a,onClose:r,template:d,onSave:c,isPending:x}){const[f,o]=l.useState(""),[C,P]=l.useState("custom"),[j,h]=l.useState(""),[i,y]=l.useState(""),[S,e]=l.useState(""),[t,F]=l.useState("all");return l.useMemo(()=>{d?(o(d.name||""),P(d.category||"custom"),h(d.title||""),y(d.body||""),e(d.actionUrl||""),F(d.defaultTargetType||"all")):(o(""),P("custom"),h(""),y(""),e(""),F("all"))},[d,a]),s.jsx(X,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1001",open:a,onOpenChange:r,children:s.jsxs(q,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1002",className:"max-w-lg",children:[s.jsx(W,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1003",children:s.jsx(Y,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1004",children:d?"編輯模板":"新增模板"})}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1006",className:"space-y-4 py-2",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1007",className:"grid grid-cols-2 gap-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1008",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1009",children:"模板名稱 *"}),s.jsx(U,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1010",value:f,onChange:T=>
1o(T.target.value),placeholder:"例:系統維護公告"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1012",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1013",children:"分類"}),s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1014",value:C,onValueChange:P,children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1015",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1015"})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1016",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1017",value:"system",children:"系統"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1018",value:"promotion",children:"促銷"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1019",value:"new_listing",children:"新盤"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1020",value:"maintenance",children:"維護"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1021",value:"custom",children:"自定義"})]})]})]})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1026",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1027",children:"通知標題 *"}),s.jsx(U,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1028",value:j,onChange:T=>h(T.target.value),placeholder:"通知標題(支持 {{variable}} 佔位符)"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1030",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1031",children:"通知內容 *"}),s.jsx(G,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1032",value:i,onChange:T=>y(T.target.value),placeholder:"通知正文(支持 {{variable}} 佔位符)",rows:4})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1034",className:"grid grid-cols-2 gap-4",children:[s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1035",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1036",children:"跳轉連結"}),s.jsx(U,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1037",value:S,onChange:T=>e(T.target.value),placeholder:"/detail/{{id}}"})]}),s.jsxs("div",{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1039",className:"space-y-1.5",children:[s.jsx(A,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1040",children:"預設目標"}),s.jsxs(z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1041",value:t,onValueChange:F,children:[s.jsx(w,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1042",children:s.jsx(k,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1042"})}),s.jsxs(D,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1043",children:[s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1044",value:"all",children:"全體用戶"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1045",value:"userType",children:"按用戶類型"}),s.jsx(n,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1046",value:"specific",children:"指定用戶"})]})]})]})]})]}),s.jsxs(Z,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1052",children:[s.jsx(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1053",variant:"outline",onClick:r,children:"取消"}),s.jsxs(N,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1054",onClick:()=>c({name:f,category:C,title:j,body:i,actionUrl:S||void 0,defaultTargetType:t}),disabled:x||!f.trim()||!j.trim()||!i.trim(),children:[x?s.jsx(J,{"data-loc":"client/src/pages/admin/AdminPushNotifications.tsx:1058",size:14,className:"animate-spin mr-1"}):null,d?"保存修改":"創建模板"]})]})]})})}export{_s as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.