@burdenoff/microfe-channel 2026.1013.2 → 2026.1107.1

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.
Files changed (161) hide show
  1. package/dist/channel/ChannelRoot.d.ts +0 -2
  2. package/dist/channel/ChannelRoot.js +9 -6
  3. package/dist/channel/ChannelRoot.js.map +1 -1
  4. package/dist/channel/ChannelRoutes.d.ts +1 -2
  5. package/dist/channel/ChannelRoutes.js +5 -6
  6. package/dist/channel/ChannelRoutes.js.map +1 -1
  7. package/dist/channel/components/AdapterCredentialsForm.d.ts +2 -4
  8. package/dist/channel/components/AdapterCredentialsForm.js +1 -2
  9. package/dist/channel/components/AdapterCredentialsForm.js.map +1 -1
  10. package/dist/channel/components/FeatureNotEnabled.d.ts +1 -2
  11. package/dist/channel/components/FeatureNotEnabled.js +1 -2
  12. package/dist/channel/components/FeatureNotEnabled.js.map +1 -1
  13. package/dist/channel/components/MarkdownEditor.d.ts +1 -2
  14. package/dist/channel/components/MarkdownEditor.js +2 -5
  15. package/dist/channel/components/MarkdownEditor.js.map +1 -1
  16. package/dist/channel/components/PermissionGuard.d.ts +0 -2
  17. package/dist/channel/components/PermissionGuard.js +1 -2
  18. package/dist/channel/components/PermissionGuard.js.map +1 -1
  19. package/dist/channel/config/adapterCredentials.d.ts +0 -2
  20. package/dist/channel/config/adapterCredentials.js +3 -7
  21. package/dist/channel/config/adapterCredentials.js.map +1 -1
  22. package/dist/channel/constants/permissions.d.ts +0 -1
  23. package/dist/channel/constants/permissions.js +1 -2
  24. package/dist/channel/constants/permissions.js.map +1 -1
  25. package/dist/channel/graphql/global-client.d.ts +0 -2
  26. package/dist/channel/graphql/global-client.js +5 -6
  27. package/dist/channel/graphql/global-client.js.map +1 -1
  28. package/dist/channel/hooks/useChannelOrgSettings.d.ts +0 -2
  29. package/dist/channel/hooks/useChannelOrgSettings.js +20 -21
  30. package/dist/channel/hooks/useChannelOrgSettings.js.map +1 -1
  31. package/dist/channel/hooks/useChannelSubscription.d.ts +0 -1
  32. package/dist/channel/hooks/useChannelSubscription.js +7 -12
  33. package/dist/channel/hooks/useChannelSubscription.js.map +1 -1
  34. package/dist/channel/hooks/useChannels.d.ts +20 -30
  35. package/dist/channel/hooks/useChannels.js +100 -101
  36. package/dist/channel/hooks/useChannels.js.map +1 -1
  37. package/dist/channel/hooks/useTr.d.ts +0 -1
  38. package/dist/channel/hooks/useTr.js +1 -2
  39. package/dist/channel/hooks/useTr.js.map +1 -1
  40. package/dist/channel/index.d.ts +0 -1
  41. package/dist/channel/index.js +3 -2
  42. package/dist/channel/modules/channels/hooks/useExport.d.ts +0 -2
  43. package/dist/channel/modules/channels/hooks/useExport.js +77 -80
  44. package/dist/channel/modules/channels/hooks/useExport.js.map +1 -1
  45. package/dist/channel/modules/channels/i18n.d.ts +0 -2
  46. package/dist/channel/modules/channels/i18n.js +1 -2
  47. package/dist/channel/modules/channels/i18n.js.map +1 -1
  48. package/dist/channel/modules/channels/pages/ChannelDashboardPage.d.ts +1 -2
  49. package/dist/channel/modules/channels/pages/ChannelDashboardPage.js +10 -11
  50. package/dist/channel/modules/channels/pages/ChannelDashboardPage.js.map +1 -1
  51. package/dist/channel/modules/channels/pages/ChannelDetailsPage.d.ts +1 -2
  52. package/dist/channel/modules/channels/pages/ChannelDetailsPage.js +400 -401
  53. package/dist/channel/modules/channels/pages/ChannelDetailsPage.js.map +1 -1
  54. package/dist/channel/modules/channels/pages/ChannelSettingsPage.d.ts +1 -2
  55. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js +8 -7
  56. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js.map +1 -1
  57. package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts +1 -2
  58. package/dist/channel/modules/channels/pages/ChannelUsersPage.js +5 -10
  59. package/dist/channel/modules/channels/pages/ChannelUsersPage.js.map +1 -1
  60. package/dist/channel/modules/channels/pages/ChannelsListPage.d.ts +1 -2
  61. package/dist/channel/modules/channels/pages/ChannelsListPage.js +287 -288
  62. package/dist/channel/modules/channels/pages/ChannelsListPage.js.map +1 -1
  63. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.d.ts +1 -2
  64. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js +11 -12
  65. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js.map +1 -1
  66. package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts +1 -2
  67. package/dist/channel/modules/channels/pages/ConnectionsListPage.js +1 -2
  68. package/dist/channel/modules/channels/pages/ConnectionsListPage.js.map +1 -1
  69. package/dist/channel/modules/channels/pages/CreateChannelPage.d.ts +1 -2
  70. package/dist/channel/modules/channels/pages/CreateChannelPage.js +4 -5
  71. package/dist/channel/modules/channels/pages/CreateChannelPage.js.map +1 -1
  72. package/dist/channel/modules/channels/pages/CreateConnectionPage.d.ts +1 -2
  73. package/dist/channel/modules/channels/pages/CreateConnectionPage.js +37 -38
  74. package/dist/channel/modules/channels/pages/CreateConnectionPage.js.map +1 -1
  75. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts +1 -2
  76. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js +7 -12
  77. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js.map +1 -1
  78. package/dist/channel/modules/channels/pages/EditChannelPage.d.ts +1 -2
  79. package/dist/channel/modules/channels/pages/EditChannelPage.js +105 -103
  80. package/dist/channel/modules/channels/pages/EditChannelPage.js.map +1 -1
  81. package/dist/channel/modules/channels/pages/EditConnectionPage.d.ts +1 -2
  82. package/dist/channel/modules/channels/pages/EditConnectionPage.js +22 -23
  83. package/dist/channel/modules/channels/pages/EditConnectionPage.js.map +1 -1
  84. package/dist/channel/modules/channels/pages/SendMessagePage.d.ts +1 -2
  85. package/dist/channel/modules/channels/pages/SendMessagePage.js +180 -187
  86. package/dist/channel/modules/channels/pages/SendMessagePage.js.map +1 -1
  87. package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts +1 -2
  88. package/dist/channel/modules/channels/pages/WebhookEventsPage.js +144 -149
  89. package/dist/channel/modules/channels/pages/WebhookEventsPage.js.map +1 -1
  90. package/dist/channel/pages/ChannelLandingPage.d.ts +1 -2
  91. package/dist/channel/pages/ChannelLandingPage.js +20 -21
  92. package/dist/channel/pages/ChannelLandingPage.js.map +1 -1
  93. package/dist/channel/providers/ChannelProvider.d.ts +0 -2
  94. package/dist/channel/providers/ChannelProvider.js +1 -2
  95. package/dist/channel/providers/ChannelProvider.js.map +1 -1
  96. package/dist/channel/types/index.d.ts +0 -2
  97. package/dist/channel/utils/shellBridge.d.ts +0 -1
  98. package/dist/channel/utils/shellBridge.js +1 -2
  99. package/dist/channel/utils/shellBridge.js.map +1 -1
  100. package/dist/dev/App.d.ts +1 -2
  101. package/dist/dev/main.d.ts +0 -2
  102. package/dist/generated/global-operations.d.ts +885 -336
  103. package/dist/generated/global-operations.js +2 -3
  104. package/dist/generated/global-operations.js.map +1 -1
  105. package/dist/generated/global-types.d.ts +2 -22
  106. package/dist/generated/global-types.js +1 -2
  107. package/dist/generated/global-types.js.map +1 -1
  108. package/dist/generated/wspace-operations.d.ts +4 -2
  109. package/dist/generated/wspace-types.d.ts +4 -24
  110. package/dist/index.d.ts +0 -1
  111. package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js +1 -2
  112. package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -1
  113. package/dist/node_modules/@apollo/client/errors/utils.js +1 -2
  114. package/dist/node_modules/@apollo/client/errors/utils.js.map +1 -1
  115. package/dist/translations/en.d.ts +0 -1
  116. package/dist/utils/nativeBridge.d.ts +0 -1
  117. package/dist/utils/nativeBridge.js +1 -2
  118. package/package.json +65 -43
  119. package/dist/channel/ChannelRoot.d.ts.map +0 -1
  120. package/dist/channel/ChannelRoutes.d.ts.map +0 -1
  121. package/dist/channel/components/AdapterCredentialsForm.d.ts.map +0 -1
  122. package/dist/channel/components/FeatureNotEnabled.d.ts.map +0 -1
  123. package/dist/channel/components/MarkdownEditor.d.ts.map +0 -1
  124. package/dist/channel/components/PermissionGuard.d.ts.map +0 -1
  125. package/dist/channel/config/adapterCredentials.d.ts.map +0 -1
  126. package/dist/channel/constants/permissions.d.ts.map +0 -1
  127. package/dist/channel/graphql/global-client.d.ts.map +0 -1
  128. package/dist/channel/hooks/useChannelOrgSettings.d.ts.map +0 -1
  129. package/dist/channel/hooks/useChannelSubscription.d.ts.map +0 -1
  130. package/dist/channel/hooks/useChannels.d.ts.map +0 -1
  131. package/dist/channel/hooks/useTr.d.ts.map +0 -1
  132. package/dist/channel/index.d.ts.map +0 -1
  133. package/dist/channel/modules/channels/hooks/useExport.d.ts.map +0 -1
  134. package/dist/channel/modules/channels/i18n.d.ts.map +0 -1
  135. package/dist/channel/modules/channels/pages/ChannelDashboardPage.d.ts.map +0 -1
  136. package/dist/channel/modules/channels/pages/ChannelDetailsPage.d.ts.map +0 -1
  137. package/dist/channel/modules/channels/pages/ChannelSettingsPage.d.ts.map +0 -1
  138. package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts.map +0 -1
  139. package/dist/channel/modules/channels/pages/ChannelsListPage.d.ts.map +0 -1
  140. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.d.ts.map +0 -1
  141. package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts.map +0 -1
  142. package/dist/channel/modules/channels/pages/CreateChannelPage.d.ts.map +0 -1
  143. package/dist/channel/modules/channels/pages/CreateConnectionPage.d.ts.map +0 -1
  144. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts.map +0 -1
  145. package/dist/channel/modules/channels/pages/EditChannelPage.d.ts.map +0 -1
  146. package/dist/channel/modules/channels/pages/EditConnectionPage.d.ts.map +0 -1
  147. package/dist/channel/modules/channels/pages/SendMessagePage.d.ts.map +0 -1
  148. package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts.map +0 -1
  149. package/dist/channel/pages/ChannelLandingPage.d.ts.map +0 -1
  150. package/dist/channel/providers/ChannelProvider.d.ts.map +0 -1
  151. package/dist/channel/types/index.d.ts.map +0 -1
  152. package/dist/channel/utils/shellBridge.d.ts.map +0 -1
  153. package/dist/dev/App.d.ts.map +0 -1
  154. package/dist/dev/main.d.ts.map +0 -1
  155. package/dist/generated/global-operations.d.ts.map +0 -1
  156. package/dist/generated/global-types.d.ts.map +0 -1
  157. package/dist/generated/wspace-operations.d.ts.map +0 -1
  158. package/dist/generated/wspace-types.d.ts.map +0 -1
  159. package/dist/index.d.ts.map +0 -1
  160. package/dist/translations/en.d.ts.map +0 -1
  161. package/dist/utils/nativeBridge.d.ts.map +0 -1
