tmex-cli 0.4.3 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{c as Z,u as B,a as ke,b as Se,r as i,d as fe,e as z,j as e,B as d,I as we,t as Ce,f as o,i as Ae}from"./index-BhBqXsZI.js";import{u as b,C as $,a as I,b as _,c as D,I as u,S as $e,d as Ie,e as _e,f as De,g as ze}from"./select-D70hG6p7.js";import{T as Ee,A as Le,a as Qe,b as Ke,c as Oe,d as Ue,e as We,f as He,g as Ve}from"./useValueChanged-CBb-JR7o.js";import{S as f,L as Ne,a as Je}from"./switch-DsyIGzyC.js";/**
1
+ import{c as Z,u as B,a as ke,b as Se,r as i,d as fe,e as z,j as e,B as d,I as we,t as Ce,f as o,i as Ae}from"./index-61hq_aNX.js";import{u as b,C as $,a as I,b as _,c as D,I as u,S as $e,d as Ie,e as _e,f as De,g as ze}from"./select-DI4HQZd4.js";import{T as Ee,A as Le,a as Qe,b as Ke,c as Oe,d as Ue,e as We,f as He,g as Ve}from"./useValueChanged-AVaPYvln.js";import{S as f,L as Ne,a as Je}from"./switch-DsfDIUrU.js";/**
2
2
  * @license lucide-react v0.564.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -14,4 +14,4 @@ import{c as Z,u as B,a as ke,b as Se,r as i,d as fe,e as z,j as e,B as d,I as we
14
14
  * This source code is licensed under the ISC license.
15
15
  * See the LICENSE file in the root directory of this source tree.
16
16
  */const Ze=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]],ve=Z("shield",Ze),Y=["terminal_bell","terminal_notification","tmux_window_close","tmux_pane_close","device_tmux_missing","device_disconnect","session_created","session_closed"];async function h(t,m){try{return(await t.json()).error??m}catch{return m}}function is(){var xe,pe,be,je;const{t}=B(),m=ke(),{refreshSettings:g}=Se(),[n,r]=i.useState("site"),x=fe(s=>s.theme),v=fe(s=>s.setTheme),w=x==="dark",[j,S]=i.useState("tmex"),[C,E]=i.useState(window.location.origin),[p,y]=i.useState("en_US"),[N,P]=i.useState(6),[M,R]=i.useState(3),[T,q]=i.useState(!0),[F,a]=i.useState(!0),[c,k]=i.useState(!0),[ee,se]=i.useState(!0),[te,ae]=i.useState(2),[ne,ie]=i.useState(10),[Te,Fe]=i.useState(!1),[Q,oe]=i.useState(""),[K,re]=i.useState(""),[Be,Pe]=i.useState(null),[O,le]=i.useState(""),[U,ce]=i.useState(""),[W,de]=i.useState(Y),Me=s=>{const l=s?"dark":"light";v(l),document.documentElement.classList.toggle("dark",l==="dark")},H=z({queryKey:["site-settings"],queryFn:async()=>{const s=await fetch("/api/settings/site");if(!s.ok)throw new Error(await h(s,t("settings.loadFailed")));return await s.json()}}),V=z({queryKey:["telegram-bots"],queryFn:async()=>{const s=await fetch("/api/settings/telegram/bots");if(!s.ok)throw new Error(await h(s,t("telegram.loadBotsFailed")));return await s.json()}});i.useEffect(()=>{var l;const s=(l=H.data)==null?void 0:l.settings;s&&(S(s.siteName),E(s.siteUrl),y(s.language??"en_US"),P(s.bellThrottleSeconds),R(s.notificationThrottleSeconds??3),q(s.enableBrowserBellToast??!0),a(s.enableBrowserNotificationToast??!0),k(s.enableTelegramBellPush??!0),se(s.enableTelegramNotificationPush??!0),ae(s.sshReconnectMaxRetries),ie(s.sshReconnectDelaySeconds))},[(xe=H.data)==null?void 0:xe.settings]);const me=b({mutationFn:async()=>{const l=await fetch("/api/settings/site",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({siteName:j,siteUrl:C,language:p,bellThrottleSeconds:N,notificationThrottleSeconds:M,enableBrowserBellToast:T,enableBrowserNotificationToast:F,enableTelegramBellPush:c,enableTelegramNotificationPush:ee,sshReconnectMaxRetries:te,sshReconnectDelaySeconds:ne})});if(!l.ok)throw new Error(await h(l,t("settings.saveFailed")))},onSuccess:async()=>{var s,l;await Promise.all([m.invalidateQueries({queryKey:["site-settings"]}),g()]),o.success(t("settings.settingsSaved")),((l=(s=H.data)==null?void 0:s.settings)==null?void 0:l.language)!==p&&(Ae.changeLanguage(p),Fe(!0))},onError:s=>{o.error(s instanceof Error?s.message:t("common.error"))}}),J=b({mutationFn:async()=>{const s=await fetch("/api/settings/telegram/bots",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:Q,token:K,enabled:!0,allowAuthRequests:!0})});if(!s.ok)throw new Error(await h(s,t("telegram.createFailed")))},onSuccess:async()=>{oe(""),re(""),await m.invalidateQueries({queryKey:["telegram-bots"]}),o.success(t("common.success"))},onError:s=>{o.error(s instanceof Error?s.message:t("common.error"))}}),he=((pe=V.data)==null?void 0:pe.bots)??[],G=z({queryKey:["webhooks"],queryFn:async()=>{const s=await fetch("/api/webhooks");if(!s.ok)throw new Error(await h(s,t("webhook.loadFailed")));return await s.json()}}),X=b({mutationFn:async()=>{const s=await fetch("/api/webhooks",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:O,secret:U,eventMask:W})});if(!s.ok)throw new Error(await h(s,t("webhook.createFailed")))},onSuccess:async()=>{le(""),ce(""),de(Y),await m.invalidateQueries({queryKey:["webhooks"]}),o.success(t("common.success"))},onError:s=>{o.error(s instanceof Error?s.message:t("common.error"))}}),ue=b({mutationFn:async s=>{const l=await fetch(`/api/webhooks/${s}`,{method:"DELETE"});if(!l.ok)throw new Error(await h(l,t("webhook.deleteFailed")))},onSuccess:async()=>{await m.invalidateQueries({queryKey:["webhooks"]}),o.success(t("common.success"))},onError:s=>{o.error(s instanceof Error?s.message:t("common.error"))}}),ge=((be=G.data)==null?void 0:be.webhooks)??[];return e.jsxs("div",{className:"mx-auto flex w-full max-w-6xl flex-col gap-4 p-3 pb-[calc(2rem+env(safe-area-inset-bottom))] sm:gap-6 sm:p-5","data-testid":"settings-page",children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(d,{type:"button",size:"sm",variant:n==="site"?"default":"outline","data-testid":"settings-tab-site",onClick:()=>r("site"),children:t("settings.siteSettings")}),e.jsx(d,{type:"button",size:"sm",variant:n==="notifications"?"default":"outline","data-testid":"settings-tab-notifications",onClick:()=>r("notifications"),children:t("settings.notificationsTab")}),e.jsx(d,{type:"button",size:"sm",variant:n==="telegram"?"default":"outline","data-testid":"settings-tab-telegram",onClick:()=>r("telegram"),children:t("telegram.title")}),e.jsx(d,{type:"button",size:"sm",variant:n==="webhooks"?"default":"outline","data-testid":"settings-tab-webhooks",onClick:()=>r("webhooks"),children:t("webhook.title")})]}),n==="site"&&e.jsxs($,{className:"border-0 ring-0",children:[e.jsx(I,{children:e.jsx(_,{children:t("settings.siteSettings")})}),e.jsxs(D,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"site-name-input",children:t("settings.siteName")}),e.jsx(u,{id:"site-name-input",value:j,onChange:s=>S(s.target.value),placeholder:t("settings.siteNamePlaceholder"),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"site-url-input",children:t("settings.siteUrl")}),e.jsx(u,{id:"site-url-input",value:C,onChange:s=>E(s.target.value),placeholder:t("settings.siteUrlPlaceholder"),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"language-select",children:t("settings.language")}),e.jsxs($e,{value:p,onValueChange:s=>{s&&y(s)},children:[e.jsx(Ie,{id:"language-select","data-testid":"settings-language-select",className:"w-full min-h-10",children:e.jsx(_e,{placeholder:t("settings.language"),children:((je=we.locales.find(s=>s.code===p))==null?void 0:je.nativeName)??p})}),e.jsx(De,{className:"max-h-[var(--tmex-viewport-height)]",children:we.locales.map(s=>e.jsx(ze,{value:s.code,children:s.nativeName},s.code))})]}),Te&&e.jsx("p",{className:"mt-1 text-xs text-primary","data-testid":"settings-refresh-notice",children:t("settings.refreshToApply")})]}),e.jsx("div",{className:"space-y-3",children:e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:t("settings.theme")})}),e.jsx(f,{checked:w,onCheckedChange:s=>Me(!!s),"data-testid":"settings-theme-toggle"})]})})]})]}),n==="notifications"&&e.jsxs($,{className:"border-0 ring-0",children:[e.jsx(I,{children:e.jsx(_,{children:t("settings.notificationsTab")})}),e.jsxs(D,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:t("settings.enableBrowserBellToast")})}),e.jsx(f,{checked:T,onCheckedChange:s=>q(!!s),"data-testid":"settings-enable-browser-bell-toast"})]}),e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:t("settings.enableTelegramBellPush")})}),e.jsx(f,{checked:c,onCheckedChange:s=>k(!!s),"data-testid":"settings-enable-telegram-bell-push"})]}),e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:t("settings.enableBrowserNotificationToast")})}),e.jsx(f,{checked:F,onCheckedChange:s=>a(!!s),"data-testid":"settings-enable-browser-notification-toast"})]}),e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsx("div",{className:"min-w-0 pr-2",children:e.jsx("div",{className:"text-sm font-medium",children:t("settings.enableTelegramNotificationPush")})}),e.jsx(f,{checked:ee,onCheckedChange:s=>se(!!s),"data-testid":"settings-enable-telegram-notification-push"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-3",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"bell-throttle-input",children:t("settings.bellThrottle")}),e.jsx(u,{id:"bell-throttle-input",type:"number",value:N,min:0,max:300,onChange:s=>P(Number(s.target.value)),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"notification-throttle-input",children:t("settings.notificationThrottle")}),e.jsx(u,{id:"notification-throttle-input",type:"number",value:M,min:0,max:300,onChange:s=>R(Number(s.target.value)),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"ssh-reconnect-retries-input",children:t("settings.sshReconnectMaxRetries")}),e.jsx(u,{id:"ssh-reconnect-retries-input",type:"number",value:te,min:0,max:20,onChange:s=>ae(Number(s.target.value)),className:"min-h-10"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"ssh-reconnect-delay-input",children:t("settings.sshReconnectDelay")}),e.jsx(u,{id:"ssh-reconnect-delay-input",type:"number",value:ne,min:1,max:300,onChange:s=>ie(Number(s.target.value)),className:"min-h-10"})]})]})]})]}),n==="telegram"&&e.jsxs($,{className:"border-0 ring-0",children:[e.jsx(I,{children:e.jsx(_,{children:t("telegram.title")})}),e.jsxs(D,{className:"space-y-6",children:[e.jsx("div",{className:"space-y-4",children:e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end",children:[e.jsxs("div",{className:"md:col-span-4 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"new-bot-name",children:t("telegram.botName")}),e.jsx(u,{id:"new-bot-name",value:Q,onChange:s=>oe(s.target.value),placeholder:t("telegram.botNamePlaceholder"),className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-6 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"new-bot-token",children:t("telegram.botToken")}),e.jsx(u,{id:"new-bot-token",type:"password",value:K,onChange:s=>re(s.target.value),placeholder:t("telegram.botTokenPlaceholder"),className:"min-h-10"})]}),e.jsx("div",{className:"md:col-span-2",children:e.jsxs(d,{variant:"default",className:"w-full md:w-auto","data-testid":"telegram-add-bot",onClick:()=>J.mutate(),disabled:J.isPending||!Q.trim()||!K.trim(),children:[J.isPending?e.jsx(Ne,{className:"h-4 w-4 animate-spin"}):e.jsx(L,{className:"h-4 w-4"}),t("telegram.addBot")]})})]})}),e.jsxs("div",{className:"space-y-3",children:[V.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("common.loading")}),!V.isLoading&&he.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("telegram.addBot")}),he.map(s=>e.jsx(es,{bot:s,expanded:Be===s.id,onToggleExpand:()=>{Pe(l=>l===s.id?null:s.id)}},s.id))]})]})]}),n==="webhooks"&&e.jsxs($,{className:"border-0 ring-0",children:[e.jsx(I,{children:e.jsx(_,{children:t("webhook.title")})}),e.jsxs(D,{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end",children:[e.jsxs("div",{className:"md:col-span-6 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"webhook-url-input",children:t("webhook.url")}),e.jsx(u,{id:"webhook-url-input","data-testid":"webhook-url-input",value:O,onChange:s=>le(s.target.value),placeholder:"https://example.com/webhook",className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-4 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"webhook-secret-input",children:t("webhook.secret")}),e.jsx(u,{id:"webhook-secret-input","data-testid":"webhook-secret-input",value:U,onChange:s=>ce(s.target.value),placeholder:t("webhook.secretPlaceholder"),className:"min-h-10"})]}),e.jsx("div",{className:"md:col-span-2",children:e.jsxs(d,{variant:"default",className:"w-full md:w-auto","data-testid":"webhook-add",onClick:()=>X.mutate(),disabled:X.isPending||!O.trim()||!U.trim()||W.length===0,children:[X.isPending?e.jsx(Ne,{className:"h-4 w-4 animate-spin"}):e.jsx(L,{className:"h-4 w-4"}),t("webhook.add")]})})]}),e.jsxs("div",{className:"space-y-3 rounded-lg border border-border bg-card px-4 py-3",children:[e.jsx("div",{className:"text-sm font-medium",children:t("webhook.eventMask")}),e.jsx("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:Y.map(s=>{const l=W.includes(s);return e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-background px-3 py-2",children:[e.jsx("div",{className:"min-w-0 pr-2 text-sm font-medium",children:t(`notification.eventType.${s}`)}),e.jsx(f,{checked:l,"data-testid":`webhook-event-${s}`,onCheckedChange:Re=>{de(A=>Re?A.includes(s)?A:[...A,s]:A.filter(qe=>qe!==s))}})]},s)})})]}),e.jsxs("div",{className:"space-y-2",children:[G.isLoading&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("common.loading")}),!G.isLoading&&ge.length===0&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t("webhook.empty")}),ge.map(s=>e.jsxs("div",{"data-testid":"webhook-item","data-webhook-url":s.url,className:"flex items-center justify-between gap-3 rounded-lg border border-border bg-card px-4 py-2.5",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-sm font-medium",children:s.url}),e.jsx("div",{className:"text-xs text-muted-foreground",children:new Date(s.createdAt).toLocaleString(Ce(p))})]}),e.jsx(d,{variant:"ghost",size:"icon-sm","data-testid":"webhook-delete",onClick:()=>ue.mutate(s.id),disabled:ue.isPending,"aria-label":t("common.delete"),title:t("common.delete"),children:e.jsx(Ee,{className:"h-4 w-4"})})]},s.id))]})]})]}),(n==="site"||n==="notifications")&&e.jsx("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end",children:e.jsxs(d,{variant:"default","data-testid":"settings-save",onClick:()=>me.mutate(),disabled:me.isPending,className:"w-full sm:w-auto",children:[e.jsx(L,{className:"h-4 w-4"}),t("common.save")]})})]})}function es({bot:t,expanded:m,onToggleExpand:g}){var F;const{t:n}=B(),r=ke(),[x,v]=i.useState(t.name),[w,j]=i.useState(""),[S,C]=i.useState(t.enabled),[E,p]=i.useState(t.allowAuthRequests);i.useEffect(()=>{v(t.name),C(t.enabled),p(t.allowAuthRequests)},[t.allowAuthRequests,t.enabled,t.name]);const y=z({queryKey:["telegram-bot-chats",t.id],enabled:m,queryFn:async()=>{const a=await fetch(`/api/settings/telegram/bots/${t.id}/chats`);if(!a.ok)throw new Error(await h(a,n("telegram.loadChatsFailed")));return await a.json()}}),N=i.useMemo(()=>{var c;const a=((c=y.data)==null?void 0:c.chats)??[];return{pending:a.filter(k=>k.status==="pending"),authorized:a.filter(k=>k.status==="authorized")}},[(F=y.data)==null?void 0:F.chats]),P=b({mutationFn:async()=>{const a={name:x,enabled:S,allowAuthRequests:E};w.trim()&&(a.token=w.trim());const c=await fetch(`/api/settings/telegram/bots/${t.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!c.ok)throw new Error(await h(c,n("telegram.updateFailed")))},onSuccess:async()=>{j(""),await r.invalidateQueries({queryKey:["telegram-bots"]}),o.success(n("common.success"))},onError:a=>{o.error(a instanceof Error?a.message:n("common.error"))}}),M=b({mutationFn:async()=>{const a=await fetch(`/api/settings/telegram/bots/${t.id}`,{method:"DELETE"});if(!a.ok)throw new Error(await h(a,n("telegram.deleteFailed")))},onSuccess:async()=>{await r.invalidateQueries({queryKey:["telegram-bots"]}),o.success(n("common.success"))},onError:a=>{o.error(a instanceof Error?a.message:n("common.error"))}}),R=b({mutationFn:async a=>{const c=await fetch(`/api/settings/telegram/bots/${t.id}/chats/${encodeURIComponent(a)}/approve`,{method:"POST"});if(!c.ok)throw new Error(await h(c,n("telegram.approveFailed")))},onSuccess:async()=>{await Promise.all([r.invalidateQueries({queryKey:["telegram-bots"]}),r.invalidateQueries({queryKey:["telegram-bot-chats",t.id]})]),o.success(n("common.success"))},onError:a=>{o.error(a instanceof Error?a.message:n("common.error"))}}),T=b({mutationFn:async a=>{const c=await fetch(`/api/settings/telegram/bots/${t.id}/chats/${encodeURIComponent(a)}`,{method:"DELETE"});if(!c.ok)throw new Error(await h(c,n("telegram.removeFailed")))},onSuccess:async()=>{await Promise.all([r.invalidateQueries({queryKey:["telegram-bots"]}),r.invalidateQueries({queryKey:["telegram-bot-chats",t.id]})]),o.success(n("common.success"))},onError:a=>{o.error(a instanceof Error?a.message:n("common.error"))}}),q=b({mutationFn:async a=>{const c=await fetch(`/api/settings/telegram/bots/${t.id}/chats/${encodeURIComponent(a)}/test`,{method:"POST"});if(!c.ok)throw new Error(await h(c,n("telegram.testMessageFailed")))},onSuccess:()=>{o.success(n("common.success"))},onError:a=>{o.error(a instanceof Error?a.message:n("common.error"))}});return e.jsxs("div",{className:"space-y-4 rounded-md border-0 bg-card p-4","data-testid":`telegram-bot-card-${t.id}`,"data-bot-name":t.name,children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:t.name}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[t.authorizedCount," / ",t.pendingCount]})]}),e.jsx(d,{variant:"ghost","data-testid":`telegram-bot-toggle-${t.id}`,onClick:g,children:n(m?"common.collapse":"common.expand")})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end",children:[e.jsxs("div",{className:"md:col-span-3 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:`bot-name-${t.id}`,children:n("telegram.botName")}),e.jsx(u,{id:`bot-name-${t.id}`,value:x,onChange:a=>v(a.target.value),className:"min-h-10"})]}),e.jsxs("div",{className:"md:col-span-4 space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:`bot-token-${t.id}`,children:n("telegram.botToken")}),e.jsx(u,{id:`bot-token-${t.id}`,type:"password",value:w,onChange:a=>j(a.target.value),placeholder:n("telegram.tokenPlaceholder"),className:"min-h-10"})]}),e.jsx("div",{className:"md:col-span-2",children:e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2.5",children:[e.jsx("span",{className:"text-sm font-medium",children:n("common.enabled")}),e.jsx(f,{checked:S,onCheckedChange:a=>C(!!a)})]})}),e.jsx("div",{className:"md:col-span-3",children:e.jsxs("div",{className:"flex min-h-10 items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2.5",children:[e.jsx("span",{className:"text-sm font-medium",children:n("telegram.allowAuthRequests")}),e.jsx(f,{checked:E,onCheckedChange:a=>p(!!a)})]})})]}),e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end",children:[e.jsxs(d,{variant:"destructive","data-testid":`telegram-bot-delete-${t.id}`,onClick:()=>M.mutate(),className:"w-full sm:w-auto",children:[e.jsx(Ee,{className:"h-4 w-4"}),n("telegram.deleteBot")]}),e.jsxs(d,{variant:"default","data-testid":`telegram-bot-save-${t.id}`,onClick:()=>P.mutate(),className:"w-full sm:w-auto",children:[e.jsx(L,{className:"h-4 w-4"}),n("common.save")]})]}),m&&e.jsxs("div",{className:"grid grid-cols-1 gap-4 border-t border-border pt-4 lg:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("h3",{className:"text-sm font-semibold flex items-center gap-1",children:[e.jsx(ve,{className:"h-4 w-4"}),n("telegram.pendingChats")]}),N.pending.length===0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"-"}),N.pending.map(a=>e.jsx(ye,{chat:a,pending:!0,onApprove:()=>R.mutate(a.chatId),onDelete:()=>T.mutate(a.chatId)},`${a.botId}-${a.chatId}`))]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("h3",{className:"text-sm font-semibold flex items-center gap-1",children:[e.jsx(ve,{className:"h-4 w-4"}),n("telegram.chats")]}),N.authorized.length===0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"-"}),N.authorized.map(a=>e.jsx(ye,{chat:a,pending:!1,onTest:()=>q.mutate(a.chatId),onDelete:()=>T.mutate(a.chatId)},`${a.botId}-${a.chatId}`))]}),y.isLoading&&e.jsx("div",{className:"lg:col-span-2 text-xs text-muted-foreground",children:n("common.loading")})]})]})}function ye({chat:t,pending:m,onApprove:g,onDelete:n,onTest:r}){const{t:x}=B(),v=Se(w=>{var j;return((j=w.settings)==null?void 0:j.language)??"en_US"});return e.jsxs("div",{className:"space-y-2 rounded border-0 bg-background p-3",children:[e.jsx("div",{className:"text-sm font-medium truncate",title:t.displayName,children:t.displayName}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[x("telegram.chatId"),":",t.chatId]}),e.jsx("div",{className:"text-xs text-muted-foreground",children:new Date(t.appliedAt).toLocaleString(Ce(v))}),e.jsx("div",{className:"flex items-center justify-end gap-2 pt-1",children:m?e.jsxs(e.Fragment,{children:[e.jsx(d,{variant:"outline",size:"sm",onClick:n,children:x("telegram.reject")}),e.jsx(d,{variant:"default",size:"sm",onClick:g,children:x("telegram.authorize")})]}):e.jsxs(e.Fragment,{children:[e.jsxs(d,{variant:"secondary",size:"sm",onClick:r,children:[e.jsx(Je,{className:"h-3.5 w-3.5"}),x("telegram.sendTestMessage")]}),e.jsx(d,{variant:"destructive",size:"sm",onClick:n,children:x("common.delete")})]})})]})}function os(){const{t}=B();return e.jsx(e.Fragment,{children:t("sidebar.settings")})}function rs(){const{t}=B(),[m,g]=i.useState(!1),n=b({mutationFn:async()=>{const r=await fetch("/api/settings/restart",{method:"POST"});if(!r.ok)throw new Error(await h(r,t("settings.restartFailed")))},onSuccess:()=>{o.success(t("settings.restartScheduled"))},onError:r=>{o.error(r instanceof Error?r.message:t("common.error"))}});return e.jsxs(e.Fragment,{children:[e.jsx(d,{variant:"ghost",size:"icon-sm",onClick:()=>g(!0),disabled:n.isPending,"aria-label":t("settings.restartGateway"),title:t("settings.restartGateway"),className:"text-destructive hover:text-destructive hover:bg-destructive/10",children:e.jsx(Xe,{className:"h-4 w-4"})}),e.jsx(Le,{open:m,onOpenChange:g,children:e.jsxs(Qe,{children:[e.jsxs(Ke,{children:[e.jsx(Oe,{children:t("settings.restartGateway")}),e.jsx(Ue,{children:t("settings.restartConfirm")})]}),e.jsxs(We,{children:[e.jsx(He,{onClick:()=>g(!1),children:t("common.cancel")}),e.jsx(Ve,{variant:"destructive",onClick:()=>{n.mutate(),g(!1)},children:t("common.confirm")})]})]})})]})}export{rs as PageActions,os as PageTitle,is as default};
17
- //# sourceMappingURL=SettingsPage-BRs8Unfx.js.map
17
+ //# sourceMappingURL=SettingsPage-DwpbDA_e.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsPage-BRs8Unfx.js","sources":["../../../../node_modules/.bun/lucide-react@0.564.0+b1ab299f0a400331/node_modules/lucide-react/dist/esm/icons/rotate-ccw.js","../../../../node_modules/.bun/lucide-react@0.564.0+b1ab299f0a400331/node_modules/lucide-react/dist/esm/icons/save.js","../../../../node_modules/.bun/lucide-react@0.564.0+b1ab299f0a400331/node_modules/lucide-react/dist/esm/icons/shield.js","../../src/pages/SettingsPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.564.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"1357e3\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }]\n];\nconst RotateCcw = createLucideIcon(\"rotate-ccw\", __iconNode);\n\nexport { __iconNode, RotateCcw as default };\n//# sourceMappingURL=rotate-ccw.js.map\n","/**\n * @license lucide-react v0.564.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n 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\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n];\nconst Save = createLucideIcon(\"save\", __iconNode);\n\nexport { __iconNode, Save as default };\n//# sourceMappingURL=save.js.map\n","/**\n * @license lucide-react v0.564.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ]\n];\nconst Shield = createLucideIcon(\"shield\", __iconNode);\n\nexport { __iconNode, Shield as default };\n//# sourceMappingURL=shield.js.map\n","import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport type {\n EventType,\n LocaleCode,\n SiteSettings,\n TelegramBotChat,\n TelegramBotWithStats,\n UpdateSiteSettingsRequest,\n WebhookEndpoint,\n} from '@tmex/shared';\nimport { I18N_MANIFEST, toBCP47 as toBCP47Locale } from '@tmex/shared';\nimport { Loader2, RotateCcw, Save, Send, Shield, Trash2 } from 'lucide-react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport i18n from '../i18n';\nimport { toast } from 'sonner';\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@/components/ui/alert-dialog';\nimport { Button } from '@/components/ui/button';\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';\nimport { Input } from '@/components/ui/input';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select';\nimport { Switch } from '@/components/ui/switch';\nimport { useSiteStore } from '../stores/site';\nimport { useUIStore } from '../stores/ui';\n\ninterface TelegramBotsResponse {\n bots: TelegramBotWithStats[];\n}\n\ninterface TelegramChatsResponse {\n chats: TelegramBotChat[];\n}\n\ninterface SiteSettingsResponse {\n settings: SiteSettings;\n}\n\ninterface WebhooksResponse {\n webhooks: WebhookEndpoint[];\n}\n\nconst WEBHOOK_EVENT_OPTIONS: EventType[] = [\n 'terminal_bell',\n 'terminal_notification',\n 'tmux_window_close',\n 'tmux_pane_close',\n 'device_tmux_missing',\n 'device_disconnect',\n 'session_created',\n 'session_closed',\n];\n\nasync function parseApiError(res: Response, fallback: string): Promise<string> {\n try {\n const payload = (await res.json()) as { error?: string };\n return payload.error ?? fallback;\n } catch {\n return fallback;\n }\n}\n\nexport default function SettingsPage() {\n const { t } = useTranslation();\n const queryClient = useQueryClient();\n const { refreshSettings } = useSiteStore();\n\n const [activeTab, setActiveTab] = useState<'site' | 'notifications' | 'telegram' | 'webhooks'>(\n 'site'\n );\n\n const theme = useUIStore((state) => state.theme);\n const setTheme = useUIStore((state) => state.setTheme);\n const isDark = theme === 'dark';\n\n // Site settings state\n const [siteName, setSiteName] = useState('tmex');\n const [siteUrl, setSiteUrl] = useState(window.location.origin);\n const [language, setLanguage] = useState<LocaleCode>('en_US');\n\n // Notifications state\n const [bellThrottleSeconds, setBellThrottleSeconds] = useState(6);\n const [notificationThrottleSeconds, setNotificationThrottleSeconds] = useState(3);\n const [enableBrowserBellToast, setEnableBrowserBellToast] = useState(true);\n const [enableBrowserNotificationToast, setEnableBrowserNotificationToast] = useState(true);\n const [enableTelegramBellPush, setEnableTelegramBellPush] = useState(true);\n const [enableTelegramNotificationPush, setEnableTelegramNotificationPush] = useState(true);\n const [sshReconnectMaxRetries, setSshReconnectMaxRetries] = useState(2);\n const [sshReconnectDelaySeconds, setSshReconnectDelaySeconds] = useState(10);\n const [showRefreshNotice, setShowRefreshNotice] = useState(false);\n\n // Telegram state\n const [newBotName, setNewBotName] = useState('');\n const [newBotToken, setNewBotToken] = useState('');\n const [expandedBotId, setExpandedBotId] = useState<string | null>(null);\n\n // Webhook state\n const [newWebhookUrl, setNewWebhookUrl] = useState('');\n const [newWebhookSecret, setNewWebhookSecret] = useState('');\n const [newWebhookEventMask, setNewWebhookEventMask] = useState<EventType[]>(WEBHOOK_EVENT_OPTIONS);\n\n const handleThemeChange = (checked: boolean) => {\n const nextTheme = checked ? 'dark' : 'light';\n setTheme(nextTheme);\n document.documentElement.classList.toggle('dark', nextTheme === 'dark');\n };\n\n const settingsQuery = useQuery({\n queryKey: ['site-settings'],\n queryFn: async () => {\n const res = await fetch('/api/settings/site');\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('settings.loadFailed')));\n }\n return (await res.json()) as SiteSettingsResponse;\n },\n });\n\n const botsQuery = useQuery({\n queryKey: ['telegram-bots'],\n queryFn: async () => {\n const res = await fetch('/api/settings/telegram/bots');\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.loadBotsFailed')));\n }\n return (await res.json()) as TelegramBotsResponse;\n },\n });\n\n useEffect(() => {\n const settings = settingsQuery.data?.settings;\n if (!settings) {\n return;\n }\n\n setSiteName(settings.siteName);\n setSiteUrl(settings.siteUrl);\n setLanguage(settings.language ?? 'en_US');\n setBellThrottleSeconds(settings.bellThrottleSeconds);\n setNotificationThrottleSeconds(settings.notificationThrottleSeconds ?? 3);\n setEnableBrowserBellToast(settings.enableBrowserBellToast ?? true);\n setEnableBrowserNotificationToast(settings.enableBrowserNotificationToast ?? true);\n setEnableTelegramBellPush(settings.enableTelegramBellPush ?? true);\n setEnableTelegramNotificationPush(settings.enableTelegramNotificationPush ?? true);\n setSshReconnectMaxRetries(settings.sshReconnectMaxRetries);\n setSshReconnectDelaySeconds(settings.sshReconnectDelaySeconds);\n }, [settingsQuery.data?.settings]);\n\n const saveSiteMutation = useMutation({\n mutationFn: async () => {\n const payload: UpdateSiteSettingsRequest = {\n siteName,\n siteUrl,\n language,\n bellThrottleSeconds,\n notificationThrottleSeconds,\n enableBrowserBellToast,\n enableBrowserNotificationToast,\n enableTelegramBellPush,\n enableTelegramNotificationPush,\n sshReconnectMaxRetries,\n sshReconnectDelaySeconds,\n };\n\n const res = await fetch('/api/settings/site', {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('settings.saveFailed')));\n }\n },\n onSuccess: async () => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: ['site-settings'] }),\n refreshSettings(),\n ]);\n toast.success(t('settings.settingsSaved'));\n if (settingsQuery.data?.settings?.language !== language) {\n void i18n.changeLanguage(language);\n setShowRefreshNotice(true);\n }\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const createBotMutation = useMutation({\n mutationFn: async () => {\n const res = await fetch('/api/settings/telegram/bots', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name: newBotName,\n token: newBotToken,\n enabled: true,\n allowAuthRequests: true,\n }),\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.createFailed')));\n }\n },\n onSuccess: async () => {\n setNewBotName('');\n setNewBotToken('');\n await queryClient.invalidateQueries({ queryKey: ['telegram-bots'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const bots = botsQuery.data?.bots ?? [];\n\n const webhooksQuery = useQuery({\n queryKey: ['webhooks'],\n queryFn: async () => {\n const res = await fetch('/api/webhooks');\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('webhook.loadFailed')));\n }\n return (await res.json()) as WebhooksResponse;\n },\n });\n\n const createWebhookMutation = useMutation({\n mutationFn: async () => {\n const res = await fetch('/api/webhooks', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n url: newWebhookUrl,\n secret: newWebhookSecret,\n eventMask: newWebhookEventMask,\n }),\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('webhook.createFailed')));\n }\n },\n onSuccess: async () => {\n setNewWebhookUrl('');\n setNewWebhookSecret('');\n setNewWebhookEventMask(WEBHOOK_EVENT_OPTIONS);\n await queryClient.invalidateQueries({ queryKey: ['webhooks'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const deleteWebhookMutation = useMutation({\n mutationFn: async (id: string) => {\n const res = await fetch(`/api/webhooks/${id}`, { method: 'DELETE' });\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('webhook.deleteFailed')));\n }\n },\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: ['webhooks'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const webhooks = webhooksQuery.data?.webhooks ?? [];\n\n return (\n <div\n className=\"mx-auto flex w-full max-w-6xl flex-col gap-4 p-3 pb-[calc(2rem+env(safe-area-inset-bottom))] sm:gap-6 sm:p-5\"\n data-testid=\"settings-page\"\n >\n <div className=\"flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant={activeTab === 'site' ? 'default' : 'outline'}\n data-testid=\"settings-tab-site\"\n onClick={() => setActiveTab('site')}\n >\n {t('settings.siteSettings')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={activeTab === 'notifications' ? 'default' : 'outline'}\n data-testid=\"settings-tab-notifications\"\n onClick={() => setActiveTab('notifications')}\n >\n {t('settings.notificationsTab')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={activeTab === 'telegram' ? 'default' : 'outline'}\n data-testid=\"settings-tab-telegram\"\n onClick={() => setActiveTab('telegram')}\n >\n {t('telegram.title')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={activeTab === 'webhooks' ? 'default' : 'outline'}\n data-testid=\"settings-tab-webhooks\"\n onClick={() => setActiveTab('webhooks')}\n >\n {t('webhook.title')}\n </Button>\n </div>\n\n {activeTab === 'site' && (\n <Card className=\"border-0 ring-0\">\n <CardHeader>\n <CardTitle>{t('settings.siteSettings')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"site-name-input\">\n {t('settings.siteName')}\n </label>\n <Input\n id=\"site-name-input\"\n value={siteName}\n onChange={(event) => setSiteName(event.target.value)}\n placeholder={t('settings.siteNamePlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"site-url-input\">\n {t('settings.siteUrl')}\n </label>\n <Input\n id=\"site-url-input\"\n value={siteUrl}\n onChange={(event) => setSiteUrl(event.target.value)}\n placeholder={t('settings.siteUrlPlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"language-select\">\n {t('settings.language')}\n </label>\n <Select\n value={language}\n onValueChange={(nextValue) => {\n if (!nextValue) return;\n setLanguage(nextValue as LocaleCode);\n }}\n >\n <SelectTrigger\n id=\"language-select\"\n data-testid=\"settings-language-select\"\n className=\"w-full min-h-10\"\n >\n <SelectValue placeholder={t('settings.language')}>\n {I18N_MANIFEST.locales.find((l) => l.code === language)?.nativeName ?? language}\n </SelectValue>\n </SelectTrigger>\n <SelectContent className=\"max-h-[var(--tmex-viewport-height)]\">\n {I18N_MANIFEST.locales.map((locale) => (\n <SelectItem key={locale.code} value={locale.code}>\n {locale.nativeName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {showRefreshNotice && (\n <p className=\"mt-1 text-xs text-primary\" data-testid=\"settings-refresh-notice\">\n {t('settings.refreshToApply')}\n </p>\n )}\n </div>\n\n <div className=\"space-y-3\">\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">{t('settings.theme')}</div>\n </div>\n <Switch\n checked={isDark}\n onCheckedChange={(checked) => handleThemeChange(Boolean(checked))}\n data-testid=\"settings-theme-toggle\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n {activeTab === 'notifications' && (\n <Card className=\"border-0 ring-0\">\n <CardHeader>\n <CardTitle>{t('settings.notificationsTab')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"space-y-3\">\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">{t('settings.enableBrowserBellToast')}</div>\n </div>\n <Switch\n checked={enableBrowserBellToast}\n onCheckedChange={(checked) => setEnableBrowserBellToast(Boolean(checked))}\n data-testid=\"settings-enable-browser-bell-toast\"\n />\n </div>\n\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">{t('settings.enableTelegramBellPush')}</div>\n </div>\n <Switch\n checked={enableTelegramBellPush}\n onCheckedChange={(checked) => setEnableTelegramBellPush(Boolean(checked))}\n data-testid=\"settings-enable-telegram-bell-push\"\n />\n </div>\n\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">\n {t('settings.enableBrowserNotificationToast')}\n </div>\n </div>\n <Switch\n checked={enableBrowserNotificationToast}\n onCheckedChange={(checked) => setEnableBrowserNotificationToast(Boolean(checked))}\n data-testid=\"settings-enable-browser-notification-toast\"\n />\n </div>\n\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">\n {t('settings.enableTelegramNotificationPush')}\n </div>\n </div>\n <Switch\n checked={enableTelegramNotificationPush}\n onCheckedChange={(checked) => setEnableTelegramNotificationPush(Boolean(checked))}\n data-testid=\"settings-enable-telegram-notification-push\"\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"bell-throttle-input\">\n {t('settings.bellThrottle')}\n </label>\n <Input\n id=\"bell-throttle-input\"\n type=\"number\"\n value={bellThrottleSeconds}\n min={0}\n max={300}\n onChange={(event) => setBellThrottleSeconds(Number(event.target.value))}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"notification-throttle-input\">\n {t('settings.notificationThrottle')}\n </label>\n <Input\n id=\"notification-throttle-input\"\n type=\"number\"\n value={notificationThrottleSeconds}\n min={0}\n max={300}\n onChange={(event) => setNotificationThrottleSeconds(Number(event.target.value))}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"ssh-reconnect-retries-input\">\n {t('settings.sshReconnectMaxRetries')}\n </label>\n <Input\n id=\"ssh-reconnect-retries-input\"\n type=\"number\"\n value={sshReconnectMaxRetries}\n min={0}\n max={20}\n onChange={(event) => setSshReconnectMaxRetries(Number(event.target.value))}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"ssh-reconnect-delay-input\">\n {t('settings.sshReconnectDelay')}\n </label>\n <Input\n id=\"ssh-reconnect-delay-input\"\n type=\"number\"\n value={sshReconnectDelaySeconds}\n min={1}\n max={300}\n onChange={(event) => setSshReconnectDelaySeconds(Number(event.target.value))}\n className=\"min-h-10\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n {activeTab === 'telegram' && (\n <Card className=\"border-0 ring-0\">\n <CardHeader>\n <CardTitle>{t('telegram.title')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end\">\n <div className=\"md:col-span-4 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"new-bot-name\">\n {t('telegram.botName')}\n </label>\n <Input\n id=\"new-bot-name\"\n value={newBotName}\n onChange={(event) => setNewBotName(event.target.value)}\n placeholder={t('telegram.botNamePlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"md:col-span-6 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"new-bot-token\">\n {t('telegram.botToken')}\n </label>\n <Input\n id=\"new-bot-token\"\n type=\"password\"\n value={newBotToken}\n onChange={(event) => setNewBotToken(event.target.value)}\n placeholder={t('telegram.botTokenPlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"md:col-span-2\">\n <Button\n variant=\"default\"\n className=\"w-full md:w-auto\"\n data-testid=\"telegram-add-bot\"\n onClick={() => createBotMutation.mutate()}\n disabled={\n createBotMutation.isPending || !newBotName.trim() || !newBotToken.trim()\n }\n >\n {createBotMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n {t('telegram.addBot')}\n </Button>\n </div>\n </div>\n </div>\n\n <div className=\"space-y-3\">\n {botsQuery.isLoading && (\n <div className=\"text-sm text-muted-foreground\">{t('common.loading')}</div>\n )}\n\n {!botsQuery.isLoading && bots.length === 0 && (\n <div className=\"text-sm text-muted-foreground\">{t('telegram.addBot')}</div>\n )}\n\n {bots.map((bot) => (\n <BotCard\n key={bot.id}\n bot={bot}\n expanded={expandedBotId === bot.id}\n onToggleExpand={() => {\n setExpandedBotId((prev) => (prev === bot.id ? null : bot.id));\n }}\n />\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n\n {activeTab === 'webhooks' && (\n <Card className=\"border-0 ring-0\">\n <CardHeader>\n <CardTitle>{t('webhook.title')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end\">\n <div className=\"md:col-span-6 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"webhook-url-input\">\n {t('webhook.url')}\n </label>\n <Input\n id=\"webhook-url-input\"\n data-testid=\"webhook-url-input\"\n value={newWebhookUrl}\n onChange={(event) => setNewWebhookUrl(event.target.value)}\n placeholder=\"https://example.com/webhook\"\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"md:col-span-4 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"webhook-secret-input\">\n {t('webhook.secret')}\n </label>\n <Input\n id=\"webhook-secret-input\"\n data-testid=\"webhook-secret-input\"\n value={newWebhookSecret}\n onChange={(event) => setNewWebhookSecret(event.target.value)}\n placeholder={t('webhook.secretPlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"md:col-span-2\">\n <Button\n variant=\"default\"\n className=\"w-full md:w-auto\"\n data-testid=\"webhook-add\"\n onClick={() => createWebhookMutation.mutate()}\n disabled={\n createWebhookMutation.isPending ||\n !newWebhookUrl.trim() ||\n !newWebhookSecret.trim() ||\n newWebhookEventMask.length === 0\n }\n >\n {createWebhookMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n {t('webhook.add')}\n </Button>\n </div>\n </div>\n\n <div className=\"space-y-3 rounded-lg border border-border bg-card px-4 py-3\">\n <div className=\"text-sm font-medium\">{t('webhook.eventMask')}</div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {WEBHOOK_EVENT_OPTIONS.map((eventType) => {\n const checked = newWebhookEventMask.includes(eventType);\n return (\n <div\n key={eventType}\n className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-background px-3 py-2\"\n >\n <div className=\"min-w-0 pr-2 text-sm font-medium\">\n {t(`notification.eventType.${eventType}` as const)}\n </div>\n <Switch\n checked={checked}\n data-testid={`webhook-event-${eventType}`}\n onCheckedChange={(nextChecked) => {\n setNewWebhookEventMask((prev) => {\n if (nextChecked) {\n return prev.includes(eventType) ? prev : [...prev, eventType];\n }\n return prev.filter((item) => item !== eventType);\n });\n }}\n />\n </div>\n );\n })}\n </div>\n </div>\n\n <div className=\"space-y-2\">\n {webhooksQuery.isLoading && (\n <div className=\"text-sm text-muted-foreground\">{t('common.loading')}</div>\n )}\n\n {!webhooksQuery.isLoading && webhooks.length === 0 && (\n <div className=\"text-sm text-muted-foreground\">{t('webhook.empty')}</div>\n )}\n\n {webhooks.map((webhook) => (\n <div\n key={webhook.id}\n data-testid=\"webhook-item\"\n data-webhook-url={webhook.url}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border bg-card px-4 py-2.5\"\n >\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">{webhook.url}</div>\n <div className=\"text-xs text-muted-foreground\">\n {new Date(webhook.createdAt).toLocaleString(toBCP47Locale(language))}\n </div>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n data-testid=\"webhook-delete\"\n onClick={() => deleteWebhookMutation.mutate(webhook.id)}\n disabled={deleteWebhookMutation.isPending}\n aria-label={t('common.delete')}\n title={t('common.delete')}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n\n {(activeTab === 'site' || activeTab === 'notifications') && (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end\">\n <Button\n variant=\"default\"\n data-testid=\"settings-save\"\n onClick={() => saveSiteMutation.mutate()}\n disabled={saveSiteMutation.isPending}\n className=\"w-full sm:w-auto\"\n >\n <Save className=\"h-4 w-4\" />\n {t('common.save')}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\ninterface BotCardProps {\n bot: TelegramBotWithStats;\n expanded: boolean;\n onToggleExpand: () => void;\n}\n\nfunction BotCard({ bot, expanded, onToggleExpand }: BotCardProps) {\n const { t } = useTranslation();\n const queryClient = useQueryClient();\n\n const [name, setName] = useState(bot.name);\n const [token, setToken] = useState('');\n const [enabled, setEnabled] = useState(bot.enabled);\n const [allowAuthRequests, setAllowAuthRequests] = useState(bot.allowAuthRequests);\n\n useEffect(() => {\n setName(bot.name);\n setEnabled(bot.enabled);\n setAllowAuthRequests(bot.allowAuthRequests);\n }, [bot.allowAuthRequests, bot.enabled, bot.name]);\n\n const chatsQuery = useQuery({\n queryKey: ['telegram-bot-chats', bot.id],\n enabled: expanded,\n queryFn: async () => {\n const res = await fetch(`/api/settings/telegram/bots/${bot.id}/chats`);\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.loadChatsFailed')));\n }\n return (await res.json()) as TelegramChatsResponse;\n },\n });\n\n const groupedChats = useMemo(() => {\n const chats = chatsQuery.data?.chats ?? [];\n return {\n pending: chats.filter((chat) => chat.status === 'pending'),\n authorized: chats.filter((chat) => chat.status === 'authorized'),\n };\n }, [chatsQuery.data?.chats]);\n\n const patchBotMutation = useMutation({\n mutationFn: async () => {\n const payload: Record<string, unknown> = {\n name,\n enabled,\n allowAuthRequests,\n };\n if (token.trim()) {\n payload.token = token.trim();\n }\n\n const res = await fetch(`/api/settings/telegram/bots/${bot.id}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.updateFailed')));\n }\n },\n onSuccess: async () => {\n setToken('');\n await queryClient.invalidateQueries({ queryKey: ['telegram-bots'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const deleteBotMutation = useMutation({\n mutationFn: async () => {\n const res = await fetch(`/api/settings/telegram/bots/${bot.id}`, {\n method: 'DELETE',\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.deleteFailed')));\n }\n },\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: ['telegram-bots'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const approveMutation = useMutation({\n mutationFn: async (chatId: string) => {\n const res = await fetch(\n `/api/settings/telegram/bots/${bot.id}/chats/${encodeURIComponent(chatId)}/approve`,\n {\n method: 'POST',\n }\n );\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.approveFailed')));\n }\n },\n onSuccess: async () => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: ['telegram-bots'] }),\n queryClient.invalidateQueries({ queryKey: ['telegram-bot-chats', bot.id] }),\n ]);\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const removeChatMutation = useMutation({\n mutationFn: async (chatId: string) => {\n const res = await fetch(\n `/api/settings/telegram/bots/${bot.id}/chats/${encodeURIComponent(chatId)}`,\n {\n method: 'DELETE',\n }\n );\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.removeFailed')));\n }\n },\n onSuccess: async () => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: ['telegram-bots'] }),\n queryClient.invalidateQueries({ queryKey: ['telegram-bot-chats', bot.id] }),\n ]);\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const testChatMutation = useMutation({\n mutationFn: async (chatId: string) => {\n const res = await fetch(\n `/api/settings/telegram/bots/${bot.id}/chats/${encodeURIComponent(chatId)}/test`,\n {\n method: 'POST',\n }\n );\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.testMessageFailed')));\n }\n },\n onSuccess: () => {\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n return (\n <div\n className=\"space-y-4 rounded-md border-0 bg-card p-4\"\n data-testid={`telegram-bot-card-${bot.id}`}\n data-bot-name={bot.name}\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <div className=\"font-medium\">{bot.name}</div>\n <div className=\"text-xs text-muted-foreground\">\n {bot.authorizedCount} / {bot.pendingCount}\n </div>\n </div>\n <Button\n variant=\"ghost\"\n data-testid={`telegram-bot-toggle-${bot.id}`}\n onClick={onToggleExpand}\n >\n {expanded ? t('common.collapse') : t('common.expand')}\n </Button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end\">\n <div className=\"md:col-span-3 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor={`bot-name-${bot.id}`}>\n {t('telegram.botName')}\n </label>\n <Input\n id={`bot-name-${bot.id}`}\n value={name}\n onChange={(event) => setName(event.target.value)}\n className=\"min-h-10\"\n />\n </div>\n <div className=\"md:col-span-4 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor={`bot-token-${bot.id}`}>\n {t('telegram.botToken')}\n </label>\n <Input\n id={`bot-token-${bot.id}`}\n type=\"password\"\n value={token}\n onChange={(event) => setToken(event.target.value)}\n placeholder={t('telegram.tokenPlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n <div className=\"md:col-span-2\">\n <div className=\"flex min-h-10 items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2.5\">\n <span className=\"text-sm font-medium\">{t('common.enabled')}</span>\n <Switch checked={enabled} onCheckedChange={(checked) => setEnabled(Boolean(checked))} />\n </div>\n </div>\n <div className=\"md:col-span-3\">\n <div className=\"flex min-h-10 items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2.5\">\n <span className=\"text-sm font-medium\">{t('telegram.allowAuthRequests')}</span>\n <Switch\n checked={allowAuthRequests}\n onCheckedChange={(checked) => setAllowAuthRequests(Boolean(checked))}\n />\n </div>\n </div>\n </div>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end\">\n <Button\n variant=\"destructive\"\n data-testid={`telegram-bot-delete-${bot.id}`}\n onClick={() => deleteBotMutation.mutate()}\n className=\"w-full sm:w-auto\"\n >\n <Trash2 className=\"h-4 w-4\" />\n {t('telegram.deleteBot')}\n </Button>\n <Button\n variant=\"default\"\n data-testid={`telegram-bot-save-${bot.id}`}\n onClick={() => patchBotMutation.mutate()}\n className=\"w-full sm:w-auto\"\n >\n <Save className=\"h-4 w-4\" />\n {t('common.save')}\n </Button>\n </div>\n\n {expanded && (\n <div className=\"grid grid-cols-1 gap-4 border-t border-border pt-4 lg:grid-cols-2\">\n <div className=\"space-y-2\">\n <h3 className=\"text-sm font-semibold flex items-center gap-1\">\n <Shield className=\"h-4 w-4\" />\n {t('telegram.pendingChats')}\n </h3>\n {groupedChats.pending.length === 0 && <div className=\"text-xs text-muted-foreground\">-</div>}\n {groupedChats.pending.map((chat) => (\n <ChatRow\n key={`${chat.botId}-${chat.chatId}`}\n chat={chat}\n pending\n onApprove={() => approveMutation.mutate(chat.chatId)}\n onDelete={() => removeChatMutation.mutate(chat.chatId)}\n />\n ))}\n </div>\n\n <div className=\"space-y-2\">\n <h3 className=\"text-sm font-semibold flex items-center gap-1\">\n <Shield className=\"h-4 w-4\" />\n {t('telegram.chats')}\n </h3>\n {groupedChats.authorized.length === 0 && <div className=\"text-xs text-muted-foreground\">-</div>}\n {groupedChats.authorized.map((chat) => (\n <ChatRow\n key={`${chat.botId}-${chat.chatId}`}\n chat={chat}\n pending={false}\n onTest={() => testChatMutation.mutate(chat.chatId)}\n onDelete={() => removeChatMutation.mutate(chat.chatId)}\n />\n ))}\n </div>\n\n {chatsQuery.isLoading && (\n <div className=\"lg:col-span-2 text-xs text-muted-foreground\">\n {t('common.loading')}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\ninterface ChatRowProps {\n chat: TelegramBotChat;\n pending: boolean;\n onApprove?: () => void;\n onDelete: () => void;\n onTest?: () => void;\n}\n\nfunction ChatRow({ chat, pending, onApprove, onDelete, onTest }: ChatRowProps) {\n const { t } = useTranslation();\n const language = useSiteStore((state) => state.settings?.language ?? 'en_US');\n return (\n <div className=\"space-y-2 rounded border-0 bg-background p-3\">\n <div className=\"text-sm font-medium truncate\" title={chat.displayName}>\n {chat.displayName}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {t('telegram.chatId')}:{chat.chatId}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {new Date(chat.appliedAt).toLocaleString(toBCP47Locale(language))}\n </div>\n\n <div className=\"flex items-center justify-end gap-2 pt-1\">\n {pending ? (\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={onDelete}>\n {t('telegram.reject')}\n </Button>\n <Button variant=\"default\" size=\"sm\" onClick={onApprove}>\n {t('telegram.authorize')}\n </Button>\n </>\n ) : (\n <>\n <Button variant=\"secondary\" size=\"sm\" onClick={onTest}>\n <Send className=\"h-3.5 w-3.5\" />\n {t('telegram.sendTestMessage')}\n </Button>\n <Button variant=\"destructive\" size=\"sm\" onClick={onDelete}>\n {t('common.delete')}\n </Button>\n </>\n )}\n </div>\n </div>\n );\n}\n\n// Page title component\nexport function PageTitle() {\n const { t } = useTranslation();\n return <>{t('sidebar.settings')}</>;\n}\n\n// Page actions component\nexport function PageActions() {\n const { t } = useTranslation();\n const [showRestartConfirm, setShowRestartConfirm] = useState(false);\n\n const restartMutation = useMutation({\n mutationFn: async () => {\n const res = await fetch('/api/settings/restart', { method: 'POST' });\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('settings.restartFailed')));\n }\n },\n onSuccess: () => {\n toast.success(t('settings.restartScheduled'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n return (\n <>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={() => setShowRestartConfirm(true)}\n disabled={restartMutation.isPending}\n aria-label={t('settings.restartGateway')}\n title={t('settings.restartGateway')}\n className=\"text-destructive hover:text-destructive hover:bg-destructive/10\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n </Button>\n\n <AlertDialog open={showRestartConfirm} onOpenChange={setShowRestartConfirm}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{t('settings.restartGateway')}</AlertDialogTitle>\n <AlertDialogDescription>{t('settings.restartConfirm')}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel onClick={() => setShowRestartConfirm(false)}>\n {t('common.cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => {\n restartMutation.mutate();\n setShowRestartConfirm(false);\n }}\n >\n {t('common.confirm')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n"],"names":["__iconNode","RotateCcw","createLucideIcon","Save","Shield","WEBHOOK_EVENT_OPTIONS","parseApiError","res","fallback","SettingsPage","useTranslation","queryClient","useQueryClient","refreshSettings","useSiteStore","activeTab","setActiveTab","useState","theme","useUIStore","state","setTheme","isDark","siteName","setSiteName","siteUrl","setSiteUrl","language","setLanguage","bellThrottleSeconds","setBellThrottleSeconds","notificationThrottleSeconds","setNotificationThrottleSeconds","enableBrowserBellToast","setEnableBrowserBellToast","enableBrowserNotificationToast","setEnableBrowserNotificationToast","enableTelegramBellPush","setEnableTelegramBellPush","enableTelegramNotificationPush","setEnableTelegramNotificationPush","sshReconnectMaxRetries","setSshReconnectMaxRetries","sshReconnectDelaySeconds","setSshReconnectDelaySeconds","showRefreshNotice","setShowRefreshNotice","newBotName","setNewBotName","newBotToken","setNewBotToken","expandedBotId","setExpandedBotId","newWebhookUrl","setNewWebhookUrl","newWebhookSecret","setNewWebhookSecret","newWebhookEventMask","setNewWebhookEventMask","handleThemeChange","checked","nextTheme","settingsQuery","useQuery","botsQuery","useEffect","settings","_a","saveSiteMutation","useMutation","toast","_b","i18n","err","createBotMutation","bots","webhooksQuery","createWebhookMutation","deleteWebhookMutation","id","webhooks","_c","jsxs","jsx","Button","Card","CardHeader","CardTitle","CardContent","Input","event","Select","nextValue","SelectTrigger","SelectValue","_d","I18N_MANIFEST","l","SelectContent","locale","SelectItem","Switch","Loader2","bot","BotCard","prev","eventType","nextChecked","item","webhook","toBCP47Locale","Trash2","expanded","onToggleExpand","t","name","setName","token","setToken","enabled","setEnabled","allowAuthRequests","setAllowAuthRequests","chatsQuery","groupedChats","useMemo","chats","chat","patchBotMutation","payload","deleteBotMutation","approveMutation","chatId","removeChatMutation","testChatMutation","ChatRow","pending","onApprove","onDelete","onTest","Fragment","Send","PageTitle","PageActions","showRestartConfirm","setShowRestartConfirm","restartMutation","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"mappings":"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","x_google_ignoreList":[0,1,2]}
1
+ {"version":3,"file":"SettingsPage-DwpbDA_e.js","sources":["../../../../node_modules/.bun/lucide-react@0.564.0+b1ab299f0a400331/node_modules/lucide-react/dist/esm/icons/rotate-ccw.js","../../../../node_modules/.bun/lucide-react@0.564.0+b1ab299f0a400331/node_modules/lucide-react/dist/esm/icons/save.js","../../../../node_modules/.bun/lucide-react@0.564.0+b1ab299f0a400331/node_modules/lucide-react/dist/esm/icons/shield.js","../../src/pages/SettingsPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.564.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"1357e3\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }]\n];\nconst RotateCcw = createLucideIcon(\"rotate-ccw\", __iconNode);\n\nexport { __iconNode, RotateCcw as default };\n//# sourceMappingURL=rotate-ccw.js.map\n","/**\n * @license lucide-react v0.564.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n 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\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n];\nconst Save = createLucideIcon(\"save\", __iconNode);\n\nexport { __iconNode, Save as default };\n//# sourceMappingURL=save.js.map\n","/**\n * @license lucide-react v0.564.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ]\n];\nconst Shield = createLucideIcon(\"shield\", __iconNode);\n\nexport { __iconNode, Shield as default };\n//# sourceMappingURL=shield.js.map\n","import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport type {\n EventType,\n LocaleCode,\n SiteSettings,\n TelegramBotChat,\n TelegramBotWithStats,\n UpdateSiteSettingsRequest,\n WebhookEndpoint,\n} from '@tmex/shared';\nimport { I18N_MANIFEST, toBCP47 as toBCP47Locale } from '@tmex/shared';\nimport { Loader2, RotateCcw, Save, Send, Shield, Trash2 } from 'lucide-react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport i18n from '../i18n';\nimport { toast } from 'sonner';\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@/components/ui/alert-dialog';\nimport { Button } from '@/components/ui/button';\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';\nimport { Input } from '@/components/ui/input';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select';\nimport { Switch } from '@/components/ui/switch';\nimport { useSiteStore } from '../stores/site';\nimport { useUIStore } from '../stores/ui';\n\ninterface TelegramBotsResponse {\n bots: TelegramBotWithStats[];\n}\n\ninterface TelegramChatsResponse {\n chats: TelegramBotChat[];\n}\n\ninterface SiteSettingsResponse {\n settings: SiteSettings;\n}\n\ninterface WebhooksResponse {\n webhooks: WebhookEndpoint[];\n}\n\nconst WEBHOOK_EVENT_OPTIONS: EventType[] = [\n 'terminal_bell',\n 'terminal_notification',\n 'tmux_window_close',\n 'tmux_pane_close',\n 'device_tmux_missing',\n 'device_disconnect',\n 'session_created',\n 'session_closed',\n];\n\nasync function parseApiError(res: Response, fallback: string): Promise<string> {\n try {\n const payload = (await res.json()) as { error?: string };\n return payload.error ?? fallback;\n } catch {\n return fallback;\n }\n}\n\nexport default function SettingsPage() {\n const { t } = useTranslation();\n const queryClient = useQueryClient();\n const { refreshSettings } = useSiteStore();\n\n const [activeTab, setActiveTab] = useState<'site' | 'notifications' | 'telegram' | 'webhooks'>(\n 'site'\n );\n\n const theme = useUIStore((state) => state.theme);\n const setTheme = useUIStore((state) => state.setTheme);\n const isDark = theme === 'dark';\n\n // Site settings state\n const [siteName, setSiteName] = useState('tmex');\n const [siteUrl, setSiteUrl] = useState(window.location.origin);\n const [language, setLanguage] = useState<LocaleCode>('en_US');\n\n // Notifications state\n const [bellThrottleSeconds, setBellThrottleSeconds] = useState(6);\n const [notificationThrottleSeconds, setNotificationThrottleSeconds] = useState(3);\n const [enableBrowserBellToast, setEnableBrowserBellToast] = useState(true);\n const [enableBrowserNotificationToast, setEnableBrowserNotificationToast] = useState(true);\n const [enableTelegramBellPush, setEnableTelegramBellPush] = useState(true);\n const [enableTelegramNotificationPush, setEnableTelegramNotificationPush] = useState(true);\n const [sshReconnectMaxRetries, setSshReconnectMaxRetries] = useState(2);\n const [sshReconnectDelaySeconds, setSshReconnectDelaySeconds] = useState(10);\n const [showRefreshNotice, setShowRefreshNotice] = useState(false);\n\n // Telegram state\n const [newBotName, setNewBotName] = useState('');\n const [newBotToken, setNewBotToken] = useState('');\n const [expandedBotId, setExpandedBotId] = useState<string | null>(null);\n\n // Webhook state\n const [newWebhookUrl, setNewWebhookUrl] = useState('');\n const [newWebhookSecret, setNewWebhookSecret] = useState('');\n const [newWebhookEventMask, setNewWebhookEventMask] = useState<EventType[]>(WEBHOOK_EVENT_OPTIONS);\n\n const handleThemeChange = (checked: boolean) => {\n const nextTheme = checked ? 'dark' : 'light';\n setTheme(nextTheme);\n document.documentElement.classList.toggle('dark', nextTheme === 'dark');\n };\n\n const settingsQuery = useQuery({\n queryKey: ['site-settings'],\n queryFn: async () => {\n const res = await fetch('/api/settings/site');\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('settings.loadFailed')));\n }\n return (await res.json()) as SiteSettingsResponse;\n },\n });\n\n const botsQuery = useQuery({\n queryKey: ['telegram-bots'],\n queryFn: async () => {\n const res = await fetch('/api/settings/telegram/bots');\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.loadBotsFailed')));\n }\n return (await res.json()) as TelegramBotsResponse;\n },\n });\n\n useEffect(() => {\n const settings = settingsQuery.data?.settings;\n if (!settings) {\n return;\n }\n\n setSiteName(settings.siteName);\n setSiteUrl(settings.siteUrl);\n setLanguage(settings.language ?? 'en_US');\n setBellThrottleSeconds(settings.bellThrottleSeconds);\n setNotificationThrottleSeconds(settings.notificationThrottleSeconds ?? 3);\n setEnableBrowserBellToast(settings.enableBrowserBellToast ?? true);\n setEnableBrowserNotificationToast(settings.enableBrowserNotificationToast ?? true);\n setEnableTelegramBellPush(settings.enableTelegramBellPush ?? true);\n setEnableTelegramNotificationPush(settings.enableTelegramNotificationPush ?? true);\n setSshReconnectMaxRetries(settings.sshReconnectMaxRetries);\n setSshReconnectDelaySeconds(settings.sshReconnectDelaySeconds);\n }, [settingsQuery.data?.settings]);\n\n const saveSiteMutation = useMutation({\n mutationFn: async () => {\n const payload: UpdateSiteSettingsRequest = {\n siteName,\n siteUrl,\n language,\n bellThrottleSeconds,\n notificationThrottleSeconds,\n enableBrowserBellToast,\n enableBrowserNotificationToast,\n enableTelegramBellPush,\n enableTelegramNotificationPush,\n sshReconnectMaxRetries,\n sshReconnectDelaySeconds,\n };\n\n const res = await fetch('/api/settings/site', {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('settings.saveFailed')));\n }\n },\n onSuccess: async () => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: ['site-settings'] }),\n refreshSettings(),\n ]);\n toast.success(t('settings.settingsSaved'));\n if (settingsQuery.data?.settings?.language !== language) {\n void i18n.changeLanguage(language);\n setShowRefreshNotice(true);\n }\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const createBotMutation = useMutation({\n mutationFn: async () => {\n const res = await fetch('/api/settings/telegram/bots', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name: newBotName,\n token: newBotToken,\n enabled: true,\n allowAuthRequests: true,\n }),\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.createFailed')));\n }\n },\n onSuccess: async () => {\n setNewBotName('');\n setNewBotToken('');\n await queryClient.invalidateQueries({ queryKey: ['telegram-bots'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const bots = botsQuery.data?.bots ?? [];\n\n const webhooksQuery = useQuery({\n queryKey: ['webhooks'],\n queryFn: async () => {\n const res = await fetch('/api/webhooks');\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('webhook.loadFailed')));\n }\n return (await res.json()) as WebhooksResponse;\n },\n });\n\n const createWebhookMutation = useMutation({\n mutationFn: async () => {\n const res = await fetch('/api/webhooks', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n url: newWebhookUrl,\n secret: newWebhookSecret,\n eventMask: newWebhookEventMask,\n }),\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('webhook.createFailed')));\n }\n },\n onSuccess: async () => {\n setNewWebhookUrl('');\n setNewWebhookSecret('');\n setNewWebhookEventMask(WEBHOOK_EVENT_OPTIONS);\n await queryClient.invalidateQueries({ queryKey: ['webhooks'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const deleteWebhookMutation = useMutation({\n mutationFn: async (id: string) => {\n const res = await fetch(`/api/webhooks/${id}`, { method: 'DELETE' });\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('webhook.deleteFailed')));\n }\n },\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: ['webhooks'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const webhooks = webhooksQuery.data?.webhooks ?? [];\n\n return (\n <div\n className=\"mx-auto flex w-full max-w-6xl flex-col gap-4 p-3 pb-[calc(2rem+env(safe-area-inset-bottom))] sm:gap-6 sm:p-5\"\n data-testid=\"settings-page\"\n >\n <div className=\"flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant={activeTab === 'site' ? 'default' : 'outline'}\n data-testid=\"settings-tab-site\"\n onClick={() => setActiveTab('site')}\n >\n {t('settings.siteSettings')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={activeTab === 'notifications' ? 'default' : 'outline'}\n data-testid=\"settings-tab-notifications\"\n onClick={() => setActiveTab('notifications')}\n >\n {t('settings.notificationsTab')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={activeTab === 'telegram' ? 'default' : 'outline'}\n data-testid=\"settings-tab-telegram\"\n onClick={() => setActiveTab('telegram')}\n >\n {t('telegram.title')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={activeTab === 'webhooks' ? 'default' : 'outline'}\n data-testid=\"settings-tab-webhooks\"\n onClick={() => setActiveTab('webhooks')}\n >\n {t('webhook.title')}\n </Button>\n </div>\n\n {activeTab === 'site' && (\n <Card className=\"border-0 ring-0\">\n <CardHeader>\n <CardTitle>{t('settings.siteSettings')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"site-name-input\">\n {t('settings.siteName')}\n </label>\n <Input\n id=\"site-name-input\"\n value={siteName}\n onChange={(event) => setSiteName(event.target.value)}\n placeholder={t('settings.siteNamePlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"site-url-input\">\n {t('settings.siteUrl')}\n </label>\n <Input\n id=\"site-url-input\"\n value={siteUrl}\n onChange={(event) => setSiteUrl(event.target.value)}\n placeholder={t('settings.siteUrlPlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"language-select\">\n {t('settings.language')}\n </label>\n <Select\n value={language}\n onValueChange={(nextValue) => {\n if (!nextValue) return;\n setLanguage(nextValue as LocaleCode);\n }}\n >\n <SelectTrigger\n id=\"language-select\"\n data-testid=\"settings-language-select\"\n className=\"w-full min-h-10\"\n >\n <SelectValue placeholder={t('settings.language')}>\n {I18N_MANIFEST.locales.find((l) => l.code === language)?.nativeName ?? language}\n </SelectValue>\n </SelectTrigger>\n <SelectContent className=\"max-h-[var(--tmex-viewport-height)]\">\n {I18N_MANIFEST.locales.map((locale) => (\n <SelectItem key={locale.code} value={locale.code}>\n {locale.nativeName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {showRefreshNotice && (\n <p className=\"mt-1 text-xs text-primary\" data-testid=\"settings-refresh-notice\">\n {t('settings.refreshToApply')}\n </p>\n )}\n </div>\n\n <div className=\"space-y-3\">\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">{t('settings.theme')}</div>\n </div>\n <Switch\n checked={isDark}\n onCheckedChange={(checked) => handleThemeChange(Boolean(checked))}\n data-testid=\"settings-theme-toggle\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n {activeTab === 'notifications' && (\n <Card className=\"border-0 ring-0\">\n <CardHeader>\n <CardTitle>{t('settings.notificationsTab')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"space-y-3\">\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">{t('settings.enableBrowserBellToast')}</div>\n </div>\n <Switch\n checked={enableBrowserBellToast}\n onCheckedChange={(checked) => setEnableBrowserBellToast(Boolean(checked))}\n data-testid=\"settings-enable-browser-bell-toast\"\n />\n </div>\n\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">{t('settings.enableTelegramBellPush')}</div>\n </div>\n <Switch\n checked={enableTelegramBellPush}\n onCheckedChange={(checked) => setEnableTelegramBellPush(Boolean(checked))}\n data-testid=\"settings-enable-telegram-bell-push\"\n />\n </div>\n\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">\n {t('settings.enableBrowserNotificationToast')}\n </div>\n </div>\n <Switch\n checked={enableBrowserNotificationToast}\n onCheckedChange={(checked) => setEnableBrowserNotificationToast(Boolean(checked))}\n data-testid=\"settings-enable-browser-notification-toast\"\n />\n </div>\n\n <div className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-2.5\">\n <div className=\"min-w-0 pr-2\">\n <div className=\"text-sm font-medium\">\n {t('settings.enableTelegramNotificationPush')}\n </div>\n </div>\n <Switch\n checked={enableTelegramNotificationPush}\n onCheckedChange={(checked) => setEnableTelegramNotificationPush(Boolean(checked))}\n data-testid=\"settings-enable-telegram-notification-push\"\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"bell-throttle-input\">\n {t('settings.bellThrottle')}\n </label>\n <Input\n id=\"bell-throttle-input\"\n type=\"number\"\n value={bellThrottleSeconds}\n min={0}\n max={300}\n onChange={(event) => setBellThrottleSeconds(Number(event.target.value))}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"notification-throttle-input\">\n {t('settings.notificationThrottle')}\n </label>\n <Input\n id=\"notification-throttle-input\"\n type=\"number\"\n value={notificationThrottleSeconds}\n min={0}\n max={300}\n onChange={(event) => setNotificationThrottleSeconds(Number(event.target.value))}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"ssh-reconnect-retries-input\">\n {t('settings.sshReconnectMaxRetries')}\n </label>\n <Input\n id=\"ssh-reconnect-retries-input\"\n type=\"number\"\n value={sshReconnectMaxRetries}\n min={0}\n max={20}\n onChange={(event) => setSshReconnectMaxRetries(Number(event.target.value))}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"ssh-reconnect-delay-input\">\n {t('settings.sshReconnectDelay')}\n </label>\n <Input\n id=\"ssh-reconnect-delay-input\"\n type=\"number\"\n value={sshReconnectDelaySeconds}\n min={1}\n max={300}\n onChange={(event) => setSshReconnectDelaySeconds(Number(event.target.value))}\n className=\"min-h-10\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n {activeTab === 'telegram' && (\n <Card className=\"border-0 ring-0\">\n <CardHeader>\n <CardTitle>{t('telegram.title')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end\">\n <div className=\"md:col-span-4 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"new-bot-name\">\n {t('telegram.botName')}\n </label>\n <Input\n id=\"new-bot-name\"\n value={newBotName}\n onChange={(event) => setNewBotName(event.target.value)}\n placeholder={t('telegram.botNamePlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"md:col-span-6 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"new-bot-token\">\n {t('telegram.botToken')}\n </label>\n <Input\n id=\"new-bot-token\"\n type=\"password\"\n value={newBotToken}\n onChange={(event) => setNewBotToken(event.target.value)}\n placeholder={t('telegram.botTokenPlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"md:col-span-2\">\n <Button\n variant=\"default\"\n className=\"w-full md:w-auto\"\n data-testid=\"telegram-add-bot\"\n onClick={() => createBotMutation.mutate()}\n disabled={\n createBotMutation.isPending || !newBotName.trim() || !newBotToken.trim()\n }\n >\n {createBotMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n {t('telegram.addBot')}\n </Button>\n </div>\n </div>\n </div>\n\n <div className=\"space-y-3\">\n {botsQuery.isLoading && (\n <div className=\"text-sm text-muted-foreground\">{t('common.loading')}</div>\n )}\n\n {!botsQuery.isLoading && bots.length === 0 && (\n <div className=\"text-sm text-muted-foreground\">{t('telegram.addBot')}</div>\n )}\n\n {bots.map((bot) => (\n <BotCard\n key={bot.id}\n bot={bot}\n expanded={expandedBotId === bot.id}\n onToggleExpand={() => {\n setExpandedBotId((prev) => (prev === bot.id ? null : bot.id));\n }}\n />\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n\n {activeTab === 'webhooks' && (\n <Card className=\"border-0 ring-0\">\n <CardHeader>\n <CardTitle>{t('webhook.title')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end\">\n <div className=\"md:col-span-6 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"webhook-url-input\">\n {t('webhook.url')}\n </label>\n <Input\n id=\"webhook-url-input\"\n data-testid=\"webhook-url-input\"\n value={newWebhookUrl}\n onChange={(event) => setNewWebhookUrl(event.target.value)}\n placeholder=\"https://example.com/webhook\"\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"md:col-span-4 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor=\"webhook-secret-input\">\n {t('webhook.secret')}\n </label>\n <Input\n id=\"webhook-secret-input\"\n data-testid=\"webhook-secret-input\"\n value={newWebhookSecret}\n onChange={(event) => setNewWebhookSecret(event.target.value)}\n placeholder={t('webhook.secretPlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n\n <div className=\"md:col-span-2\">\n <Button\n variant=\"default\"\n className=\"w-full md:w-auto\"\n data-testid=\"webhook-add\"\n onClick={() => createWebhookMutation.mutate()}\n disabled={\n createWebhookMutation.isPending ||\n !newWebhookUrl.trim() ||\n !newWebhookSecret.trim() ||\n newWebhookEventMask.length === 0\n }\n >\n {createWebhookMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n {t('webhook.add')}\n </Button>\n </div>\n </div>\n\n <div className=\"space-y-3 rounded-lg border border-border bg-card px-4 py-3\">\n <div className=\"text-sm font-medium\">{t('webhook.eventMask')}</div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {WEBHOOK_EVENT_OPTIONS.map((eventType) => {\n const checked = newWebhookEventMask.includes(eventType);\n return (\n <div\n key={eventType}\n className=\"flex min-h-10 items-center justify-between gap-4 rounded-lg border border-border bg-background px-3 py-2\"\n >\n <div className=\"min-w-0 pr-2 text-sm font-medium\">\n {t(`notification.eventType.${eventType}` as const)}\n </div>\n <Switch\n checked={checked}\n data-testid={`webhook-event-${eventType}`}\n onCheckedChange={(nextChecked) => {\n setNewWebhookEventMask((prev) => {\n if (nextChecked) {\n return prev.includes(eventType) ? prev : [...prev, eventType];\n }\n return prev.filter((item) => item !== eventType);\n });\n }}\n />\n </div>\n );\n })}\n </div>\n </div>\n\n <div className=\"space-y-2\">\n {webhooksQuery.isLoading && (\n <div className=\"text-sm text-muted-foreground\">{t('common.loading')}</div>\n )}\n\n {!webhooksQuery.isLoading && webhooks.length === 0 && (\n <div className=\"text-sm text-muted-foreground\">{t('webhook.empty')}</div>\n )}\n\n {webhooks.map((webhook) => (\n <div\n key={webhook.id}\n data-testid=\"webhook-item\"\n data-webhook-url={webhook.url}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border bg-card px-4 py-2.5\"\n >\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">{webhook.url}</div>\n <div className=\"text-xs text-muted-foreground\">\n {new Date(webhook.createdAt).toLocaleString(toBCP47Locale(language))}\n </div>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n data-testid=\"webhook-delete\"\n onClick={() => deleteWebhookMutation.mutate(webhook.id)}\n disabled={deleteWebhookMutation.isPending}\n aria-label={t('common.delete')}\n title={t('common.delete')}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n\n {(activeTab === 'site' || activeTab === 'notifications') && (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end\">\n <Button\n variant=\"default\"\n data-testid=\"settings-save\"\n onClick={() => saveSiteMutation.mutate()}\n disabled={saveSiteMutation.isPending}\n className=\"w-full sm:w-auto\"\n >\n <Save className=\"h-4 w-4\" />\n {t('common.save')}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\ninterface BotCardProps {\n bot: TelegramBotWithStats;\n expanded: boolean;\n onToggleExpand: () => void;\n}\n\nfunction BotCard({ bot, expanded, onToggleExpand }: BotCardProps) {\n const { t } = useTranslation();\n const queryClient = useQueryClient();\n\n const [name, setName] = useState(bot.name);\n const [token, setToken] = useState('');\n const [enabled, setEnabled] = useState(bot.enabled);\n const [allowAuthRequests, setAllowAuthRequests] = useState(bot.allowAuthRequests);\n\n useEffect(() => {\n setName(bot.name);\n setEnabled(bot.enabled);\n setAllowAuthRequests(bot.allowAuthRequests);\n }, [bot.allowAuthRequests, bot.enabled, bot.name]);\n\n const chatsQuery = useQuery({\n queryKey: ['telegram-bot-chats', bot.id],\n enabled: expanded,\n queryFn: async () => {\n const res = await fetch(`/api/settings/telegram/bots/${bot.id}/chats`);\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.loadChatsFailed')));\n }\n return (await res.json()) as TelegramChatsResponse;\n },\n });\n\n const groupedChats = useMemo(() => {\n const chats = chatsQuery.data?.chats ?? [];\n return {\n pending: chats.filter((chat) => chat.status === 'pending'),\n authorized: chats.filter((chat) => chat.status === 'authorized'),\n };\n }, [chatsQuery.data?.chats]);\n\n const patchBotMutation = useMutation({\n mutationFn: async () => {\n const payload: Record<string, unknown> = {\n name,\n enabled,\n allowAuthRequests,\n };\n if (token.trim()) {\n payload.token = token.trim();\n }\n\n const res = await fetch(`/api/settings/telegram/bots/${bot.id}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.updateFailed')));\n }\n },\n onSuccess: async () => {\n setToken('');\n await queryClient.invalidateQueries({ queryKey: ['telegram-bots'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const deleteBotMutation = useMutation({\n mutationFn: async () => {\n const res = await fetch(`/api/settings/telegram/bots/${bot.id}`, {\n method: 'DELETE',\n });\n\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.deleteFailed')));\n }\n },\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: ['telegram-bots'] });\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const approveMutation = useMutation({\n mutationFn: async (chatId: string) => {\n const res = await fetch(\n `/api/settings/telegram/bots/${bot.id}/chats/${encodeURIComponent(chatId)}/approve`,\n {\n method: 'POST',\n }\n );\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.approveFailed')));\n }\n },\n onSuccess: async () => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: ['telegram-bots'] }),\n queryClient.invalidateQueries({ queryKey: ['telegram-bot-chats', bot.id] }),\n ]);\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const removeChatMutation = useMutation({\n mutationFn: async (chatId: string) => {\n const res = await fetch(\n `/api/settings/telegram/bots/${bot.id}/chats/${encodeURIComponent(chatId)}`,\n {\n method: 'DELETE',\n }\n );\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.removeFailed')));\n }\n },\n onSuccess: async () => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: ['telegram-bots'] }),\n queryClient.invalidateQueries({ queryKey: ['telegram-bot-chats', bot.id] }),\n ]);\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n const testChatMutation = useMutation({\n mutationFn: async (chatId: string) => {\n const res = await fetch(\n `/api/settings/telegram/bots/${bot.id}/chats/${encodeURIComponent(chatId)}/test`,\n {\n method: 'POST',\n }\n );\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('telegram.testMessageFailed')));\n }\n },\n onSuccess: () => {\n toast.success(t('common.success'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n return (\n <div\n className=\"space-y-4 rounded-md border-0 bg-card p-4\"\n data-testid={`telegram-bot-card-${bot.id}`}\n data-bot-name={bot.name}\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <div className=\"font-medium\">{bot.name}</div>\n <div className=\"text-xs text-muted-foreground\">\n {bot.authorizedCount} / {bot.pendingCount}\n </div>\n </div>\n <Button\n variant=\"ghost\"\n data-testid={`telegram-bot-toggle-${bot.id}`}\n onClick={onToggleExpand}\n >\n {expanded ? t('common.collapse') : t('common.expand')}\n </Button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-12 md:items-end\">\n <div className=\"md:col-span-3 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor={`bot-name-${bot.id}`}>\n {t('telegram.botName')}\n </label>\n <Input\n id={`bot-name-${bot.id}`}\n value={name}\n onChange={(event) => setName(event.target.value)}\n className=\"min-h-10\"\n />\n </div>\n <div className=\"md:col-span-4 space-y-2\">\n <label className=\"block text-sm font-medium\" htmlFor={`bot-token-${bot.id}`}>\n {t('telegram.botToken')}\n </label>\n <Input\n id={`bot-token-${bot.id}`}\n type=\"password\"\n value={token}\n onChange={(event) => setToken(event.target.value)}\n placeholder={t('telegram.tokenPlaceholder')}\n className=\"min-h-10\"\n />\n </div>\n <div className=\"md:col-span-2\">\n <div className=\"flex min-h-10 items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2.5\">\n <span className=\"text-sm font-medium\">{t('common.enabled')}</span>\n <Switch checked={enabled} onCheckedChange={(checked) => setEnabled(Boolean(checked))} />\n </div>\n </div>\n <div className=\"md:col-span-3\">\n <div className=\"flex min-h-10 items-center justify-between gap-3 rounded-lg border border-border bg-background px-3 py-2.5\">\n <span className=\"text-sm font-medium\">{t('telegram.allowAuthRequests')}</span>\n <Switch\n checked={allowAuthRequests}\n onCheckedChange={(checked) => setAllowAuthRequests(Boolean(checked))}\n />\n </div>\n </div>\n </div>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end\">\n <Button\n variant=\"destructive\"\n data-testid={`telegram-bot-delete-${bot.id}`}\n onClick={() => deleteBotMutation.mutate()}\n className=\"w-full sm:w-auto\"\n >\n <Trash2 className=\"h-4 w-4\" />\n {t('telegram.deleteBot')}\n </Button>\n <Button\n variant=\"default\"\n data-testid={`telegram-bot-save-${bot.id}`}\n onClick={() => patchBotMutation.mutate()}\n className=\"w-full sm:w-auto\"\n >\n <Save className=\"h-4 w-4\" />\n {t('common.save')}\n </Button>\n </div>\n\n {expanded && (\n <div className=\"grid grid-cols-1 gap-4 border-t border-border pt-4 lg:grid-cols-2\">\n <div className=\"space-y-2\">\n <h3 className=\"text-sm font-semibold flex items-center gap-1\">\n <Shield className=\"h-4 w-4\" />\n {t('telegram.pendingChats')}\n </h3>\n {groupedChats.pending.length === 0 && <div className=\"text-xs text-muted-foreground\">-</div>}\n {groupedChats.pending.map((chat) => (\n <ChatRow\n key={`${chat.botId}-${chat.chatId}`}\n chat={chat}\n pending\n onApprove={() => approveMutation.mutate(chat.chatId)}\n onDelete={() => removeChatMutation.mutate(chat.chatId)}\n />\n ))}\n </div>\n\n <div className=\"space-y-2\">\n <h3 className=\"text-sm font-semibold flex items-center gap-1\">\n <Shield className=\"h-4 w-4\" />\n {t('telegram.chats')}\n </h3>\n {groupedChats.authorized.length === 0 && <div className=\"text-xs text-muted-foreground\">-</div>}\n {groupedChats.authorized.map((chat) => (\n <ChatRow\n key={`${chat.botId}-${chat.chatId}`}\n chat={chat}\n pending={false}\n onTest={() => testChatMutation.mutate(chat.chatId)}\n onDelete={() => removeChatMutation.mutate(chat.chatId)}\n />\n ))}\n </div>\n\n {chatsQuery.isLoading && (\n <div className=\"lg:col-span-2 text-xs text-muted-foreground\">\n {t('common.loading')}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\ninterface ChatRowProps {\n chat: TelegramBotChat;\n pending: boolean;\n onApprove?: () => void;\n onDelete: () => void;\n onTest?: () => void;\n}\n\nfunction ChatRow({ chat, pending, onApprove, onDelete, onTest }: ChatRowProps) {\n const { t } = useTranslation();\n const language = useSiteStore((state) => state.settings?.language ?? 'en_US');\n return (\n <div className=\"space-y-2 rounded border-0 bg-background p-3\">\n <div className=\"text-sm font-medium truncate\" title={chat.displayName}>\n {chat.displayName}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {t('telegram.chatId')}:{chat.chatId}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {new Date(chat.appliedAt).toLocaleString(toBCP47Locale(language))}\n </div>\n\n <div className=\"flex items-center justify-end gap-2 pt-1\">\n {pending ? (\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={onDelete}>\n {t('telegram.reject')}\n </Button>\n <Button variant=\"default\" size=\"sm\" onClick={onApprove}>\n {t('telegram.authorize')}\n </Button>\n </>\n ) : (\n <>\n <Button variant=\"secondary\" size=\"sm\" onClick={onTest}>\n <Send className=\"h-3.5 w-3.5\" />\n {t('telegram.sendTestMessage')}\n </Button>\n <Button variant=\"destructive\" size=\"sm\" onClick={onDelete}>\n {t('common.delete')}\n </Button>\n </>\n )}\n </div>\n </div>\n );\n}\n\n// Page title component\nexport function PageTitle() {\n const { t } = useTranslation();\n return <>{t('sidebar.settings')}</>;\n}\n\n// Page actions component\nexport function PageActions() {\n const { t } = useTranslation();\n const [showRestartConfirm, setShowRestartConfirm] = useState(false);\n\n const restartMutation = useMutation({\n mutationFn: async () => {\n const res = await fetch('/api/settings/restart', { method: 'POST' });\n if (!res.ok) {\n throw new Error(await parseApiError(res, t('settings.restartFailed')));\n }\n },\n onSuccess: () => {\n toast.success(t('settings.restartScheduled'));\n },\n onError: (err) => {\n toast.error(err instanceof Error ? err.message : t('common.error'));\n },\n });\n\n return (\n <>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={() => setShowRestartConfirm(true)}\n disabled={restartMutation.isPending}\n aria-label={t('settings.restartGateway')}\n title={t('settings.restartGateway')}\n className=\"text-destructive hover:text-destructive hover:bg-destructive/10\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n </Button>\n\n <AlertDialog open={showRestartConfirm} onOpenChange={setShowRestartConfirm}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{t('settings.restartGateway')}</AlertDialogTitle>\n <AlertDialogDescription>{t('settings.restartConfirm')}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel onClick={() => setShowRestartConfirm(false)}>\n {t('common.cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => {\n restartMutation.mutate();\n setShowRestartConfirm(false);\n }}\n >\n {t('common.confirm')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n"],"names":["__iconNode","RotateCcw","createLucideIcon","Save","Shield","WEBHOOK_EVENT_OPTIONS","parseApiError","res","fallback","SettingsPage","useTranslation","queryClient","useQueryClient","refreshSettings","useSiteStore","activeTab","setActiveTab","useState","theme","useUIStore","state","setTheme","isDark","siteName","setSiteName","siteUrl","setSiteUrl","language","setLanguage","bellThrottleSeconds","setBellThrottleSeconds","notificationThrottleSeconds","setNotificationThrottleSeconds","enableBrowserBellToast","setEnableBrowserBellToast","enableBrowserNotificationToast","setEnableBrowserNotificationToast","enableTelegramBellPush","setEnableTelegramBellPush","enableTelegramNotificationPush","setEnableTelegramNotificationPush","sshReconnectMaxRetries","setSshReconnectMaxRetries","sshReconnectDelaySeconds","setSshReconnectDelaySeconds","showRefreshNotice","setShowRefreshNotice","newBotName","setNewBotName","newBotToken","setNewBotToken","expandedBotId","setExpandedBotId","newWebhookUrl","setNewWebhookUrl","newWebhookSecret","setNewWebhookSecret","newWebhookEventMask","setNewWebhookEventMask","handleThemeChange","checked","nextTheme","settingsQuery","useQuery","botsQuery","useEffect","settings","_a","saveSiteMutation","useMutation","toast","_b","i18n","err","createBotMutation","bots","webhooksQuery","createWebhookMutation","deleteWebhookMutation","id","webhooks","_c","jsxs","jsx","Button","Card","CardHeader","CardTitle","CardContent","Input","event","Select","nextValue","SelectTrigger","SelectValue","_d","I18N_MANIFEST","l","SelectContent","locale","SelectItem","Switch","Loader2","bot","BotCard","prev","eventType","nextChecked","item","webhook","toBCP47Locale","Trash2","expanded","onToggleExpand","t","name","setName","token","setToken","enabled","setEnabled","allowAuthRequests","setAllowAuthRequests","chatsQuery","groupedChats","useMemo","chats","chat","patchBotMutation","payload","deleteBotMutation","approveMutation","chatId","removeChatMutation","testChatMutation","ChatRow","pending","onApprove","onDelete","onTest","Fragment","Send","PageTitle","PageActions","showRestartConfirm","setShowRestartConfirm","restartMutation","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"mappings":"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","x_google_ignoreList":[0,1,2]}