@@ -1,17 +1,17 @@
1
1
  import { useTr as e } from "../../../hooks/useTr.js";
2
- import { nativeImpact as t, nativeNotify as n } from "../../../../utils/nativeBridge.js";
3
- import { useChannel as r, useChannels as i } from "../../../hooks/useChannels.js";
2
+ import { useChannel as t, useChannels as n } from "../../../hooks/useChannels.js";
3
+ import { nativeImpact as r, nativeNotify as i } from "../../../../utils/nativeBridge.js";
4
4
  import { PermissionGuard as a } from "../../../components/PermissionGuard.js";
5
5
  import { CHANNEL_PERMISSIONS as o } from "../../../constants/permissions.js";
6
6
  import { MarkdownEditor as ee } from "../../../components/MarkdownEditor.js";
7
- import { useEffect as s, useMemo as c, useRef as l, useState as u } from "react";
8
- import { AlertCircle as d, ArrowLeft as te, Bell as ne, Hash as re, Inbox as ie, Loader2 as f, Mail as p, MessageCircle as m, MessageSquare as h, Save as g, Send as _, Smartphone as v, Trash2 as y, Users as b } from "lucide-react";
9
- import { useNavigate as x, useParams as S } from "react-router";
10
- import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
11
- import { EmphasisPanel as ae, GlassCard as oe, PagePurpose as se } from "@burdenoff/fe-libs/ui";
12
- //#region src/channel/modules/channels/pages/EditChannelPage.tsx
7
+ import { useEffect as te, useMemo as s, useRef as c, useState as l } from "react";
8
+ import { AlertCircle as u, ArrowLeft as ne, Bell as re, Hash as ie, Inbox as d, Loader2 as f, Mail as p, MessageCircle as m, MessageSquare as h, Save as g, Send as ae, Smartphone as _, Trash2 as v, Users as y } from "lucide-react";
9
+ import { useNavigate as b, useParams as x } from "react-router";
10
+ import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
11
+ import { EmphasisPanel as T, GlassCard as oe, PagePurpose as se } from "@burdenoff/fe-libs/ui";
12
+ // src/channel/modules/channels/pages/EditChannelPage.tsx
13
13
  function E() {
14
- let E = x(), { channelId: D } = S(), { channel: O, isLoading: ce, error: le } = r(D), { updateChannel: k, deleteChannel: A } = i(), j = e(), M = c(() => [
14
+ let E = b(), { channelId: D } = x(), { channel: O, isLoading: ce, error: le } = t(D), { updateChannel: k, deleteChannel: A } = n(), j = e(), M = s(() => [
15
15
  {
16
16
  value: "EMAIL",
17
17
  labelKey: "channel.platformLabel.email",
@@ -64,7 +64,7 @@ function E() {
64
64
  labelFallback: "SMS",
65
65
  descriptionKey: "channel.platformDescription.smsDescription",
66
66
  descriptionFallback: "Send text messages",
67
- icon: v,
67
+ icon: _,
68
68
  color: "text-status-success-text bg-status-success-bg-subtle border-status-success-border/30",
69
69
  adapters: [
70
70
  {
@@ -105,7 +105,7 @@ function E() {
105
105
  labelFallback: "Push",
106
106
  descriptionKey: "channel.platformDescription.pushDescription",
107
107
  descriptionFallback: "Mobile & web push",
108
- icon: ne,
108
+ icon: re,
109
109
  color: "text-accent-purple bg-accent-purple-subtle border-accent-purple/30",
110
110
  adapters: [
111
111
  {
@@ -136,7 +136,7 @@ function E() {
136
136
  labelFallback: "In-App",
137
137
  descriptionKey: "channel.platformDescription.inAppDescription",
138
138
  descriptionFallback: "Internal in-app notifications",
139
- icon: ie,
139
+ icon: d,
140
140
  color: "text-status-warning-text bg-status-warning-bg-subtle border-status-warning-border/30",
141
141
  adapters: [{
142
142
  value: "INAPP_NATIVE",
@@ -168,7 +168,7 @@ function E() {
168
168
  labelFallback: "Slack",
169
169
  descriptionKey: "channel.platformDescription.slackDescription",
170
170
  descriptionFallback: "Slack bot & channels",
171
- icon: re,
171
+ icon: ie,
172
172
  color: "text-accent-purple bg-accent-purple-subtle border-accent-purple/30",
173
173
  adapters: [{
174
174
  value: "SLACK_BOT",
@@ -182,7 +182,7 @@ function E() {
182
182
  labelFallback: "Teams",
183
183
  descriptionKey: "channel.platformDescription.teamsDescription",
184
184
  descriptionFallback: "Microsoft Teams",
185
- icon: b,
185
+ icon: y,
186
186
  color: "text-status-info-text bg-status-info-bg-subtle border-status-info-border",
187
187
  adapters: [{
188
188
  value: "TEAMS_BOT",
@@ -224,7 +224,7 @@ function E() {
224
224
  labelFallback: "Webhook",
225
225
  descriptionKey: "channel.platformDescription.webhookDescription",
226
226
  descriptionFallback: "Generic HTTP webhook",
227
- icon: _,
227
+ icon: ae,
228
228
  color: "text-text-secondary bg-bg-sunken/50 border-border-subtle",
229
229
  adapters: [{
230
230
  value: "WEBHOOK_HTTP",
@@ -232,7 +232,7 @@ function E() {
232
232
  labelFallback: "HTTP Webhook"
233
233
  }]
234
234
  }
235
- ], []), N = c(() => [
235
+ ], []), N = s(() => [
236
236
  {
237
237
  value: 0,
238
238
  label: j("channel.priorityLabel.lowest", "0 - Lowest")
@@ -253,100 +253,100 @@ function E() {
253
253
  value: 4,
254
254
  label: j("channel.priorityLabel.highest", "4 - Highest")
255
255
  }
256
- ], [j]), [P, F] = u(""), [I, L] = u(""), [R, z] = u("AWS_SES"), [B, V] = u(2), [H, U] = u("INACTIVE"), [W, G] = u(!1), [K, q] = u(!1), [J, Y] = u(null), [X, Z] = u(!1), Q = l(null);
257
- s(() => {
256
+ ], [j]), [P, F] = l(""), [I, L] = l(""), [R, z] = l("AWS_SES"), [B, V] = l(2), [H, U] = l("INACTIVE"), [W, G] = l(!1), [K, q] = l(!1), [J, Y] = l(null), [X, Z] = l(!1), Q = c(null);
257
+ te(() => {
258
258
  O && O.id !== Q.current && (Q.current = O.id, Promise.resolve().then(() => {
259
259
  F(O.name || ""), L(O.description || ""), z(O.adapterType || "AWS_SES"), V(O.priority || 2), U(O.status || "INACTIVE");
260
260
  }));
261
261
  }, [O]);
262
262
  let ue = O?.platform || "EMAIL", $ = M.find((e) => e.value === ue);
263
- return ce ? /* @__PURE__ */ w("div", {
263
+ return ce ? /* @__PURE__ */ C("div", {
264
264
  className: "flex items-center justify-center min-h-screen",
265
- children: /* @__PURE__ */ w(f, { className: "size-8 animate-spin text-text-secondary" })
266
- }) : le || !O ? /* @__PURE__ */ T("div", {
265
+ children: /* @__PURE__ */ C(f, { className: "size-8 animate-spin text-text-secondary" })
266
+ }) : le || !O ? /* @__PURE__ */ w("div", {
267
267
  className: "flex flex-col items-center justify-center min-h-screen gap-4",
268
268
  children: [
269
- /* @__PURE__ */ w(d, { className: "size-12 text-status-error-text" }),
270
- /* @__PURE__ */ w("h1", {
269
+ /* @__PURE__ */ C(u, { className: "size-12 text-status-error-text" }),
270
+ /* @__PURE__ */ C("h1", {
271
271
  className: "text-xl font-semibold",
272
272
  children: j("channel.channelNotFound", "Channel not found")
273
273
  }),
274
- /* @__PURE__ */ w("button", {
274
+ /* @__PURE__ */ C("button", {
275
275
  type: "button",
276
276
  onClick: () => E("../list"),
277
277
  className: "text-primary hover:underline",
278
278
  children: j("channel.backToChannels", "Back to channels")
279
279
  })
280
280
  ]
281
- }) : /* @__PURE__ */ w(a, {
281
+ }) : /* @__PURE__ */ C(a, {
282
282
  permission: o.CHANNEL_UPDATE,
283
- children: /* @__PURE__ */ T("div", {
283
+ children: /* @__PURE__ */ w("div", {
284
284
  className: "min-h-screen bg-bg-surface",
285
- children: [/* @__PURE__ */ w("div", {
285
+ children: [/* @__PURE__ */ C("div", {
286
286
  className: "border-b bg-bg-surface",
287
- children: /* @__PURE__ */ w("div", {
287
+ children: /* @__PURE__ */ C("div", {
288
288
  className: "container mx-auto px-6 py-4",
289
- children: /* @__PURE__ */ T("div", {
289
+ children: /* @__PURE__ */ w("div", {
290
290
  className: "flex items-center gap-4",
291
- children: [/* @__PURE__ */ w("button", {
291
+ children: [/* @__PURE__ */ C("button", {
292
292
  type: "button",
293
293
  onClick: () => E(`/channels/${D}`),
294
294
  className: "p-2 hover:bg-bg-sunken rounded-lg transition-colors",
295
- children: /* @__PURE__ */ w(te, { className: "size-5 " })
296
- }), /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("h1", {
295
+ children: /* @__PURE__ */ C(ne, { className: "size-5 " })
296
+ }), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("h1", {
297
297
  className: "text-2xl font-bold",
298
298
  children: j("channel.editChannel", "Edit Channel")
299
- }), /* @__PURE__ */ w("p", {
299
+ }), /* @__PURE__ */ C("p", {
300
300
  className: "text-sm text-text-secondary",
301
301
  children: j("channel.updateChannelConfig", "Update channel configuration")
302
302
  })] })]
303
303
  })
304
304
  })
305
- }), /* @__PURE__ */ w("div", {
305
+ }), /* @__PURE__ */ C("div", {
306
306
  className: "container mx-auto px-6 py-8 max-w-2xl",
307
- children: /* @__PURE__ */ T("div", {
307
+ children: /* @__PURE__ */ w("div", {
308
308
  className: "space-y-6",
309
309
  children: [
310
- /* @__PURE__ */ w(se, {
311
- icon: /* @__PURE__ */ w(g, {
310
+ /* @__PURE__ */ C(se, {
311
+ icon: /* @__PURE__ */ C(g, {
312
312
  size: 15,
313
313
  "aria-hidden": "true"
314
314
  }),
315
315
  children: j("channel.editChannelPurpose", "Change how this channel behaves — its name, description, priority and status. The platform and provider stay fixed (they define what the channel is); to swap credentials use the channel's connection instead. Use this to rename a channel, bump its priority, or temporarily deactivate it without deleting it.")
316
316
  }),
317
- J && /* @__PURE__ */ T("div", {
317
+ J && /* @__PURE__ */ w("div", {
318
318
  className: "p-4 rounded-lg bg-status-error-bg/10 border border-status-error-border/20 flex items-center gap-3",
319
- children: [/* @__PURE__ */ w(d, { className: "size-5 text-status-error-text shrink-0" }), /* @__PURE__ */ w("p", {
319
+ children: [/* @__PURE__ */ C(u, { className: "size-5 text-status-error-text shrink-0" }), /* @__PURE__ */ C("p", {
320
320
  className: "text-sm text-status-error-text",
321
321
  children: J
322
322
  })]
323
323
  }),
324
- /* @__PURE__ */ T(oe, {
324
+ /* @__PURE__ */ w(oe, {
325
325
  treatment: "insight",
326
326
  className: "p-4 border-border-seam space-y-2",
327
- children: [/* @__PURE__ */ w("div", {
327
+ children: [/* @__PURE__ */ C("div", {
328
328
  className: "flex items-center gap-2",
329
- children: $ && /* @__PURE__ */ T(C, { children: [(() => {
329
+ children: $ && /* @__PURE__ */ w(S, { children: [(() => {
330
330
  let e = $.icon;
331
- return /* @__PURE__ */ w(e, { className: "size-5 text-text-secondary" });
332
- })(), /* @__PURE__ */ w("span", {
331
+ return /* @__PURE__ */ C(e, { className: "size-5 text-text-secondary" });
332
+ })(), /* @__PURE__ */ C("span", {
333
333
  className: "font-medium",
334
334
  children: j($.labelKey, $.labelFallback)
335
335
  })] })
336
- }), /* @__PURE__ */ w("p", {
336
+ }), /* @__PURE__ */ C("p", {
337
337
  className: "text-sm text-text-secondary",
338
338
  children: j("channel.platformLockedHint", "Platform cannot be changed after channel creation. Create a new channel to use a different platform.")
339
339
  })]
340
340
  }),
341
- /* @__PURE__ */ T(ae, {
341
+ /* @__PURE__ */ w(T, {
342
342
  className: "p-5 space-y-6",
343
343
  children: [
344
- /* @__PURE__ */ T("div", {
344
+ /* @__PURE__ */ w("div", {
345
345
  className: "space-y-2",
346
- children: [/* @__PURE__ */ T("label", {
346
+ children: [/* @__PURE__ */ w("label", {
347
347
  className: "text-sm font-medium",
348
348
  children: [j("channel.channelName", "Channel Name"), " *"]
349
- }), /* @__PURE__ */ w("input", {
349
+ }), /* @__PURE__ */ C("input", {
350
350
  "aria-label": j("channel.editNamePlaceholder", "e.g., Production Email, Customer SMS"),
351
351
  type: "text",
352
352
  value: P,
@@ -355,13 +355,13 @@ function E() {
355
355
  className: "w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary"
356
356
  })]
357
357
  }),
358
- /* @__PURE__ */ T("div", {
358
+ /* @__PURE__ */ w("div", {
359
359
  className: "space-y-2",
360
- children: [/* @__PURE__ */ w("label", {
360
+ children: [/* @__PURE__ */ C("label", {
361
361
  htmlFor: "channel-edit-description",
362
362
  className: "text-sm font-medium",
363
363
  children: j("channel.description", "Description")
364
- }), /* @__PURE__ */ w(ee, {
364
+ }), /* @__PURE__ */ C(ee, {
365
365
  id: "channel-edit-description",
366
366
  value: I,
367
367
  onChange: L,
@@ -370,63 +370,63 @@ function E() {
370
370
  rows: 3
371
371
  })]
372
372
  }),
373
- $ && /* @__PURE__ */ T("div", {
373
+ $ && /* @__PURE__ */ w("div", {
374
374
  className: "space-y-2",
375
- children: [/* @__PURE__ */ w("label", {
375
+ children: [/* @__PURE__ */ C("label", {
376
376
  className: "text-sm font-medium",
377
377
  children: j("channel.adapterProvider", "Adapter / Provider")
378
- }), /* @__PURE__ */ w("select", {
378
+ }), /* @__PURE__ */ C("select", {
379
379
  value: R,
380
380
  onChange: (e) => z(e.target.value),
381
381
  className: "w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary",
382
- children: $.adapters.map((e) => /* @__PURE__ */ w("option", {
382
+ children: $.adapters.map((e) => /* @__PURE__ */ C("option", {
383
383
  value: e.value,
384
384
  children: j(e.labelKey, e.labelFallback)
385
385
  }, e.value))
386
386
  })]
387
387
  }),
388
- /* @__PURE__ */ T("div", {
388
+ /* @__PURE__ */ w("div", {
389
389
  className: "grid grid-cols-2 gap-4",
390
- children: [/* @__PURE__ */ T("div", {
390
+ children: [/* @__PURE__ */ w("div", {
391
391
  className: "space-y-2",
392
392
  children: [
393
- /* @__PURE__ */ w("label", {
393
+ /* @__PURE__ */ C("label", {
394
394
  className: "text-sm font-medium",
395
395
  children: j("channel.priority", "Priority")
396
396
  }),
397
- /* @__PURE__ */ w("select", {
397
+ /* @__PURE__ */ C("select", {
398
398
  value: B,
399
399
  onChange: (e) => V(Number(e.target.value)),
400
400
  className: "w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary",
401
- children: N.map((e) => /* @__PURE__ */ w("option", {
401
+ children: N.map((e) => /* @__PURE__ */ C("option", {
402
402
  value: e.value,
403
403
  children: e.label
404
404
  }, e.value))
405
405
  }),
406
- /* @__PURE__ */ w("p", {
406
+ /* @__PURE__ */ C("p", {
407
407
  className: "text-xs text-text-secondary",
408
408
  children: j("channel.priorityFailoverHint", "Higher priority channels are used first in failover")
409
409
  })
410
410
  ]
411
- }), /* @__PURE__ */ T("div", {
411
+ }), /* @__PURE__ */ w("div", {
412
412
  className: "space-y-2",
413
- children: [/* @__PURE__ */ w("label", {
413
+ children: [/* @__PURE__ */ C("label", {
414
414
  className: "text-sm font-medium",
415
415
  children: j("channel.status", "Status")
416
- }), /* @__PURE__ */ T("select", {
416
+ }), /* @__PURE__ */ w("select", {
417
417
  value: H,
418
418
  onChange: (e) => U(e.target.value),
419
419
  className: "w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary",
420
420
  children: [
421
- /* @__PURE__ */ w("option", {
421
+ /* @__PURE__ */ C("option", {
422
422
  value: "INACTIVE",
423
423
  children: j("channel.statusLabel.inactive", "Inactive")
424
424
  }),
425
- /* @__PURE__ */ w("option", {
425
+ /* @__PURE__ */ C("option", {
426
426
  value: "ACTIVE",
427
427
  children: j("channel.statusLabel.active", "Active")
428
428
  }),
429
- /* @__PURE__ */ w("option", {
429
+ /* @__PURE__ */ C("option", {
430
430
  value: "SUSPENDED",
431
431
  children: j("channel.statusLabel.suspended", "Suspended")
432
432
  })
@@ -436,80 +436,83 @@ function E() {
436
436
  })
437
437
  ]
438
438
  }),
439
- /* @__PURE__ */ T("div", {
439
+ /* @__PURE__ */ w("div", {
440
440
  className: "flex items-center justify-between pt-6 border-t",
441
- children: [/* @__PURE__ */ w("div", { children: X ? /* @__PURE__ */ T("div", {
441
+ children: [/* @__PURE__ */ C("div", { children: X ? /* @__PURE__ */ w("div", {
442
442
  className: "flex items-center gap-2",
443
443
  children: [
444
- /* @__PURE__ */ w("span", {
444
+ /* @__PURE__ */ C("span", {
445
445
  className: "text-sm text-text-secondary",
446
446
  children: j("channel.confirmDelete", "Confirm delete?")
447
447
  }),
448
- /* @__PURE__ */ T("button", {
448
+ /* @__PURE__ */ w("button", {
449
449
  type: "button",
450
450
  onClick: async () => {
451
- if (!(!D || !X)) {
452
- t("medium"), q(!0);
451
+ if (D && X) {
452
+ r("medium"), q(!0);
453
453
  try {
454
- await A(D) ? (n("success"), E("../list")) : n("error");
454
+ await A(D) ? (i("success"), E("../list")) : i("error");
455
455
  } catch (e) {
456
- n("error"), Y(e instanceof Error ? e.message : j("channel.deleteFailed", "Failed to delete channel")), q(!1);
456
+ i("error");
457
+ let t = e instanceof Error ? e.message : j("channel.deleteFailed", "Failed to delete channel");
458
+ Y(t), q(!1);
457
459
  }
458
460
  }
459
461
  },
460
462
  disabled: K,
461
463
  className: "px-4 py-2 text-sm bg-status-error-bg text-status-error-text rounded-lg hover:bg-status-error-bg/90 transition-colors flex items-center gap-2",
462
- children: [K ? /* @__PURE__ */ w(f, { className: "size-4 animate-spin" }) : /* @__PURE__ */ w(y, { className: "size-4 " }), j("channel.delete", "Delete")]
464
+ children: [K ? /* @__PURE__ */ C(f, { className: "size-4 animate-spin" }) : /* @__PURE__ */ C(v, { className: "size-4 " }), j("channel.delete", "Delete")]
463
465
  }),
464
- /* @__PURE__ */ w("button", {
466
+ /* @__PURE__ */ C("button", {
465
467
  type: "button",
466
468
  onClick: () => Z(!1),
467
469
  className: "px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors",
468
470
  children: j("channel.cancel", "Cancel")
469
471
  })
470
472
  ]
471
- }) : /* @__PURE__ */ w(a, {
473
+ }) : /* @__PURE__ */ C(a, {
472
474
  permission: o.CHANNEL_DELETE,
473
- children: /* @__PURE__ */ T("button", {
475
+ children: /* @__PURE__ */ w("button", {
474
476
  type: "button",
475
477
  onClick: () => Z(!0),
476
478
  className: "px-4 py-2 text-sm text-status-error-text hover:bg-status-error-bg/10 rounded-lg transition-colors flex items-center gap-2",
477
- children: [/* @__PURE__ */ w(y, { className: "size-4 " }), j("channel.deleteChannel", "Delete Channel")]
479
+ children: [/* @__PURE__ */ C(v, { className: "size-4 " }), j("channel.deleteChannel", "Delete Channel")]
478
480
  })
479
- }) }), /* @__PURE__ */ T("div", {
481
+ }) }), /* @__PURE__ */ w("div", {
480
482
  className: "flex items-center gap-3",
481
- children: [/* @__PURE__ */ w("button", {
483
+ children: [/* @__PURE__ */ C("button", {
482
484
  type: "button",
483
485
  onClick: () => E(`/channels/${D}`),
484
486
  className: "px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors",
485
487
  children: j("channel.cancel", "Cancel")
486
- }), /* @__PURE__ */ T("button", {
488
+ }), /* @__PURE__ */ w("button", {
487
489
  type: "button",
488
490
  onClick: async () => {
489
491
  if (D) {
490
- if (!P.trim()) {
491
- Y(j("channel.validation.nameRequired", "Channel name is required"));
492
- return;
493
- }
494
- G(!0), Y(null);
495
- try {
496
- await k(D, {
497
- name: P.trim(),
498
- description: I.trim() || void 0,
499
- adapterType: R,
500
- priority: B,
501
- status: H
502
- }) ? E(`/channels/${D}`) : Y(j("channel.updateFailed", "Failed to update channel"));
503
- } catch (e) {
504
- Y(e instanceof Error ? e.message : j("channel.updateFailed", "Failed to update channel"));
505
- } finally {
506
- G(!1);
492
+ if (!P.trim()) Y(j("channel.validation.nameRequired", "Channel name is required"));
493
+ else {
494
+ G(!0), Y(null);
495
+ try {
496
+ let e = {
497
+ name: P.trim(),
498
+ description: I.trim() || void 0,
499
+ adapterType: R,
500
+ priority: B,
501
+ status: H
502
+ };
503
+ await k(D, e) ? E(`/channels/${D}`) : Y(j("channel.updateFailed", "Failed to update channel"));
504
+ } catch (e) {
505
+ let t = e instanceof Error ? e.message : j("channel.updateFailed", "Failed to update channel");
506
+ Y(t);
507
+ } finally {
508
+ G(!1);
509
+ }
507
510
  }
508
511
  }
509
512
  },
510
513
  disabled: W || !P.trim(),
511
514
  className: "px-6 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors flex items-center gap-2 disabled:opacity-50",
512
- children: [W ? /* @__PURE__ */ w(f, { className: "size-4 animate-spin" }) : /* @__PURE__ */ w(g, { className: "size-4 " }), j("channel.saveChanges", "Save Changes")]
515
+ children: [W ? /* @__PURE__ */ C(f, { className: "size-4 animate-spin" }) : /* @__PURE__ */ C(g, { className: "size-4 " }), j("channel.saveChanges", "Save Changes")]
513
516
  })]
514
517
  })]
515
518
  })
@@ -519,7 +522,6 @@ function E() {
519
522
  })
520
523
  });
521
524
  }
522
- //#endregion
523
525
  export { E as EditChannelPage };
524
526
 
525
527
  //# sourceMappingURL=EditChannelPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditChannelPage.js","names":[],"sources":["../../../../../src/channel/modules/channels/pages/EditChannelPage.tsx"],"sourcesContent":["/**\n * Edit Channel Page\n *\n * Allows editing an existing channel's configuration.\n * Uses the same form structure as CreateChannelPage but pre-fills existing values.\n */\n\nimport { useState, useEffect, useRef, useMemo } from 'react';\nimport { useNavigate, useParams } from 'react-router';\nimport { useTr } from '../../../hooks/useTr';\nimport {\n ArrowLeft,\n Save,\n Loader2,\n AlertCircle,\n Mail,\n Smartphone,\n Bell,\n Inbox,\n MessageSquare,\n Hash,\n Users,\n MessageCircle,\n Send,\n Trash2,\n} from 'lucide-react';\nimport { useChannel, useChannels } from '../../../hooks/useChannels';\nimport {\n type ChannelPlatform,\n type AdapterType,\n type ChannelStatus,\n type UpdateChannelInput,\n} from '../../../hooks/useChannels';\nimport { EmphasisPanel, GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { nativeImpact, nativeNotify } from '../../../../utils/nativeBridge';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\nimport { MarkdownEditor } from '../../../components/MarkdownEditor';\n\ntype PlatformOption = {\n value: ChannelPlatform;\n labelKey: string;\n labelFallback: string;\n descriptionKey: string;\n descriptionFallback: string;\n icon: typeof Mail;\n color: string;\n adapters: { value: AdapterType; labelKey: string; labelFallback: string }[];\n};\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport function EditChannelPage() {\n const navigate = useNavigate();\n const { channelId } = useParams<{ channelId: string }>();\n const { channel, isLoading, error } = useChannel(channelId!);\n const { updateChannel, deleteChannel } = useChannels();\n const tr = useTr();\n\n const PLATFORM_OPTIONS: PlatformOption[] = useMemo(\n () => [\n {\n value: 'EMAIL',\n labelKey: 'channel.platformLabel.email',\n labelFallback: 'Email',\n descriptionKey: 'channel.platformDescription.emailDescription',\n descriptionFallback: 'Send emails via various providers',\n icon: Mail,\n color: 'text-status-info-text bg-status-info-bg-subtle border-status-info-border',\n adapters: [\n { value: 'AWS_SES', labelKey: 'channel.adapter.awsSes', labelFallback: 'AWS SES' },\n { value: 'MAILGUN', labelKey: 'channel.adapter.mailgun', labelFallback: 'Mailgun' },\n { value: 'POSTMARK', labelKey: 'channel.adapter.postmark', labelFallback: 'Postmark' },\n { value: 'MANDRILL', labelKey: 'channel.adapter.mandrill', labelFallback: 'Mandrill' },\n { value: 'RESEND', labelKey: 'channel.adapter.resend', labelFallback: 'Resend' },\n {\n value: 'AZURE_ACS',\n labelKey: 'channel.adapter.azureAcs',\n labelFallback: 'Azure Communication Services',\n },\n { value: 'SMTP', labelKey: 'channel.adapter.smtp', labelFallback: 'Custom SMTP' },\n ],\n },\n {\n value: 'SMS',\n labelKey: 'channel.platformLabel.sms',\n labelFallback: 'SMS',\n descriptionKey: 'channel.platformDescription.smsDescription',\n descriptionFallback: 'Send text messages',\n icon: Smartphone,\n color:\n 'text-status-success-text bg-status-success-bg-subtle border-status-success-border/30',\n adapters: [\n { value: 'TWILIO_SMS', labelKey: 'channel.adapter.twilio', labelFallback: 'Twilio' },\n { value: 'AWS_SNS', labelKey: 'channel.adapter.awsSns', labelFallback: 'AWS SNS' },\n { value: 'VONAGE', labelKey: 'channel.adapter.vonage', labelFallback: 'Vonage' },\n { value: 'PLIVO', labelKey: 'channel.adapter.plivo', labelFallback: 'Plivo' },\n {\n value: 'MESSAGEBIRD',\n labelKey: 'channel.adapter.messagebird',\n labelFallback: 'MessageBird',\n },\n { value: 'INFOBIP', labelKey: 'channel.adapter.infobip', labelFallback: 'Infobip' },\n ],\n },\n {\n value: 'PUSH',\n labelKey: 'channel.platformLabel.push',\n labelFallback: 'Push',\n descriptionKey: 'channel.platformDescription.pushDescription',\n descriptionFallback: 'Mobile & web push',\n icon: Bell,\n color: 'text-accent-purple bg-accent-purple-subtle border-accent-purple/30',\n adapters: [\n {\n value: 'FCM',\n labelKey: 'channel.adapter.fcm',\n labelFallback: 'Firebase Cloud Messaging',\n },\n {\n value: 'APNS',\n labelKey: 'channel.adapter.apns',\n labelFallback: 'Apple Push Notification Service',\n },\n { value: 'ONESIGNAL', labelKey: 'channel.adapter.onesignal', labelFallback: 'OneSignal' },\n { value: 'EXPO', labelKey: 'channel.adapter.expo', labelFallback: 'Expo Push' },\n ],\n },\n {\n value: 'INAPP',\n labelKey: 'channel.platformLabel.inApp',\n labelFallback: 'In-App',\n descriptionKey: 'channel.platformDescription.inAppDescription',\n descriptionFallback: 'Internal in-app notifications',\n icon: Inbox,\n color:\n 'text-status-warning-text bg-status-warning-bg-subtle border-status-warning-border/30',\n adapters: [\n {\n value: 'INAPP_NATIVE',\n labelKey: 'channel.adapter.inAppNative',\n labelFallback: 'Native In-App',\n },\n ],\n },\n {\n value: 'WHATSAPP',\n labelKey: 'channel.platformLabel.whatsapp',\n labelFallback: 'WhatsApp',\n descriptionKey: 'channel.platformDescription.whatsappDescription',\n descriptionFallback: 'WhatsApp Business messaging',\n icon: MessageSquare,\n color:\n 'text-status-success-text bg-status-success-bg-subtle border-status-success-border/30',\n adapters: [\n {\n value: 'WHATSAPP_CLOUD',\n labelKey: 'channel.adapter.whatsappCloud',\n labelFallback: 'WhatsApp Cloud API',\n },\n {\n value: 'WHATSAPP_TWILIO',\n labelKey: 'channel.adapter.whatsappTwilio',\n labelFallback: 'WhatsApp via Twilio',\n },\n ],\n },\n {\n value: 'SLACK',\n labelKey: 'channel.platformLabel.slack',\n labelFallback: 'Slack',\n descriptionKey: 'channel.platformDescription.slackDescription',\n descriptionFallback: 'Slack bot & channels',\n icon: Hash,\n color: 'text-accent-purple bg-accent-purple-subtle border-accent-purple/30',\n adapters: [\n { value: 'SLACK_BOT', labelKey: 'channel.adapter.slackBot', labelFallback: 'Slack Bot' },\n ],\n },\n {\n value: 'TEAMS',\n labelKey: 'channel.platformLabel.teams',\n labelFallback: 'Teams',\n descriptionKey: 'channel.platformDescription.teamsDescription',\n descriptionFallback: 'Microsoft Teams',\n icon: Users,\n color: 'text-status-info-text bg-status-info-bg-subtle border-status-info-border',\n adapters: [\n { value: 'TEAMS_BOT', labelKey: 'channel.adapter.teamsBot', labelFallback: 'Teams Bot' },\n ],\n },\n {\n value: 'DISCORD',\n labelKey: 'channel.platformLabel.discord',\n labelFallback: 'Discord',\n descriptionKey: 'channel.platformDescription.discordDescription',\n descriptionFallback: 'Discord bots & webhooks',\n icon: MessageCircle,\n color: 'text-accent-indigo bg-accent-indigo-subtle border-accent-indigo/30',\n adapters: [\n {\n value: 'DISCORD_BOT',\n labelKey: 'channel.adapter.discordBot',\n labelFallback: 'Discord Bot',\n },\n ],\n },\n {\n value: 'WEBCHAT',\n labelKey: 'channel.platformLabel.webchat',\n labelFallback: 'Webchat',\n descriptionKey: 'channel.platformDescription.webchatDescription',\n descriptionFallback: 'Website live chat',\n icon: MessageSquare,\n color: 'text-accent-teal bg-accent-teal-subtle border-accent-teal/30',\n adapters: [\n {\n value: 'WEBCHAT_NATIVE',\n labelKey: 'channel.adapter.webchatNative',\n labelFallback: 'Native Webchat',\n },\n ],\n },\n {\n value: 'WEBHOOK',\n labelKey: 'channel.platformLabel.webhook',\n labelFallback: 'Webhook',\n descriptionKey: 'channel.platformDescription.webhookDescription',\n descriptionFallback: 'Generic HTTP webhook',\n icon: Send,\n color: 'text-text-secondary bg-bg-sunken/50 border-border-subtle',\n adapters: [\n {\n value: 'WEBHOOK_HTTP',\n labelKey: 'channel.adapter.webhookHttp',\n labelFallback: 'HTTP Webhook',\n },\n ],\n },\n ],\n []\n );\n\n const PRIORITY_OPTIONS = useMemo(\n () => [\n { value: 0, label: tr('channel.priorityLabel.lowest', '0 - Lowest') },\n { value: 1, label: tr('channel.priorityLabel.low', '1 - Low') },\n { value: 2, label: tr('channel.priorityLabel.normal', '2 - Normal') },\n { value: 3, label: tr('channel.priorityLabel.high', '3 - High') },\n { value: 4, label: tr('channel.priorityLabel.highest', '4 - Highest') },\n ],\n [tr]\n );\n\n // Form state\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [adapterType, setAdapterType] = useState<AdapterType>('AWS_SES');\n const [priority, setPriority] = useState(2);\n const [status, setStatus] = useState<ChannelStatus>('INACTIVE');\n\n // UI state\n const [isSaving, setIsSaving] = useState(false);\n const [isDeleting, setIsDeleting] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [deleteConfirm, setDeleteConfirm] = useState(false);\n\n // Load channel data into form — guard against re-initialization and defer\n // the state update to a microtask so setState does not run synchronously\n // inside the effect body (react-hooks/set-state-in-effect).\n const loadedChannelIdRef = useRef<string | null>(null);\n useEffect(() => {\n if (channel && channel.id !== loadedChannelIdRef.current) {\n loadedChannelIdRef.current = channel.id;\n void Promise.resolve().then(() => {\n setName(channel.name || '');\n setDescription(channel.description || '');\n setAdapterType((channel.adapterType || 'AWS_SES') as AdapterType);\n setPriority(channel.priority || 2);\n setStatus((channel.status || 'INACTIVE') as ChannelStatus);\n });\n }\n }, [channel]);\n\n // Update adapter options when platform changes\n const currentPlatform = (channel?.platform || 'EMAIL') as ChannelPlatform;\n const selectedPlatform = PLATFORM_OPTIONS.find((p) => p.value === currentPlatform);\n\n const handleSave = async () => {\n if (!channelId) return;\n\n if (!name.trim()) {\n setSaveError(tr('channel.validation.nameRequired', 'Channel name is required'));\n return;\n }\n\n setIsSaving(true);\n setSaveError(null);\n\n try {\n const input: UpdateChannelInput = {\n name: name.trim(),\n description: description.trim() || undefined,\n adapterType,\n priority,\n status,\n };\n\n const result = await updateChannel(channelId, input);\n if (result) {\n navigate(`/channels/${channelId}`);\n } else {\n setSaveError(tr('channel.updateFailed', 'Failed to update channel'));\n }\n } catch (err: unknown) {\n const message =\n err instanceof Error ? err.message : tr('channel.updateFailed', 'Failed to update channel');\n setSaveError(message);\n } finally {\n setIsSaving(false);\n }\n };\n\n const handleDelete = async () => {\n if (!channelId || !deleteConfirm) return;\n void nativeImpact('medium');\n\n setIsDeleting(true);\n try {\n const success = await deleteChannel(channelId);\n if (success) {\n void nativeNotify('success');\n navigate('../list');\n } else {\n void nativeNotify('error');\n }\n } catch (err: unknown) {\n void nativeNotify('error');\n const message =\n err instanceof Error ? err.message : tr('channel.deleteFailed', 'Failed to delete channel');\n setSaveError(message);\n setIsDeleting(false);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <Loader2 className=\"size-8 animate-spin text-text-secondary\" />\n </div>\n );\n }\n\n if (error || !channel) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-screen gap-4\">\n <AlertCircle className=\"size-12 text-status-error-text\" />\n <h1 className=\"text-xl font-semibold\">\n {tr('channel.channelNotFound', 'Channel not found')}\n </h1>\n <button\n type=\"button\"\n onClick={() => navigate('../list')}\n className=\"text-primary hover:underline\"\n >\n {tr('channel.backToChannels', 'Back to channels')}\n </button>\n </div>\n );\n }\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_UPDATE}>\n <div className=\"min-h-screen bg-bg-surface\">\n {/* Header */}\n <div className=\"border-b bg-bg-surface\">\n <div className=\"container mx-auto px-6 py-4\">\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"p-2 hover:bg-bg-sunken rounded-lg transition-colors\"\n >\n <ArrowLeft className=\"size-5 \" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold\">{tr('channel.editChannel', 'Edit Channel')}</h1>\n <p className=\"text-sm text-text-secondary\">\n {tr('channel.updateChannelConfig', 'Update channel configuration')}\n </p>\n </div>\n </div>\n </div>\n </div>\n\n {/* Form */}\n <div className=\"container mx-auto px-6 py-8 max-w-2xl\">\n <div className=\"space-y-6\">\n {/* Page purpose */}\n <PagePurpose icon={<Save size={15} aria-hidden=\"true\" />}>\n {tr(\n 'channel.editChannelPurpose',\n \"Change how this channel behaves — its name, description, priority and status. The platform and provider stay fixed (they define what the channel is); to swap credentials use the channel's connection instead. Use this to rename a channel, bump its priority, or temporarily deactivate it without deleting it.\"\n )}\n </PagePurpose>\n\n {/* Error Alert */}\n {saveError && (\n <div className=\"p-4 rounded-lg bg-status-error-bg/10 border border-status-error-border/20 flex items-center gap-3\">\n <AlertCircle className=\"size-5 text-status-error-text shrink-0\" />\n <p className=\"text-sm text-status-error-text\">{saveError}</p>\n </div>\n )}\n\n {/* Channel Info (read-only) */}\n <GlassCard treatment=\"insight\" className=\"p-4 border-border-seam space-y-2\">\n <div className=\"flex items-center gap-2\">\n {selectedPlatform && (\n <>\n {(() => {\n const Icon = selectedPlatform.icon;\n return <Icon className=\"size-5 text-text-secondary\" />;\n })()}\n <span className=\"font-medium\">\n {tr(selectedPlatform.labelKey, selectedPlatform.labelFallback)}\n </span>\n </>\n )}\n </div>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'channel.platformLockedHint',\n 'Platform cannot be changed after channel creation. Create a new channel to use a different platform.'\n )}\n </p>\n </GlassCard>\n\n {/* Channel fields — the editable core of this page */}\n <EmphasisPanel className=\"p-5 space-y-6\">\n {/* Name */}\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">\n {tr('channel.channelName', 'Channel Name')} *\n </label>\n <input\n aria-label={tr(\n 'channel.editNamePlaceholder',\n 'e.g., Production Email, Customer SMS'\n )}\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={tr(\n 'channel.editNamePlaceholder',\n 'e.g., Production Email, Customer SMS'\n )}\n className=\"w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n </div>\n\n {/* Description */}\n <div className=\"space-y-2\">\n <label htmlFor=\"channel-edit-description\" className=\"text-sm font-medium\">\n {tr('channel.description', 'Description')}\n </label>\n <MarkdownEditor\n id=\"channel-edit-description\"\n value={description}\n onChange={setDescription}\n aria-label={tr(\n 'channel.editDescriptionPlaceholder',\n 'Optional description for this channel'\n )}\n placeholder={tr(\n 'channel.editDescriptionPlaceholder',\n 'Optional description for this channel'\n )}\n rows={3}\n />\n </div>\n\n {/* Adapter Type */}\n {selectedPlatform && (\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">\n {tr('channel.adapterProvider', 'Adapter / Provider')}\n </label>\n <select\n value={adapterType}\n onChange={(e) => setAdapterType(e.target.value as AdapterType)}\n className=\"w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n {selectedPlatform.adapters.map((adapter) => (\n <option key={adapter.value} value={adapter.value}>\n {tr(adapter.labelKey, adapter.labelFallback)}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Priority & Status */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">\n {tr('channel.priority', 'Priority')}\n </label>\n <select\n value={priority}\n onChange={(e) => setPriority(Number(e.target.value))}\n className=\"w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n {PRIORITY_OPTIONS.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'channel.priorityFailoverHint',\n 'Higher priority channels are used first in failover'\n )}\n </p>\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{tr('channel.status', 'Status')}</label>\n <select\n value={status}\n onChange={(e) => setStatus(e.target.value as ChannelStatus)}\n className=\"w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"INACTIVE\">\n {tr('channel.statusLabel.inactive', 'Inactive')}\n </option>\n <option value=\"ACTIVE\">{tr('channel.statusLabel.active', 'Active')}</option>\n <option value=\"SUSPENDED\">\n {tr('channel.statusLabel.suspended', 'Suspended')}\n </option>\n </select>\n </div>\n </div>\n </EmphasisPanel>\n\n {/* Actions */}\n <div className=\"flex items-center justify-between pt-6 border-t\">\n {/* Delete */}\n <div>\n {!deleteConfirm ? (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_DELETE}>\n <button\n type=\"button\"\n onClick={() => setDeleteConfirm(true)}\n className=\"px-4 py-2 text-sm text-status-error-text hover:bg-status-error-bg/10 rounded-lg transition-colors flex items-center gap-2\"\n >\n <Trash2 className=\"size-4 \" />\n {tr('channel.deleteChannel', 'Delete Channel')}\n </button>\n </PermissionGuard>\n ) : (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-text-secondary\">\n {tr('channel.confirmDelete', 'Confirm delete?')}\n </span>\n <button\n type=\"button\"\n onClick={handleDelete}\n disabled={isDeleting}\n className=\"px-4 py-2 text-sm bg-status-error-bg text-status-error-text rounded-lg hover:bg-status-error-bg/90 transition-colors flex items-center gap-2\"\n >\n {isDeleting ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Trash2 className=\"size-4 \" />\n )}\n {tr('channel.delete', 'Delete')}\n </button>\n <button\n type=\"button\"\n onClick={() => setDeleteConfirm(false)}\n className=\"px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors\"\n >\n {tr('channel.cancel', 'Cancel')}\n </button>\n </div>\n )}\n </div>\n\n {/* Save */}\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors\"\n >\n {tr('channel.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={isSaving || !name.trim()}\n className=\"px-6 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors flex items-center gap-2 disabled:opacity-50\"\n >\n {isSaving ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Save className=\"size-4 \" />\n )}\n {tr('channel.saveChanges', 'Save Changes')}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAsDA,SAAgB,IAAkB;CAChC,IAAM,IAAW,GAAa,EACxB,EAAE,iBAAc,GAAkC,EAClD,EAAE,YAAS,eAAW,cAAU,EAAW,EAAW,EACtD,EAAE,kBAAe,qBAAkB,GAAa,EAChD,IAAK,GAAO,EAEZ,IAAqC,QACnC;EACJ;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OAAO;GACP,UAAU;IACR;KAAE,OAAO;KAAW,UAAU;KAA0B,eAAe;KAAW;IAClF;KAAE,OAAO;KAAW,UAAU;KAA2B,eAAe;KAAW;IACnF;KAAE,OAAO;KAAY,UAAU;KAA4B,eAAe;KAAY;IACtF;KAAE,OAAO;KAAY,UAAU;KAA4B,eAAe;KAAY;IACtF;KAAE,OAAO;KAAU,UAAU;KAA0B,eAAe;KAAU;IAChF;KACE,OAAO;KACP,UAAU;KACV,eAAe;KAChB;IACD;KAAE,OAAO;KAAQ,UAAU;KAAwB,eAAe;KAAe;IAClF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OACE;GACF,UAAU;IACR;KAAE,OAAO;KAAc,UAAU;KAA0B,eAAe;KAAU;IACpF;KAAE,OAAO;KAAW,UAAU;KAA0B,eAAe;KAAW;IAClF;KAAE,OAAO;KAAU,UAAU;KAA0B,eAAe;KAAU;IAChF;KAAE,OAAO;KAAS,UAAU;KAAyB,eAAe;KAAS;IAC7E;KACE,OAAO;KACP,UAAU;KACV,eAAe;KAChB;IACD;KAAE,OAAO;KAAW,UAAU;KAA2B,eAAe;KAAW;IACpF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OAAO;GACP,UAAU;IACR;KACE,OAAO;KACP,UAAU;KACV,eAAe;KAChB;IACD;KACE,OAAO;KACP,UAAU;KACV,eAAe;KAChB;IACD;KAAE,OAAO;KAAa,UAAU;KAA6B,eAAe;KAAa;IACzF;KAAE,OAAO;KAAQ,UAAU;KAAwB,eAAe;KAAa;IAChF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OACE;GACF,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;IAChB,CACF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OACE;GACF,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;IAChB,EACD;IACE,OAAO;IACP,UAAU;IACV,eAAe;IAChB,CACF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OAAO;GACP,UAAU,CACR;IAAE,OAAO;IAAa,UAAU;IAA4B,eAAe;IAAa,CACzF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OAAO;GACP,UAAU,CACR;IAAE,OAAO;IAAa,UAAU;IAA4B,eAAe;IAAa,CACzF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OAAO;GACP,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;IAChB,CACF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OAAO;GACP,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;IAChB,CACF;GACF;EACD;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAM;GACN,OAAO;GACP,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;IAChB,CACF;GACF;EACF,EACD,EAAE,CACH,EAEK,IAAmB,QACjB;EACJ;GAAE,OAAO;GAAG,OAAO,EAAG,gCAAgC,aAAa;GAAE;EACrE;GAAE,OAAO;GAAG,OAAO,EAAG,6BAA6B,UAAU;GAAE;EAC/D;GAAE,OAAO;GAAG,OAAO,EAAG,gCAAgC,aAAa;GAAE;EACrE;GAAE,OAAO;GAAG,OAAO,EAAG,8BAA8B,WAAW;GAAE;EACjE;GAAE,OAAO;GAAG,OAAO,EAAG,iCAAiC,cAAc;GAAE;EACxE,EACD,CAAC,EAAG,CACL,EAGK,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAa,KAAkB,EAAsB,UAAU,EAChE,CAAC,GAAU,KAAe,EAAS,EAAE,EACrC,CAAC,GAAQ,KAAa,EAAwB,WAAW,EAGzD,CAAC,GAAU,KAAe,EAAS,GAAM,EACzC,CAAC,GAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,CAAC,GAAe,KAAoB,EAAS,GAAM,EAKnD,IAAqB,EAAsB,KAAK;AACtD,SAAgB;AACd,EAAI,KAAW,EAAQ,OAAO,EAAmB,YAC/C,EAAmB,UAAU,EAAQ,IAChC,QAAQ,SAAS,CAAC,WAAW;AAKhC,GAJA,EAAQ,EAAQ,QAAQ,GAAG,EAC3B,EAAe,EAAQ,eAAe,GAAG,EACzC,EAAgB,EAAQ,eAAe,UAA0B,EACjE,EAAY,EAAQ,YAAY,EAAE,EAClC,EAAW,EAAQ,UAAU,WAA6B;IAC1D;IAEH,CAAC,EAAQ,CAAC;CAGb,IAAM,KAAmB,GAAS,YAAY,SACxC,IAAmB,EAAiB,MAAM,MAAM,EAAE,UAAU,GAAgB;AAqFlF,QA1BI,KAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAS,WAAU,2CAA4C,CAAA;EAC3D,CAAA,GAIN,MAAS,CAAC,IAEV,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAa,WAAU,kCAAmC,CAAA;GAC1D,kBAAC,MAAD;IAAI,WAAU;cACX,EAAG,2BAA2B,oBAAoB;IAChD,CAAA;GACL,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAS,UAAU;IAClC,WAAU;cAET,EAAG,0BAA0B,mBAAmB;IAC1C,CAAA;GACL;MAKR,kBAAC,GAAD;EAAiB,YAAY,EAAoB;YAC/C,kBAAC,OAAD;GAAK,WAAU;aAAf,CAEE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,aAAa,IAAY;OACjD,WAAU;iBAEV,kBAAC,IAAD,EAAW,WAAU,WAAY,CAAA;OAC1B,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAsB,EAAG,uBAAuB,eAAe;OAAM,CAAA,EACnF,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAG,+BAA+B,+BAA+B;OAChE,CAAA,CACA,EAAA,CAAA,CACF;;KACF,CAAA;IACF,CAAA,EAGN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf;MAEE,kBAAC,IAAD;OAAa,MAAM,kBAAC,GAAD;QAAM,MAAM;QAAI,eAAY;QAAS,CAAA;iBACrD,EACC,8BACA,qTACD;OACW,CAAA;MAGb,KACC,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAa,WAAU,0CAA2C,CAAA,EAClE,kBAAC,KAAD;QAAG,WAAU;kBAAkC;QAAc,CAAA,CACzD;;MAIR,kBAAC,IAAD;OAAW,WAAU;OAAU,WAAU;iBAAzC,CACE,kBAAC,OAAD;QAAK,WAAU;kBACZ,KACC,kBAAA,GAAA,EAAA,UAAA,QACU;SACN,IAAM,IAAO,EAAiB;AAC9B,gBAAO,kBAAC,GAAD,EAAM,WAAU,8BAA+B,CAAA;YACpD,EACJ,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAG,EAAiB,UAAU,EAAiB,cAAc;SACzD,CAAA,CACN,EAAA,CAAA;QAED,CAAA,EACN,kBAAC,KAAD;QAAG,WAAU;kBACV,EACC,8BACA,uGACD;QACC,CAAA,CACM;;MAGZ,kBAAC,IAAD;OAAe,WAAU;iBAAzB;QAEE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,SAAD;UAAO,WAAU;oBAAjB,CACG,EAAG,uBAAuB,eAAe,EAAC,KACrC;aACR,kBAAC,SAAD;UACE,cAAY,EACV,+BACA,uCACD;UACD,MAAK;UACL,OAAO;UACP,WAAW,MAAM,EAAQ,EAAE,OAAO,MAAM;UACxC,aAAa,EACX,+BACA,uCACD;UACD,WAAU;UACV,CAAA,CACE;;QAGN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,SAAD;UAAO,SAAQ;UAA2B,WAAU;oBACjD,EAAG,uBAAuB,cAAc;UACnC,CAAA,EACR,kBAAC,IAAD;UACE,IAAG;UACH,OAAO;UACP,UAAU;UACV,cAAY,EACV,sCACA,wCACD;UACD,aAAa,EACX,sCACA,wCACD;UACD,MAAM;UACN,CAAA,CACE;;QAGL,KACC,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,SAAD;UAAO,WAAU;oBACd,EAAG,2BAA2B,qBAAqB;UAC9C,CAAA,EACR,kBAAC,UAAD;UACE,OAAO;UACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAqB;UAC9D,WAAU;oBAET,EAAiB,SAAS,KAAK,MAC9B,kBAAC,UAAD;WAA4B,OAAO,EAAQ;qBACxC,EAAG,EAAQ,UAAU,EAAQ,cAAc;WACrC,EAFI,EAAQ,MAEZ,CACT;UACK,CAAA,CACL;;QAIR,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,SAAD;YAAO,WAAU;sBACd,EAAG,oBAAoB,WAAW;YAC7B,CAAA;WACR,kBAAC,UAAD;YACE,OAAO;YACP,WAAW,MAAM,EAAY,OAAO,EAAE,OAAO,MAAM,CAAC;YACpD,WAAU;sBAET,EAAiB,KAAK,MACrB,kBAAC,UAAD;aAA2B,OAAO,EAAO;uBACtC,EAAO;aACD,EAFI,EAAO,MAEX,CACT;YACK,CAAA;WACT,kBAAC,KAAD;YAAG,WAAU;sBACV,EACC,gCACA,sDACD;YACC,CAAA;WACA;aAEN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,SAAD;WAAO,WAAU;qBAAuB,EAAG,kBAAkB,SAAS;WAAS,CAAA,EAC/E,kBAAC,UAAD;WACE,OAAO;WACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAuB;WAC3D,WAAU;qBAHZ;YAKE,kBAAC,UAAD;aAAQ,OAAM;uBACX,EAAG,gCAAgC,WAAW;aACxC,CAAA;YACT,kBAAC,UAAD;aAAQ,OAAM;uBAAU,EAAG,8BAA8B,SAAS;aAAU,CAAA;YAC5E,kBAAC,UAAD;aAAQ,OAAM;uBACX,EAAG,iCAAiC,YAAY;aAC1C,CAAA;YACF;aACL;YACF;;QACQ;;MAGhB,kBAAC,OAAD;OAAK,WAAU;iBAAf,CAEE,kBAAC,OAAD,EAAA,UACI,IAYA,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAG,yBAAyB,kBAAkB;UAC1C,CAAA;SACP,kBAAC,UAAD;UACE,MAAK;UACL,SApPC,YAAY;AAC3B,kBAAC,KAAa,CAAC,IAGnB;YAFK,EAAa,SAAS,EAE3B,EAAc,GAAK;AACnB,gBAAI;AAEF,aADgB,MAAM,EAAc,EAAU,IAEvC,EAAa,UAAU,EAC5B,EAAS,UAAU,IAEd,EAAa,QAAQ;qBAErB,GAAc;AAKrB,aAJK,EAAa,QAAQ,EAG1B,EADE,aAAe,QAAQ,EAAI,UAAU,EAAG,wBAAwB,2BAA2B,CACxE,EACrB,EAAc,GAAM;;;;UAmOJ,UAAU;UACV,WAAU;oBAJZ,CAMG,IACC,kBAAC,GAAD,EAAS,WAAU,uBAAwB,CAAA,GAE3C,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAE/B,EAAG,kBAAkB,SAAS,CACxB;;SACT,kBAAC,UAAD;UACE,MAAK;UACL,eAAe,EAAiB,GAAM;UACtC,WAAU;oBAET,EAAG,kBAAkB,SAAS;UACxB,CAAA;SACL;YAnCN,kBAAC,GAAD;QAAiB,YAAY,EAAoB;kBAC/C,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAiB,GAAK;SACrC,WAAU;mBAHZ,CAKE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAC7B,EAAG,yBAAyB,iBAAiB,CACvC;;QACO,CAAA,EA4BhB,CAAA,EAGN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAS,aAAa,IAAY;SACjD,WAAU;mBAET,EAAG,kBAAkB,SAAS;SACxB,CAAA,EACT,kBAAC,UAAD;SACE,MAAK;SACL,SAxTG,YAAY;AACxB,iBAEL;eAAI,CAAC,EAAK,MAAM,EAAE;AAChB,cAAa,EAAG,mCAAmC,2BAA2B,CAAC;AAC/E;;AAIF,WADA,EAAY,GAAK,EACjB,EAAa,KAAK;AAElB,eAAI;AAUF,YADe,MAAM,EAAc,GARD;aAChC,MAAM,EAAK,MAAM;aACjB,aAAa,EAAY,MAAM,IAAI,KAAA;aACnC;aACA;aACA;aACD,CAEmD,GAElD,EAAS,aAAa,IAAY,GAElC,EAAa,EAAG,wBAAwB,2BAA2B,CAAC;oBAE/D,GAAc;AAGrB,cADE,aAAe,QAAQ,EAAI,UAAU,EAAG,wBAAwB,2BAA2B,CACxE;qBACb;AACR,cAAY,GAAM;;;;SA0RN,UAAU,KAAY,CAAC,EAAK,MAAM;SAClC,WAAU;mBAJZ,CAMG,IACC,kBAAC,GAAD,EAAS,WAAU,uBAAwB,CAAA,GAE3C,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAE7B,EAAG,uBAAuB,eAAe,CACnC;WACL;UACF;;MACF;;IACF,CAAA,CACF;;EACU,CAAA"}
1
+ {"version":3,"file":"EditChannelPage.js","names":["_Fragment","EditChannelPage","navigate","useNavigate","useParams","useChannel","channelId","useChannels","tr","useTr","PLATFORM_OPTIONS","useMemo","Mail","Smartphone","Bell","Inbox","MessageSquare","Hash","Users","MessageCircle","Send","PRIORITY_OPTIONS","name","setName","useState","description","setDescription","adapterType","setAdapterType","priority","setPriority","status","setStatus","isSaving","setIsSaving","isDeleting","setIsDeleting","saveError","setSaveError","deleteConfirm","setDeleteConfirm","loadedChannelIdRef","useRef","channel","currentPlatform","selectedPlatform","p","isLoading","Loader2","error","AlertCircle","PermissionGuard","CHANNEL_PERMISSIONS","ArrowLeft","PagePurpose","Save","GlassCard","Fragment","Icon","EmphasisPanel","MarkdownEditor","adapter","option","nativeImpact","deleteChannel","nativeNotify","err","message","Trash2","input","updateChannel"],"sources":["../../../../../src/channel/modules/channels/pages/EditChannelPage.tsx"],"sourcesContent":["/**\n * Edit Channel Page\n *\n * Allows editing an existing channel's configuration.\n * Uses the same form structure as CreateChannelPage but pre-fills existing values.\n */\n\nimport { useState, useEffect, useRef, useMemo } from 'react';\nimport { useNavigate, useParams } from 'react-router';\nimport { useTr } from '../../../hooks/useTr';\nimport {\n ArrowLeft,\n Save,\n Loader2,\n AlertCircle,\n Mail,\n Smartphone,\n Bell,\n Inbox,\n MessageSquare,\n Hash,\n Users,\n MessageCircle,\n Send,\n Trash2,\n} from 'lucide-react';\nimport { useChannel, useChannels } from '../../../hooks/useChannels';\nimport {\n type ChannelPlatform,\n type AdapterType,\n type ChannelStatus,\n type UpdateChannelInput,\n} from '../../../hooks/useChannels';\nimport { EmphasisPanel, GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { nativeImpact, nativeNotify } from '../../../../utils/nativeBridge';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\nimport { MarkdownEditor } from '../../../components/MarkdownEditor';\n\ntype PlatformOption = {\n value: ChannelPlatform;\n labelKey: string;\n labelFallback: string;\n descriptionKey: string;\n descriptionFallback: string;\n icon: typeof Mail;\n color: string;\n adapters: { value: AdapterType; labelKey: string; labelFallback: string }[];\n};\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport function EditChannelPage() {\n const navigate = useNavigate();\n const { channelId } = useParams<{ channelId: string }>();\n const { channel, isLoading, error } = useChannel(channelId!);\n const { updateChannel, deleteChannel } = useChannels();\n const tr = useTr();\n\n const PLATFORM_OPTIONS: PlatformOption[] = useMemo(\n () => [\n {\n value: 'EMAIL',\n labelKey: 'channel.platformLabel.email',\n labelFallback: 'Email',\n descriptionKey: 'channel.platformDescription.emailDescription',\n descriptionFallback: 'Send emails via various providers',\n icon: Mail,\n color: 'text-status-info-text bg-status-info-bg-subtle border-status-info-border',\n adapters: [\n { value: 'AWS_SES', labelKey: 'channel.adapter.awsSes', labelFallback: 'AWS SES' },\n { value: 'MAILGUN', labelKey: 'channel.adapter.mailgun', labelFallback: 'Mailgun' },\n { value: 'POSTMARK', labelKey: 'channel.adapter.postmark', labelFallback: 'Postmark' },\n { value: 'MANDRILL', labelKey: 'channel.adapter.mandrill', labelFallback: 'Mandrill' },\n { value: 'RESEND', labelKey: 'channel.adapter.resend', labelFallback: 'Resend' },\n {\n value: 'AZURE_ACS',\n labelKey: 'channel.adapter.azureAcs',\n labelFallback: 'Azure Communication Services',\n },\n { value: 'SMTP', labelKey: 'channel.adapter.smtp', labelFallback: 'Custom SMTP' },\n ],\n },\n {\n value: 'SMS',\n labelKey: 'channel.platformLabel.sms',\n labelFallback: 'SMS',\n descriptionKey: 'channel.platformDescription.smsDescription',\n descriptionFallback: 'Send text messages',\n icon: Smartphone,\n color:\n 'text-status-success-text bg-status-success-bg-subtle border-status-success-border/30',\n adapters: [\n { value: 'TWILIO_SMS', labelKey: 'channel.adapter.twilio', labelFallback: 'Twilio' },\n { value: 'AWS_SNS', labelKey: 'channel.adapter.awsSns', labelFallback: 'AWS SNS' },\n { value: 'VONAGE', labelKey: 'channel.adapter.vonage', labelFallback: 'Vonage' },\n { value: 'PLIVO', labelKey: 'channel.adapter.plivo', labelFallback: 'Plivo' },\n {\n value: 'MESSAGEBIRD',\n labelKey: 'channel.adapter.messagebird',\n labelFallback: 'MessageBird',\n },\n { value: 'INFOBIP', labelKey: 'channel.adapter.infobip', labelFallback: 'Infobip' },\n ],\n },\n {\n value: 'PUSH',\n labelKey: 'channel.platformLabel.push',\n labelFallback: 'Push',\n descriptionKey: 'channel.platformDescription.pushDescription',\n descriptionFallback: 'Mobile & web push',\n icon: Bell,\n color: 'text-accent-purple bg-accent-purple-subtle border-accent-purple/30',\n adapters: [\n {\n value: 'FCM',\n labelKey: 'channel.adapter.fcm',\n labelFallback: 'Firebase Cloud Messaging',\n },\n {\n value: 'APNS',\n labelKey: 'channel.adapter.apns',\n labelFallback: 'Apple Push Notification Service',\n },\n { value: 'ONESIGNAL', labelKey: 'channel.adapter.onesignal', labelFallback: 'OneSignal' },\n { value: 'EXPO', labelKey: 'channel.adapter.expo', labelFallback: 'Expo Push' },\n ],\n },\n {\n value: 'INAPP',\n labelKey: 'channel.platformLabel.inApp',\n labelFallback: 'In-App',\n descriptionKey: 'channel.platformDescription.inAppDescription',\n descriptionFallback: 'Internal in-app notifications',\n icon: Inbox,\n color:\n 'text-status-warning-text bg-status-warning-bg-subtle border-status-warning-border/30',\n adapters: [\n {\n value: 'INAPP_NATIVE',\n labelKey: 'channel.adapter.inAppNative',\n labelFallback: 'Native In-App',\n },\n ],\n },\n {\n value: 'WHATSAPP',\n labelKey: 'channel.platformLabel.whatsapp',\n labelFallback: 'WhatsApp',\n descriptionKey: 'channel.platformDescription.whatsappDescription',\n descriptionFallback: 'WhatsApp Business messaging',\n icon: MessageSquare,\n color:\n 'text-status-success-text bg-status-success-bg-subtle border-status-success-border/30',\n adapters: [\n {\n value: 'WHATSAPP_CLOUD',\n labelKey: 'channel.adapter.whatsappCloud',\n labelFallback: 'WhatsApp Cloud API',\n },\n {\n value: 'WHATSAPP_TWILIO',\n labelKey: 'channel.adapter.whatsappTwilio',\n labelFallback: 'WhatsApp via Twilio',\n },\n ],\n },\n {\n value: 'SLACK',\n labelKey: 'channel.platformLabel.slack',\n labelFallback: 'Slack',\n descriptionKey: 'channel.platformDescription.slackDescription',\n descriptionFallback: 'Slack bot & channels',\n icon: Hash,\n color: 'text-accent-purple bg-accent-purple-subtle border-accent-purple/30',\n adapters: [\n { value: 'SLACK_BOT', labelKey: 'channel.adapter.slackBot', labelFallback: 'Slack Bot' },\n ],\n },\n {\n value: 'TEAMS',\n labelKey: 'channel.platformLabel.teams',\n labelFallback: 'Teams',\n descriptionKey: 'channel.platformDescription.teamsDescription',\n descriptionFallback: 'Microsoft Teams',\n icon: Users,\n color: 'text-status-info-text bg-status-info-bg-subtle border-status-info-border',\n adapters: [\n { value: 'TEAMS_BOT', labelKey: 'channel.adapter.teamsBot', labelFallback: 'Teams Bot' },\n ],\n },\n {\n value: 'DISCORD',\n labelKey: 'channel.platformLabel.discord',\n labelFallback: 'Discord',\n descriptionKey: 'channel.platformDescription.discordDescription',\n descriptionFallback: 'Discord bots & webhooks',\n icon: MessageCircle,\n color: 'text-accent-indigo bg-accent-indigo-subtle border-accent-indigo/30',\n adapters: [\n {\n value: 'DISCORD_BOT',\n labelKey: 'channel.adapter.discordBot',\n labelFallback: 'Discord Bot',\n },\n ],\n },\n {\n value: 'WEBCHAT',\n labelKey: 'channel.platformLabel.webchat',\n labelFallback: 'Webchat',\n descriptionKey: 'channel.platformDescription.webchatDescription',\n descriptionFallback: 'Website live chat',\n icon: MessageSquare,\n color: 'text-accent-teal bg-accent-teal-subtle border-accent-teal/30',\n adapters: [\n {\n value: 'WEBCHAT_NATIVE',\n labelKey: 'channel.adapter.webchatNative',\n labelFallback: 'Native Webchat',\n },\n ],\n },\n {\n value: 'WEBHOOK',\n labelKey: 'channel.platformLabel.webhook',\n labelFallback: 'Webhook',\n descriptionKey: 'channel.platformDescription.webhookDescription',\n descriptionFallback: 'Generic HTTP webhook',\n icon: Send,\n color: 'text-text-secondary bg-bg-sunken/50 border-border-subtle',\n adapters: [\n {\n value: 'WEBHOOK_HTTP',\n labelKey: 'channel.adapter.webhookHttp',\n labelFallback: 'HTTP Webhook',\n },\n ],\n },\n ],\n []\n );\n\n const PRIORITY_OPTIONS = useMemo(\n () => [\n { value: 0, label: tr('channel.priorityLabel.lowest', '0 - Lowest') },\n { value: 1, label: tr('channel.priorityLabel.low', '1 - Low') },\n { value: 2, label: tr('channel.priorityLabel.normal', '2 - Normal') },\n { value: 3, label: tr('channel.priorityLabel.high', '3 - High') },\n { value: 4, label: tr('channel.priorityLabel.highest', '4 - Highest') },\n ],\n [tr]\n );\n\n // Form state\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [adapterType, setAdapterType] = useState<AdapterType>('AWS_SES');\n const [priority, setPriority] = useState(2);\n const [status, setStatus] = useState<ChannelStatus>('INACTIVE');\n\n // UI state\n const [isSaving, setIsSaving] = useState(false);\n const [isDeleting, setIsDeleting] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [deleteConfirm, setDeleteConfirm] = useState(false);\n\n // Load channel data into form — guard against re-initialization and defer\n // the state update to a microtask so setState does not run synchronously\n // inside the effect body (react-hooks/set-state-in-effect).\n const loadedChannelIdRef = useRef<string | null>(null);\n useEffect(() => {\n if (channel && channel.id !== loadedChannelIdRef.current) {\n loadedChannelIdRef.current = channel.id;\n void Promise.resolve().then(() => {\n setName(channel.name || '');\n setDescription(channel.description || '');\n setAdapterType((channel.adapterType || 'AWS_SES') as AdapterType);\n setPriority(channel.priority || 2);\n setStatus((channel.status || 'INACTIVE') as ChannelStatus);\n });\n }\n }, [channel]);\n\n // Update adapter options when platform changes\n const currentPlatform = (channel?.platform || 'EMAIL') as ChannelPlatform;\n const selectedPlatform = PLATFORM_OPTIONS.find((p) => p.value === currentPlatform);\n\n const handleSave = async () => {\n if (!channelId) return;\n\n if (!name.trim()) {\n setSaveError(tr('channel.validation.nameRequired', 'Channel name is required'));\n return;\n }\n\n setIsSaving(true);\n setSaveError(null);\n\n try {\n const input: UpdateChannelInput = {\n name: name.trim(),\n description: description.trim() || undefined,\n adapterType,\n priority,\n status,\n };\n\n const result = await updateChannel(channelId, input);\n if (result) {\n navigate(`/channels/${channelId}`);\n } else {\n setSaveError(tr('channel.updateFailed', 'Failed to update channel'));\n }\n } catch (err: unknown) {\n const message =\n err instanceof Error ? err.message : tr('channel.updateFailed', 'Failed to update channel');\n setSaveError(message);\n } finally {\n setIsSaving(false);\n }\n };\n\n const handleDelete = async () => {\n if (!channelId || !deleteConfirm) return;\n void nativeImpact('medium');\n\n setIsDeleting(true);\n try {\n const success = await deleteChannel(channelId);\n if (success) {\n void nativeNotify('success');\n navigate('../list');\n } else {\n void nativeNotify('error');\n }\n } catch (err: unknown) {\n void nativeNotify('error');\n const message =\n err instanceof Error ? err.message : tr('channel.deleteFailed', 'Failed to delete channel');\n setSaveError(message);\n setIsDeleting(false);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <Loader2 className=\"size-8 animate-spin text-text-secondary\" />\n </div>\n );\n }\n\n if (error || !channel) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-screen gap-4\">\n <AlertCircle className=\"size-12 text-status-error-text\" />\n <h1 className=\"text-xl font-semibold\">\n {tr('channel.channelNotFound', 'Channel not found')}\n </h1>\n <button\n type=\"button\"\n onClick={() => navigate('../list')}\n className=\"text-primary hover:underline\"\n >\n {tr('channel.backToChannels', 'Back to channels')}\n </button>\n </div>\n );\n }\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_UPDATE}>\n <div className=\"min-h-screen bg-bg-surface\">\n {/* Header */}\n <div className=\"border-b bg-bg-surface\">\n <div className=\"container mx-auto px-6 py-4\">\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"p-2 hover:bg-bg-sunken rounded-lg transition-colors\"\n >\n <ArrowLeft className=\"size-5 \" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold\">{tr('channel.editChannel', 'Edit Channel')}</h1>\n <p className=\"text-sm text-text-secondary\">\n {tr('channel.updateChannelConfig', 'Update channel configuration')}\n </p>\n </div>\n </div>\n </div>\n </div>\n\n {/* Form */}\n <div className=\"container mx-auto px-6 py-8 max-w-2xl\">\n <div className=\"space-y-6\">\n {/* Page purpose */}\n <PagePurpose icon={<Save size={15} aria-hidden=\"true\" />}>\n {tr(\n 'channel.editChannelPurpose',\n \"Change how this channel behaves — its name, description, priority and status. The platform and provider stay fixed (they define what the channel is); to swap credentials use the channel's connection instead. Use this to rename a channel, bump its priority, or temporarily deactivate it without deleting it.\"\n )}\n </PagePurpose>\n\n {/* Error Alert */}\n {saveError && (\n <div className=\"p-4 rounded-lg bg-status-error-bg/10 border border-status-error-border/20 flex items-center gap-3\">\n <AlertCircle className=\"size-5 text-status-error-text shrink-0\" />\n <p className=\"text-sm text-status-error-text\">{saveError}</p>\n </div>\n )}\n\n {/* Channel Info (read-only) */}\n <GlassCard treatment=\"insight\" className=\"p-4 border-border-seam space-y-2\">\n <div className=\"flex items-center gap-2\">\n {selectedPlatform && (\n <>\n {(() => {\n const Icon = selectedPlatform.icon;\n return <Icon className=\"size-5 text-text-secondary\" />;\n })()}\n <span className=\"font-medium\">\n {tr(selectedPlatform.labelKey, selectedPlatform.labelFallback)}\n </span>\n </>\n )}\n </div>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'channel.platformLockedHint',\n 'Platform cannot be changed after channel creation. Create a new channel to use a different platform.'\n )}\n </p>\n </GlassCard>\n\n {/* Channel fields — the editable core of this page */}\n <EmphasisPanel className=\"p-5 space-y-6\">\n {/* Name */}\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">\n {tr('channel.channelName', 'Channel Name')} *\n </label>\n <input\n aria-label={tr(\n 'channel.editNamePlaceholder',\n 'e.g., Production Email, Customer SMS'\n )}\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={tr(\n 'channel.editNamePlaceholder',\n 'e.g., Production Email, Customer SMS'\n )}\n className=\"w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n </div>\n\n {/* Description */}\n <div className=\"space-y-2\">\n <label htmlFor=\"channel-edit-description\" className=\"text-sm font-medium\">\n {tr('channel.description', 'Description')}\n </label>\n <MarkdownEditor\n id=\"channel-edit-description\"\n value={description}\n onChange={setDescription}\n aria-label={tr(\n 'channel.editDescriptionPlaceholder',\n 'Optional description for this channel'\n )}\n placeholder={tr(\n 'channel.editDescriptionPlaceholder',\n 'Optional description for this channel'\n )}\n rows={3}\n />\n </div>\n\n {/* Adapter Type */}\n {selectedPlatform && (\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">\n {tr('channel.adapterProvider', 'Adapter / Provider')}\n </label>\n <select\n value={adapterType}\n onChange={(e) => setAdapterType(e.target.value as AdapterType)}\n className=\"w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n {selectedPlatform.adapters.map((adapter) => (\n <option key={adapter.value} value={adapter.value}>\n {tr(adapter.labelKey, adapter.labelFallback)}\n </option>\n ))}\n </select>\n </div>\n )}\n\n {/* Priority & Status */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">\n {tr('channel.priority', 'Priority')}\n </label>\n <select\n value={priority}\n onChange={(e) => setPriority(Number(e.target.value))}\n className=\"w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n {PRIORITY_OPTIONS.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'channel.priorityFailoverHint',\n 'Higher priority channels are used first in failover'\n )}\n </p>\n </div>\n\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{tr('channel.status', 'Status')}</label>\n <select\n value={status}\n onChange={(e) => setStatus(e.target.value as ChannelStatus)}\n className=\"w-full px-4 py-2 rounded-lg border bg-bg-surface focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"INACTIVE\">\n {tr('channel.statusLabel.inactive', 'Inactive')}\n </option>\n <option value=\"ACTIVE\">{tr('channel.statusLabel.active', 'Active')}</option>\n <option value=\"SUSPENDED\">\n {tr('channel.statusLabel.suspended', 'Suspended')}\n </option>\n </select>\n </div>\n </div>\n </EmphasisPanel>\n\n {/* Actions */}\n <div className=\"flex items-center justify-between pt-6 border-t\">\n {/* Delete */}\n <div>\n {!deleteConfirm ? (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_DELETE}>\n <button\n type=\"button\"\n onClick={() => setDeleteConfirm(true)}\n className=\"px-4 py-2 text-sm text-status-error-text hover:bg-status-error-bg/10 rounded-lg transition-colors flex items-center gap-2\"\n >\n <Trash2 className=\"size-4 \" />\n {tr('channel.deleteChannel', 'Delete Channel')}\n </button>\n </PermissionGuard>\n ) : (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-text-secondary\">\n {tr('channel.confirmDelete', 'Confirm delete?')}\n </span>\n <button\n type=\"button\"\n onClick={handleDelete}\n disabled={isDeleting}\n className=\"px-4 py-2 text-sm bg-status-error-bg text-status-error-text rounded-lg hover:bg-status-error-bg/90 transition-colors flex items-center gap-2\"\n >\n {isDeleting ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Trash2 className=\"size-4 \" />\n )}\n {tr('channel.delete', 'Delete')}\n </button>\n <button\n type=\"button\"\n onClick={() => setDeleteConfirm(false)}\n className=\"px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors\"\n >\n {tr('channel.cancel', 'Cancel')}\n </button>\n </div>\n )}\n </div>\n\n {/* Save */}\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-lg transition-colors\"\n >\n {tr('channel.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={isSaving || !name.trim()}\n className=\"px-6 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors flex items-center gap-2 disabled:opacity-50\"\n >\n {isSaving ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Save className=\"size-4 \" />\n )}\n {tr('channel.saveChanges', 'Save Changes')}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAsDA,SAAgBC,IAAkB;CAChC,IAAMC,IAAWC,EAAY,GACvB,EAAE,iBAAcC,EAAiC,GACjD,EAAE,YAAS,eAAW,cAAUC,EAAWC,CAAU,GACrD,EAAE,kBAAe,qBAAkBC,EAAY,GAC/CC,IAAKC,EAAM,GAEXC,IAAqCC,QACnC;EACJ;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMC;GACN,OAAO;GACP,UAAU;IACR;KAAE,OAAO;KAAW,UAAU;KAA0B,eAAe;IAAU;IACjF;KAAE,OAAO;KAAW,UAAU;KAA2B,eAAe;IAAU;IAClF;KAAE,OAAO;KAAY,UAAU;KAA4B,eAAe;IAAW;IACrF;KAAE,OAAO;KAAY,UAAU;KAA4B,eAAe;IAAW;IACrF;KAAE,OAAO;KAAU,UAAU;KAA0B,eAAe;IAAS;IAC/E;KACE,OAAO;KACP,UAAU;KACV,eAAe;IACjB;IACA;KAAE,OAAO;KAAQ,UAAU;KAAwB,eAAe;IAAc;GAClF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMC;GACN,OACE;GACF,UAAU;IACR;KAAE,OAAO;KAAc,UAAU;KAA0B,eAAe;IAAS;IACnF;KAAE,OAAO;KAAW,UAAU;KAA0B,eAAe;IAAU;IACjF;KAAE,OAAO;KAAU,UAAU;KAA0B,eAAe;IAAS;IAC/E;KAAE,OAAO;KAAS,UAAU;KAAyB,eAAe;IAAQ;IAC5E;KACE,OAAO;KACP,UAAU;KACV,eAAe;IACjB;IACA;KAAE,OAAO;KAAW,UAAU;KAA2B,eAAe;IAAU;GACpF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMC;GACN,OAAO;GACP,UAAU;IACR;KACE,OAAO;KACP,UAAU;KACV,eAAe;IACjB;IACA;KACE,OAAO;KACP,UAAU;KACV,eAAe;IACjB;IACA;KAAE,OAAO;KAAa,UAAU;KAA6B,eAAe;IAAY;IACxF;KAAE,OAAO;KAAQ,UAAU;KAAwB,eAAe;IAAY;GAChF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMC;GACN,OACE;GACF,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;GACjB,CACF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMC;GACN,OACE;GACF,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;GACjB,GACA;IACE,OAAO;IACP,UAAU;IACV,eAAe;GACjB,CACF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMC;GACN,OAAO;GACP,UAAU,CACR;IAAE,OAAO;IAAa,UAAU;IAA4B,eAAe;GAAY,CACzF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMC;GACN,OAAO;GACP,UAAU,CACR;IAAE,OAAO;IAAa,UAAU;IAA4B,eAAe;GAAY,CACzF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMC;GACN,OAAO;GACP,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;GACjB,CACF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMH;GACN,OAAO;GACP,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;GACjB,CACF;EACF;EACA;GACE,OAAO;GACP,UAAU;GACV,eAAe;GACf,gBAAgB;GAChB,qBAAqB;GACrB,MAAMI;GACN,OAAO;GACP,UAAU,CACR;IACE,OAAO;IACP,UAAU;IACV,eAAe;GACjB,CACF;EACF;CACF,GACA,CAAC,CACH,GAEMC,IAAmBV,QACjB;EACJ;GAAE,OAAO;GAAG,OAAOH,EAAG,gCAAgC,YAAY;EAAE;EACpE;GAAE,OAAO;GAAG,OAAOA,EAAG,6BAA6B,SAAS;EAAE;EAC9D;GAAE,OAAO;GAAG,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"}