@burdenoff/microfe-conversations 2026.510.117

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 (155) hide show
  1. package/README.md +12 -0
  2. package/dist/__tests__/setup.d.ts +2 -0
  3. package/dist/__tests__/setup.d.ts.map +1 -0
  4. package/dist/conversations/ConversationsAdminRoot.d.ts +19 -0
  5. package/dist/conversations/ConversationsAdminRoot.d.ts.map +1 -0
  6. package/dist/conversations/ConversationsAdminRoot.js +104 -0
  7. package/dist/conversations/ConversationsAdminRoot.js.map +1 -0
  8. package/dist/conversations/ConversationsAdminRoutes.d.ts +18 -0
  9. package/dist/conversations/ConversationsAdminRoutes.d.ts.map +1 -0
  10. package/dist/conversations/ConversationsAdminRoutes.js +42 -0
  11. package/dist/conversations/ConversationsAdminRoutes.js.map +1 -0
  12. package/dist/conversations/ConversationsRoot.d.ts +33 -0
  13. package/dist/conversations/ConversationsRoot.d.ts.map +1 -0
  14. package/dist/conversations/ConversationsRoot.js +100 -0
  15. package/dist/conversations/ConversationsRoot.js.map +1 -0
  16. package/dist/conversations/ConversationsUserRoot.d.ts +17 -0
  17. package/dist/conversations/ConversationsUserRoot.d.ts.map +1 -0
  18. package/dist/conversations/ConversationsUserRoot.js +101 -0
  19. package/dist/conversations/ConversationsUserRoot.js.map +1 -0
  20. package/dist/conversations/ConversationsUserRoutes.d.ts +12 -0
  21. package/dist/conversations/ConversationsUserRoutes.d.ts.map +1 -0
  22. package/dist/conversations/ConversationsUserRoutes.js +45 -0
  23. package/dist/conversations/ConversationsUserRoutes.js.map +1 -0
  24. package/dist/conversations/components/ConversationCard.d.ts +14 -0
  25. package/dist/conversations/components/ConversationCard.d.ts.map +1 -0
  26. package/dist/conversations/components/ConversationCard.js +118 -0
  27. package/dist/conversations/components/ConversationCard.js.map +1 -0
  28. package/dist/conversations/components/LazyPageBoundary.d.ts +25 -0
  29. package/dist/conversations/components/LazyPageBoundary.d.ts.map +1 -0
  30. package/dist/conversations/components/LazyPageBoundary.js +144 -0
  31. package/dist/conversations/components/LazyPageBoundary.js.map +1 -0
  32. package/dist/conversations/components/MessageBubble.d.ts +21 -0
  33. package/dist/conversations/components/MessageBubble.d.ts.map +1 -0
  34. package/dist/conversations/components/MessageBubble.js +242 -0
  35. package/dist/conversations/components/MessageBubble.js.map +1 -0
  36. package/dist/conversations/components/PageLayout.d.ts +55 -0
  37. package/dist/conversations/components/PageLayout.d.ts.map +1 -0
  38. package/dist/conversations/components/PageLayout.js +93 -0
  39. package/dist/conversations/components/PageLayout.js.map +1 -0
  40. package/dist/conversations/components/PermissionGuard.d.ts +21 -0
  41. package/dist/conversations/components/PermissionGuard.d.ts.map +1 -0
  42. package/dist/conversations/components/PermissionGuard.js +25 -0
  43. package/dist/conversations/components/PermissionGuard.js.map +1 -0
  44. package/dist/conversations/constants/featureFlags.d.ts +8 -0
  45. package/dist/conversations/constants/featureFlags.d.ts.map +1 -0
  46. package/dist/conversations/constants/featureFlags.js +12 -0
  47. package/dist/conversations/constants/featureFlags.js.map +1 -0
  48. package/dist/conversations/constants/permissions.d.ts +174 -0
  49. package/dist/conversations/constants/permissions.d.ts.map +1 -0
  50. package/dist/conversations/constants/permissions.js +68 -0
  51. package/dist/conversations/constants/permissions.js.map +1 -0
  52. package/dist/conversations/hooks/useAdminFeatureFlags.d.ts +8 -0
  53. package/dist/conversations/hooks/useAdminFeatureFlags.d.ts.map +1 -0
  54. package/dist/conversations/hooks/useAdminFeatureFlags.js +16 -0
  55. package/dist/conversations/hooks/useAdminFeatureFlags.js.map +1 -0
  56. package/dist/conversations/hooks/useConversationQueries.d.ts +83 -0
  57. package/dist/conversations/hooks/useConversationQueries.d.ts.map +1 -0
  58. package/dist/conversations/hooks/useConversationQueries.js +136 -0
  59. package/dist/conversations/hooks/useConversationQueries.js.map +1 -0
  60. package/dist/conversations/hooks/useExportConversation.d.ts +10 -0
  61. package/dist/conversations/hooks/useExportConversation.d.ts.map +1 -0
  62. package/dist/conversations/hooks/useExportConversation.js +41 -0
  63. package/dist/conversations/hooks/useExportConversation.js.map +1 -0
  64. package/dist/conversations/hooks/useMessageQueries.d.ts +84 -0
  65. package/dist/conversations/hooks/useMessageQueries.d.ts.map +1 -0
  66. package/dist/conversations/hooks/useMessageQueries.js +123 -0
  67. package/dist/conversations/hooks/useMessageQueries.js.map +1 -0
  68. package/dist/conversations/hooks/useMessageSubscriptions.d.ts +24 -0
  69. package/dist/conversations/hooks/useMessageSubscriptions.d.ts.map +1 -0
  70. package/dist/conversations/hooks/useMessageSubscriptions.js +90 -0
  71. package/dist/conversations/hooks/useMessageSubscriptions.js.map +1 -0
  72. package/dist/conversations/hooks/useUserFeatureFlags.d.ts +5 -0
  73. package/dist/conversations/hooks/useUserFeatureFlags.d.ts.map +1 -0
  74. package/dist/conversations/hooks/useUserFeatureFlags.js +10 -0
  75. package/dist/conversations/hooks/useUserFeatureFlags.js.map +1 -0
  76. package/dist/conversations/index.d.ts +31 -0
  77. package/dist/conversations/index.d.ts.map +1 -0
  78. package/dist/conversations/index.js +5 -0
  79. package/dist/conversations/pages/AdminConversationsLandingPage.d.ts +9 -0
  80. package/dist/conversations/pages/AdminConversationsLandingPage.d.ts.map +1 -0
  81. package/dist/conversations/pages/AdminConversationsLandingPage.js +117 -0
  82. package/dist/conversations/pages/AdminConversationsLandingPage.js.map +1 -0
  83. package/dist/conversations/pages/ConversationAdminPages.d.ts +5 -0
  84. package/dist/conversations/pages/ConversationAdminPages.d.ts.map +1 -0
  85. package/dist/conversations/pages/ConversationAdminPages.js +573 -0
  86. package/dist/conversations/pages/ConversationAdminPages.js.map +1 -0
  87. package/dist/conversations/pages/ConversationDetailPage.d.ts +2 -0
  88. package/dist/conversations/pages/ConversationDetailPage.d.ts.map +1 -0
  89. package/dist/conversations/pages/ConversationDetailPage.js +439 -0
  90. package/dist/conversations/pages/ConversationDetailPage.js.map +1 -0
  91. package/dist/conversations/pages/ConversationListPage.d.ts +6 -0
  92. package/dist/conversations/pages/ConversationListPage.d.ts.map +1 -0
  93. package/dist/conversations/pages/ConversationListPage.js +269 -0
  94. package/dist/conversations/pages/ConversationListPage.js.map +1 -0
  95. package/dist/conversations/pages/ConversationsLandingPage.d.ts +9 -0
  96. package/dist/conversations/pages/ConversationsLandingPage.d.ts.map +1 -0
  97. package/dist/conversations/pages/ConversationsLandingPage.js +124 -0
  98. package/dist/conversations/pages/ConversationsLandingPage.js.map +1 -0
  99. package/dist/conversations/pages/ConversationsSettingsPage.d.ts +2 -0
  100. package/dist/conversations/pages/ConversationsSettingsPage.d.ts.map +1 -0
  101. package/dist/conversations/pages/ConversationsSettingsPage.js +215 -0
  102. package/dist/conversations/pages/ConversationsSettingsPage.js.map +1 -0
  103. package/dist/conversations/pages/NewConversationPage.d.ts +2 -0
  104. package/dist/conversations/pages/NewConversationPage.d.ts.map +1 -0
  105. package/dist/conversations/pages/NewConversationPage.js +287 -0
  106. package/dist/conversations/pages/NewConversationPage.js.map +1 -0
  107. package/dist/conversations/providers/ConversationsProvider.d.ts +13 -0
  108. package/dist/conversations/providers/ConversationsProvider.d.ts.map +1 -0
  109. package/dist/conversations/providers/ConversationsProvider.js +109 -0
  110. package/dist/conversations/providers/ConversationsProvider.js.map +1 -0
  111. package/dist/conversations/store/conversationsStore.d.ts +29 -0
  112. package/dist/conversations/store/conversationsStore.d.ts.map +1 -0
  113. package/dist/conversations/store/conversationsStore.js +56 -0
  114. package/dist/conversations/store/conversationsStore.js.map +1 -0
  115. package/dist/conversations/types/index.d.ts +352 -0
  116. package/dist/conversations/types/index.d.ts.map +1 -0
  117. package/dist/conversations/utils/cn.d.ts +8 -0
  118. package/dist/conversations/utils/cn.d.ts.map +1 -0
  119. package/dist/conversations/utils/cn.js +10 -0
  120. package/dist/conversations/utils/cn.js.map +1 -0
  121. package/dist/conversations/utils/i18n.d.ts +15 -0
  122. package/dist/conversations/utils/i18n.d.ts.map +1 -0
  123. package/dist/conversations/utils/i18n.js +14 -0
  124. package/dist/conversations/utils/i18n.js.map +1 -0
  125. package/dist/conversations/utils/mappers.d.ts +32 -0
  126. package/dist/conversations/utils/mappers.d.ts.map +1 -0
  127. package/dist/conversations/utils/mappers.js +164 -0
  128. package/dist/conversations/utils/mappers.js.map +1 -0
  129. package/dist/conversations/utils/navigation.d.ts +18 -0
  130. package/dist/conversations/utils/navigation.d.ts.map +1 -0
  131. package/dist/conversations/utils/navigation.js +8 -0
  132. package/dist/conversations/utils/navigation.js.map +1 -0
  133. package/dist/dev/main.d.ts +2 -0
  134. package/dist/dev/main.d.ts.map +1 -0
  135. package/dist/generated/global-operations.d.ts +2 -0
  136. package/dist/generated/global-operations.d.ts.map +1 -0
  137. package/dist/generated/global-types.d.ts +20716 -0
  138. package/dist/generated/global-types.d.ts.map +1 -0
  139. package/dist/generated/wspace-operations.d.ts +2008 -0
  140. package/dist/generated/wspace-operations.d.ts.map +1 -0
  141. package/dist/generated/wspace-operations.js +997 -0
  142. package/dist/generated/wspace-operations.js.map +1 -0
  143. package/dist/generated/wspace-types.d.ts +53363 -0
  144. package/dist/generated/wspace-types.d.ts.map +1 -0
  145. package/dist/index.d.ts +6 -0
  146. package/dist/index.d.ts.map +1 -0
  147. package/dist/index.js +7 -0
  148. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  149. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  150. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1674 -0
  151. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  152. package/dist/utils/nativeBridge.d.ts +3 -0
  153. package/dist/utils/nativeBridge.d.ts.map +1 -0
  154. package/dist/utils/nativeBridge.js +2 -0
  155. package/package.json +115 -0
@@ -0,0 +1,215 @@
1
+ import { useConversations as e } from "../providers/ConversationsProvider.js";
2
+ import { PageLayout as t, PageSection as n } from "../components/PageLayout.js";
3
+ import { useGetConversation as r, useUpdateConversation as i } from "../hooks/useConversationQueries.js";
4
+ import { useConversationsStore as a } from "../store/conversationsStore.js";
5
+ import { PermissionGuard as o } from "../components/PermissionGuard.js";
6
+ import { CONVERSATIONS_PERMISSIONS as s } from "../constants/permissions.js";
7
+ import { nativeImpact as c, nativeNotify as l } from "../../utils/nativeBridge.js";
8
+ import { useExportConversation as u } from "../hooks/useExportConversation.js";
9
+ import { useEffect as d, useRef as f, useState as p } from "react";
10
+ import { ArrowLeft as m, Bell as h, Download as g, Eye as _, Save as v, Settings as y } from "lucide-react";
11
+ import { useNavigate as b } from "react-router-dom";
12
+ import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
13
+ import { useI18n as w } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
+ //#region src/conversations/pages/ConversationsSettingsPage.tsx
15
+ function T() {
16
+ let T = b(), { basePath: D } = e(), { activeConversationId: O } = a(), { t: k } = w(), A = (e, t) => {
17
+ let n = k(e);
18
+ return n === e ? t : n;
19
+ }, { conversation: j, loading: M } = r(O ?? ""), { updateConversation: N, loading: P, error: F } = i(), [I, L] = p(!0), [R, z] = p(!0), [B, V] = p("ALL"), [H, U] = p(!1), W = f(null), { exportComments: G, loading: K, downloadUrl: q } = u();
20
+ d(() => {
21
+ let e = j?.settings && typeof j.settings == "object" ? j.settings : null;
22
+ e && (typeof e.showTypingIndicators == "boolean" && L(e.showTypingIndicators), typeof e.showReadReceipts == "boolean" && z(e.showReadReceipts), typeof e.defaultNotificationLevel == "string" && V(e.defaultNotificationLevel));
23
+ }, [j]);
24
+ let J = async () => {
25
+ if (j?.id) {
26
+ c("light");
27
+ try {
28
+ let e = !!await N({
29
+ id: j.id,
30
+ settings: {
31
+ showTypingIndicators: I,
32
+ showReadReceipts: R,
33
+ defaultNotificationLevel: B
34
+ }
35
+ });
36
+ l(e ? "success" : "error"), U(e);
37
+ } catch (e) {
38
+ throw l("error"), e;
39
+ }
40
+ }
41
+ };
42
+ return /* @__PURE__ */ S(t, {
43
+ title: A("conversations.settings", "Settings"),
44
+ subtitle: j ? `${A("conversations.settingsFor", "Conversation settings for")} ${j.title}` : A("conversations.selectConversationForSettings", "Select a conversation to edit settings"),
45
+ icon: /* @__PURE__ */ S(y, { size: 24 }),
46
+ maxWidth: "lg",
47
+ headerActions: /* @__PURE__ */ C("div", {
48
+ className: "flex items-center gap-2",
49
+ children: [/* @__PURE__ */ C("button", {
50
+ type: "button",
51
+ onClick: () => T(D || "/conversations"),
52
+ className: "inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
53
+ children: [/* @__PURE__ */ S(m, { size: 16 }), A("conversations.back", "Back")]
54
+ }), /* @__PURE__ */ C("button", {
55
+ type: "button",
56
+ onClick: () => void J(),
57
+ disabled: P || !j,
58
+ className: "inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors shadow-sm disabled:opacity-50",
59
+ children: [/* @__PURE__ */ S(v, { size: 16 }), P ? A("conversations.saving", "Saving...") : A("conversations.saveChanges", "Save Changes")]
60
+ })]
61
+ }),
62
+ children: M ? /* @__PURE__ */ S("div", {
63
+ className: "text-sm text-muted-foreground",
64
+ children: A("conversations.loadingSettings", "Loading settings...")
65
+ }) : j ? /* @__PURE__ */ C(x, { children: [
66
+ /* @__PURE__ */ S(n, {
67
+ title: A("conversations.notifications", "Notifications"),
68
+ description: A("conversations.notificationsDescription", "Configure delivery behavior for this conversation"),
69
+ children: /* @__PURE__ */ S("div", {
70
+ className: "space-y-4 rounded-xl border border-border p-4",
71
+ children: /* @__PURE__ */ C("div", {
72
+ className: "flex items-start justify-between gap-4",
73
+ children: [/* @__PURE__ */ C("div", {
74
+ className: "flex items-start gap-3",
75
+ children: [/* @__PURE__ */ S("div", {
76
+ className: "p-2 rounded-lg bg-status-info-bg-subtle text-status-info-text",
77
+ children: /* @__PURE__ */ S(h, { size: 16 })
78
+ }), /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("p", {
79
+ className: "text-sm font-medium text-foreground",
80
+ children: A("conversations.defaultNotificationLevel", "Default Notification Level")
81
+ }), /* @__PURE__ */ S("p", {
82
+ className: "text-xs text-muted-foreground mt-0.5",
83
+ children: A("conversations.defaultNotificationLevelHint", "This updates conversation settings JSON via GraphQL.")
84
+ })] })]
85
+ }), /* @__PURE__ */ C("select", {
86
+ value: B,
87
+ onChange: (e) => V(e.target.value),
88
+ className: "px-3 py-1.5 text-sm rounded-lg border border-border bg-background focus:outline-none focus:ring-2 focus:ring-ring",
89
+ children: [
90
+ /* @__PURE__ */ S("option", {
91
+ value: "ALL",
92
+ children: A("conversations.allMessages", "All Messages")
93
+ }),
94
+ /* @__PURE__ */ S("option", {
95
+ value: "MENTIONS",
96
+ children: A("conversations.mentionsOnly", "Mentions Only")
97
+ }),
98
+ /* @__PURE__ */ S("option", {
99
+ value: "DIRECT",
100
+ children: A("conversations.directOnly", "Direct Only")
101
+ }),
102
+ /* @__PURE__ */ S("option", {
103
+ value: "NONE",
104
+ children: A("conversations.none", "None")
105
+ })
106
+ ]
107
+ })]
108
+ })
109
+ })
110
+ }),
111
+ /* @__PURE__ */ S(n, {
112
+ title: A("conversations.messageBehavior", "Message Behavior"),
113
+ description: A("conversations.messageBehaviorDescription", "Tune read and typing experience"),
114
+ children: /* @__PURE__ */ C("div", {
115
+ className: "space-y-4 rounded-xl border border-border p-4",
116
+ children: [/* @__PURE__ */ S(E, {
117
+ icon: /* @__PURE__ */ S(_, { size: 16 }),
118
+ label: A("conversations.typingIndicators", "Typing Indicators"),
119
+ description: A("conversations.typingIndicatorsDescription", "Show others when someone is typing"),
120
+ checked: I,
121
+ onChange: L
122
+ }), /* @__PURE__ */ S(E, {
123
+ icon: /* @__PURE__ */ S(_, { size: 16 }),
124
+ label: A("conversations.readReceipts", "Read Receipts"),
125
+ description: A("conversations.readReceiptsDescription", "Display read status for conversation participants"),
126
+ checked: R,
127
+ onChange: z
128
+ })]
129
+ })
130
+ }),
131
+ /* @__PURE__ */ S(n, {
132
+ title: A("conversations.exportData", "Export Data"),
133
+ description: A("conversations.exportDataDescription", "Download conversation comments in your preferred format"),
134
+ children: /* @__PURE__ */ C("div", {
135
+ className: "space-y-3 rounded-xl border border-border p-4",
136
+ children: [
137
+ /* @__PURE__ */ S("div", {
138
+ className: "flex flex-wrap gap-2",
139
+ children: [
140
+ "JSON",
141
+ "CSV",
142
+ "MARKDOWN"
143
+ ].map((e) => /* @__PURE__ */ S(o, {
144
+ permission: s.CONVERSATION_READ,
145
+ children: /* @__PURE__ */ C("button", {
146
+ type: "button",
147
+ disabled: K || !j,
148
+ onClick: async () => {
149
+ let t = await G("conversation", j.id, e);
150
+ t && W.current && (W.current.href = t, W.current.download = `conversation-${j.id}.${e.toLowerCase()}`, W.current.click());
151
+ },
152
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg border border-border text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors disabled:opacity-50",
153
+ children: [/* @__PURE__ */ S(g, { size: 12 }), K ? A("conversations.exporting", "Exporting…") : e]
154
+ })
155
+ }, e))
156
+ }),
157
+ q && /* @__PURE__ */ S("p", {
158
+ className: "text-xs text-status-success-text",
159
+ children: A("conversations.exportReady", "Export ready — downloading…")
160
+ }),
161
+ /* @__PURE__ */ S("a", {
162
+ ref: W,
163
+ className: "hidden",
164
+ "aria-hidden": "true"
165
+ })
166
+ ]
167
+ })
168
+ }),
169
+ F && /* @__PURE__ */ S("div", {
170
+ className: "text-xs text-destructive rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2",
171
+ children: F.message
172
+ }),
173
+ H && !F && /* @__PURE__ */ S("div", {
174
+ className: "text-xs text-status-success-text rounded-lg border border-border-default bg-status-success-bg-subtle px-3 py-2",
175
+ children: A("conversations.settingsSaved", "Settings saved.")
176
+ })
177
+ ] }) : /* @__PURE__ */ S("div", {
178
+ className: "text-sm text-muted-foreground",
179
+ children: A("conversations.openConversationFirst", "Open a conversation first, then come back to settings.")
180
+ })
181
+ });
182
+ }
183
+ function E({ icon: e, label: t, description: n, checked: r, onChange: i }) {
184
+ return /* @__PURE__ */ S(o, {
185
+ permission: s.CONVERSATION_UPDATE,
186
+ children: /* @__PURE__ */ C("div", {
187
+ className: "flex items-start justify-between gap-4",
188
+ children: [/* @__PURE__ */ C("div", {
189
+ className: "flex items-start gap-3",
190
+ children: [/* @__PURE__ */ S("div", {
191
+ className: "p-2 rounded-lg bg-muted text-muted-foreground",
192
+ children: e
193
+ }), /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("p", {
194
+ className: "text-sm font-medium text-foreground",
195
+ children: t
196
+ }), /* @__PURE__ */ S("p", {
197
+ className: "text-xs text-muted-foreground mt-0.5",
198
+ children: n
199
+ })] })]
200
+ }), /* @__PURE__ */ S("button", {
201
+ type: "button",
202
+ role: "switch",
203
+ "aria-checked": r,
204
+ "aria-label": t,
205
+ onClick: () => i(!r),
206
+ className: `relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors ${r ? "bg-primary" : "bg-muted"}`,
207
+ children: /* @__PURE__ */ S("span", { className: `pointer-events-none inline-block h-5 w-5 rounded-full bg-background shadow transition ${r ? "translate-x-5" : "translate-x-0"}` })
208
+ })]
209
+ })
210
+ });
211
+ }
212
+ //#endregion
213
+ export { T as ConversationsSettingsPage };
214
+
215
+ //# sourceMappingURL=ConversationsSettingsPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConversationsSettingsPage.js","names":[],"sources":["../../../src/conversations/pages/ConversationsSettingsPage.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { useNavigate } from \"react-router-dom\";\nimport { ArrowLeft, Bell, Download, Eye, Save, Settings } from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport {\n useGetConversation,\n useUpdateConversation,\n} from \"../hooks/useConversationQueries\";\nimport { useExportConversation } from \"../hooks/useExportConversation\";\nimport { useConversations } from \"../providers/ConversationsProvider\";\nimport { useConversationsStore } from \"../store/conversationsStore\";\nimport { PermissionGuard } from \"../components/PermissionGuard\";\nimport { CONVERSATIONS_PERMISSIONS } from \"../constants/permissions\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\nexport function ConversationsSettingsPage() {\n const navigate = useNavigate();\n const { basePath } = useConversations();\n const { activeConversationId } = useConversationsStore();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { conversation, loading: conversationLoading } = useGetConversation(\n activeConversationId ?? \"\",\n );\n const {\n updateConversation,\n loading: saving,\n error: saveError,\n } = useUpdateConversation();\n\n const [showTypingIndicators, setShowTypingIndicators] = useState(true);\n const [showReadReceipts, setShowReadReceipts] = useState(true);\n const [defaultNotificationLevel, setDefaultNotificationLevel] =\n useState(\"ALL\");\n const [saved, setSaved] = useState(false);\n const downloadLinkRef = useRef<HTMLAnchorElement>(null);\n const {\n exportComments,\n loading: exporting,\n downloadUrl,\n } = useExportConversation();\n\n useEffect(() => {\n const settings =\n conversation?.settings && typeof conversation.settings === \"object\"\n ? (conversation.settings as Record<string, unknown>)\n : null;\n if (!settings) return;\n if (typeof settings.showTypingIndicators === \"boolean\") {\n setShowTypingIndicators(settings.showTypingIndicators);\n }\n if (typeof settings.showReadReceipts === \"boolean\") {\n setShowReadReceipts(settings.showReadReceipts);\n }\n if (typeof settings.defaultNotificationLevel === \"string\") {\n setDefaultNotificationLevel(settings.defaultNotificationLevel);\n }\n }, [conversation]);\n\n const handleSave = async () => {\n if (!conversation?.id) return;\n nativeImpact(\"light\");\n try {\n const updated = await updateConversation({\n id: conversation.id,\n settings: {\n showTypingIndicators,\n showReadReceipts,\n defaultNotificationLevel,\n },\n });\n const ok = Boolean(updated);\n nativeNotify(ok ? \"success\" : \"error\");\n setSaved(ok);\n } catch (error) {\n nativeNotify(\"error\");\n throw error;\n }\n };\n\n return (\n <PageLayout\n title={tr(\"conversations.settings\", \"Settings\")}\n subtitle={\n conversation\n ? `${tr(\"conversations.settingsFor\", \"Conversation settings for\")} ${conversation.title}`\n : tr(\n \"conversations.selectConversationForSettings\",\n \"Select a conversation to edit settings\",\n )\n }\n icon={<Settings size={24} />}\n maxWidth=\"lg\"\n headerActions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigate(basePath || \"/conversations\")}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors\"\n >\n <ArrowLeft size={16} />\n {tr(\"conversations.back\", \"Back\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleSave()}\n disabled={saving || !conversation}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors shadow-sm disabled:opacity-50\"\n >\n <Save size={16} />\n {saving\n ? tr(\"conversations.saving\", \"Saving...\")\n : tr(\"conversations.saveChanges\", \"Save Changes\")}\n </button>\n </div>\n }\n >\n {conversationLoading ? (\n <div className=\"text-sm text-muted-foreground\">\n {tr(\"conversations.loadingSettings\", \"Loading settings...\")}\n </div>\n ) : !conversation ? (\n <div className=\"text-sm text-muted-foreground\">\n {tr(\n \"conversations.openConversationFirst\",\n \"Open a conversation first, then come back to settings.\",\n )}\n </div>\n ) : (\n <>\n <PageSection\n title={tr(\"conversations.notifications\", \"Notifications\")}\n description={tr(\n \"conversations.notificationsDescription\",\n \"Configure delivery behavior for this conversation\",\n )}\n >\n <div className=\"space-y-4 rounded-xl border border-border p-4\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"p-2 rounded-lg bg-status-info-bg-subtle text-status-info-text\">\n <Bell size={16} />\n </div>\n <div>\n <p className=\"text-sm font-medium text-foreground\">\n {tr(\n \"conversations.defaultNotificationLevel\",\n \"Default Notification Level\",\n )}\n </p>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {tr(\n \"conversations.defaultNotificationLevelHint\",\n \"This updates conversation settings JSON via GraphQL.\",\n )}\n </p>\n </div>\n </div>\n <select\n value={defaultNotificationLevel}\n onChange={(event) =>\n setDefaultNotificationLevel(event.target.value)\n }\n className=\"px-3 py-1.5 text-sm rounded-lg border border-border bg-background focus:outline-none focus:ring-2 focus:ring-ring\"\n >\n <option value=\"ALL\">\n {tr(\"conversations.allMessages\", \"All Messages\")}\n </option>\n <option value=\"MENTIONS\">\n {tr(\"conversations.mentionsOnly\", \"Mentions Only\")}\n </option>\n <option value=\"DIRECT\">\n {tr(\"conversations.directOnly\", \"Direct Only\")}\n </option>\n <option value=\"NONE\">\n {tr(\"conversations.none\", \"None\")}\n </option>\n </select>\n </div>\n </div>\n </PageSection>\n\n <PageSection\n title={tr(\"conversations.messageBehavior\", \"Message Behavior\")}\n description={tr(\n \"conversations.messageBehaviorDescription\",\n \"Tune read and typing experience\",\n )}\n >\n <div className=\"space-y-4 rounded-xl border border-border p-4\">\n <ToggleSetting\n icon={<Eye size={16} />}\n label={tr(\n \"conversations.typingIndicators\",\n \"Typing Indicators\",\n )}\n description={tr(\n \"conversations.typingIndicatorsDescription\",\n \"Show others when someone is typing\",\n )}\n checked={showTypingIndicators}\n onChange={setShowTypingIndicators}\n />\n <ToggleSetting\n icon={<Eye size={16} />}\n label={tr(\"conversations.readReceipts\", \"Read Receipts\")}\n description={tr(\n \"conversations.readReceiptsDescription\",\n \"Display read status for conversation participants\",\n )}\n checked={showReadReceipts}\n onChange={setShowReadReceipts}\n />\n </div>\n </PageSection>\n\n <PageSection\n title={tr(\"conversations.exportData\", \"Export Data\")}\n description={tr(\n \"conversations.exportDataDescription\",\n \"Download conversation comments in your preferred format\",\n )}\n >\n <div className=\"space-y-3 rounded-xl border border-border p-4\">\n <div className=\"flex flex-wrap gap-2\">\n {([\"JSON\", \"CSV\", \"MARKDOWN\"] as const).map((format) => (\n <PermissionGuard\n key={format}\n permission={CONVERSATIONS_PERMISSIONS.CONVERSATION_READ}\n >\n <button\n type=\"button\"\n disabled={exporting || !conversation}\n onClick={async () => {\n const url = await exportComments(\n \"conversation\",\n conversation!.id,\n format,\n );\n if (url && downloadLinkRef.current) {\n downloadLinkRef.current.href = url;\n downloadLinkRef.current.download = `conversation-${conversation!.id}.${format.toLowerCase()}`;\n downloadLinkRef.current.click();\n }\n }}\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg border border-border text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors disabled:opacity-50\"\n >\n <Download size={12} />\n {exporting\n ? tr(\"conversations.exporting\", \"Exporting…\")\n : format}\n </button>\n </PermissionGuard>\n ))}\n </div>\n {downloadUrl && (\n <p className=\"text-xs text-status-success-text\">\n {tr(\n \"conversations.exportReady\",\n \"Export ready — downloading…\",\n )}\n </p>\n )}\n {/* Hidden anchor driven programmatically for download trigger */}\n <a ref={downloadLinkRef} className=\"hidden\" aria-hidden=\"true\" />\n </div>\n </PageSection>\n\n {saveError && (\n <div className=\"text-xs text-destructive rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2\">\n {saveError.message}\n </div>\n )}\n {saved && !saveError && (\n <div className=\"text-xs text-status-success-text rounded-lg border border-border-default bg-status-success-bg-subtle px-3 py-2\">\n {tr(\"conversations.settingsSaved\", \"Settings saved.\")}\n </div>\n )}\n </>\n )}\n </PageLayout>\n );\n}\n\nfunction ToggleSetting({\n icon,\n label,\n description,\n checked,\n onChange,\n}: {\n icon: React.ReactNode;\n label: string;\n description: string;\n checked: boolean;\n onChange: (value: boolean) => void;\n}) {\n return (\n <PermissionGuard permission={CONVERSATIONS_PERMISSIONS.CONVERSATION_UPDATE}>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"p-2 rounded-lg bg-muted text-muted-foreground\">\n {icon}\n </div>\n <div>\n <p className=\"text-sm font-medium text-foreground\">{label}</p>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {description}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n aria-label={label}\n onClick={() => onChange(!checked)}\n className={`relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors ${checked ? \"bg-primary\" : \"bg-muted\"}`}\n >\n <span\n className={`pointer-events-none inline-block h-5 w-5 rounded-full bg-background shadow transition ${checked ? \"translate-x-5\" : \"translate-x-0\"}`}\n />\n </button>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function NewConversationPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=NewConversationPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NewConversationPage.d.ts","sourceRoot":"","sources":["../../../src/conversations/pages/NewConversationPage.tsx"],"names":[],"mappings":"AA6CA,wBAAgB,mBAAmB,4CA8ZlC"}
@@ -0,0 +1,287 @@
1
+ import { useConversations as e } from "../providers/ConversationsProvider.js";
2
+ import { joinPath as t } from "../utils/navigation.js";
3
+ import { cn as n } from "../utils/cn.js";
4
+ import { PageLayout as r } from "../components/PageLayout.js";
5
+ import { useCreateConversation as ee } from "../hooks/useConversationQueries.js";
6
+ import { PermissionGuard as i } from "../components/PermissionGuard.js";
7
+ import { CONVERSATIONS_PERMISSIONS as a } from "../constants/permissions.js";
8
+ import { nativeImpact as o, nativeNotify as s } from "../../utils/nativeBridge.js";
9
+ import { useCallback as c, useMemo as l, useState as u } from "react";
10
+ import { ArrowLeft as d, Globe as f, Hash as p, Lock as m, Megaphone as h, MessageCircle as g, Plus as _, Shield as v, Users as y, X as b } from "lucide-react";
11
+ import { useNavigate as x } from "react-router-dom";
12
+ import { useEventBus as S } from "@burdenoff/fe-libs/shared/events";
13
+ import { jsx as C, jsxs as w } from "react/jsx-runtime";
14
+ import { useI18n as T } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
+ //#region src/conversations/pages/NewConversationPage.tsx
16
+ function te(e) {
17
+ if ("graphQLErrors" in e) {
18
+ let t = e.graphQLErrors;
19
+ if (t && t.length > 0 && t[0]?.message) return t[0].message;
20
+ }
21
+ return e.message;
22
+ }
23
+ function E() {
24
+ let E = x(), { basePath: D } = e(), { createConversation: O, loading: k, error: A } = ee(), j = S(), { t: M } = T(), N = (e, t) => {
25
+ let n = M(e);
26
+ return n === e ? t : n;
27
+ }, P = l(() => [
28
+ {
29
+ type: "DIRECT",
30
+ label: N("conversations.directMessage", "Direct Message"),
31
+ description: N("conversations.directMessageDescription", "One-on-one private conversation"),
32
+ icon: /* @__PURE__ */ C(g, { size: 20 })
33
+ },
34
+ {
35
+ type: "GROUP",
36
+ label: N("conversations.groupChat", "Group Chat"),
37
+ description: N("conversations.groupChatDescription", "Invite multiple people to a group conversation"),
38
+ icon: /* @__PURE__ */ C(y, { size: 20 })
39
+ },
40
+ {
41
+ type: "CHANNEL",
42
+ label: N("conversations.channel", "Channel"),
43
+ description: N("conversations.channelDescription", "A topic-based channel that anyone can join"),
44
+ icon: /* @__PURE__ */ C(p, { size: 20 })
45
+ },
46
+ {
47
+ type: "ANNOUNCEMENT",
48
+ label: N("conversations.announcement", "Announcement"),
49
+ description: N("conversations.announcementDescription", "Broadcast messages to a large audience"),
50
+ icon: /* @__PURE__ */ C(h, { size: 20 })
51
+ }
52
+ ], [M]), F = l(() => [
53
+ {
54
+ value: "PUBLIC",
55
+ label: N("conversations.public", "Public"),
56
+ description: N("conversations.publicDescription", "Anyone in the workspace can discover and join"),
57
+ icon: /* @__PURE__ */ C(f, { size: 16 })
58
+ },
59
+ {
60
+ value: "PRIVATE",
61
+ label: N("conversations.private", "Private"),
62
+ description: N("conversations.privateDescription", "Only invited members can access"),
63
+ icon: /* @__PURE__ */ C(m, { size: 16 })
64
+ },
65
+ {
66
+ value: "PROTECTED",
67
+ label: N("conversations.protected", "Protected"),
68
+ description: N("conversations.protectedDescription", "Discoverable but requires approval to join"),
69
+ icon: /* @__PURE__ */ C(v, { size: 16 })
70
+ }
71
+ ], [M]), [I, L] = u("GROUP"), [R, z] = u(""), [B, V] = u(""), [H, U] = u("PRIVATE"), [W, G] = u(""), [K, q] = u([]), J = I === "DIRECT", Y = !J, X = c(() => {
72
+ let e = W.trim();
73
+ !e || K.includes(e) || (q(J ? [e] : (t) => [...t, e]), G(""));
74
+ }, [
75
+ W,
76
+ K,
77
+ J
78
+ ]), Z = c((e) => {
79
+ q((t) => t.filter((t) => t !== e));
80
+ }, []), Q = I === "DIRECT" || I === "GROUP", ne = c(async () => {
81
+ if (!(Q && K.length === 0) && !(Y && !R.trim())) {
82
+ o("light");
83
+ try {
84
+ let e = await O({
85
+ type: I,
86
+ title: Y ? R.trim() : void 0,
87
+ description: B.trim() || void 0,
88
+ participantIds: K,
89
+ visibility: H
90
+ });
91
+ if (!e) {
92
+ s("error");
93
+ return;
94
+ }
95
+ s("success"), j.emit("conversations.conversation.created", {
96
+ conversationId: e.id,
97
+ conversationType: I,
98
+ source: "new-conversation-page"
99
+ }), E(t(D || "/conversations", e.id));
100
+ } catch (e) {
101
+ throw s("error"), e;
102
+ }
103
+ }
104
+ }, [
105
+ D,
106
+ j,
107
+ Q,
108
+ K,
109
+ Y,
110
+ R,
111
+ O,
112
+ I,
113
+ B,
114
+ H,
115
+ E
116
+ ]), $ = (!Q || K.length > 0) && (!Y || R.trim().length > 0);
117
+ return /* @__PURE__ */ C(i, {
118
+ permission: a.CONVERSATION_CREATE,
119
+ allowUnavailablePermissions: !0,
120
+ children: /* @__PURE__ */ w(r, {
121
+ title: N("conversations.newConversation", "New Conversation"),
122
+ subtitle: N("conversations.newConversationSubtitle", "Start a new conversation with your team"),
123
+ icon: /* @__PURE__ */ C(_, { size: 24 }),
124
+ maxWidth: "lg",
125
+ headerActions: /* @__PURE__ */ w("button", {
126
+ type: "button",
127
+ onClick: () => E(D || "/conversations"),
128
+ className: "inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
129
+ children: [/* @__PURE__ */ C(d, { size: 16 }), N("conversations.back", "Back")]
130
+ }),
131
+ children: [
132
+ /* @__PURE__ */ w("section", {
133
+ className: "space-y-3",
134
+ children: [/* @__PURE__ */ C("h3", {
135
+ className: "text-sm font-semibold text-foreground",
136
+ children: N("conversations.conversationType", "Conversation Type")
137
+ }), /* @__PURE__ */ C("div", {
138
+ className: "grid grid-cols-1 sm:grid-cols-2 gap-3",
139
+ children: P.map((e) => /* @__PURE__ */ w("button", {
140
+ type: "button",
141
+ onClick: () => {
142
+ L(e.type), e.type === "DIRECT" && q((e) => e.slice(0, 1));
143
+ },
144
+ className: n("flex items-start gap-3 p-4 rounded-xl border text-left transition-all duration-150", I === e.type ? "border-primary bg-primary/5 ring-1 ring-primary/20" : "border-border hover:border-muted-foreground/30 hover:bg-muted/30"),
145
+ children: [/* @__PURE__ */ C("div", {
146
+ className: n("p-2 rounded-lg", I === e.type ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"),
147
+ children: e.icon
148
+ }), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
149
+ className: "text-sm font-medium text-foreground",
150
+ children: e.label
151
+ }), /* @__PURE__ */ C("p", {
152
+ className: "text-xs text-muted-foreground mt-0.5",
153
+ children: e.description
154
+ })] })]
155
+ }, e.type))
156
+ })]
157
+ }),
158
+ !J && /* @__PURE__ */ w("section", {
159
+ className: "space-y-3",
160
+ children: [
161
+ /* @__PURE__ */ C("h3", {
162
+ className: "text-sm font-semibold text-foreground",
163
+ children: N("conversations.visibility", "Visibility")
164
+ }),
165
+ /* @__PURE__ */ C("div", {
166
+ className: "flex gap-2",
167
+ children: F.map((e) => /* @__PURE__ */ w("button", {
168
+ type: "button",
169
+ onClick: () => U(e.value),
170
+ className: n("flex items-center gap-2 px-4 py-2.5 rounded-lg border text-sm transition-all", H === e.value ? "border-primary bg-primary/5 text-primary font-medium" : "border-border text-muted-foreground hover:text-foreground hover:bg-muted/30"),
171
+ children: [e.icon, e.label]
172
+ }, e.value))
173
+ }),
174
+ /* @__PURE__ */ C("p", {
175
+ className: "text-xs text-muted-foreground",
176
+ children: F.find((e) => e.value === H)?.description
177
+ })
178
+ ]
179
+ }),
180
+ Y && /* @__PURE__ */ w("section", {
181
+ className: "space-y-3",
182
+ children: [/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ w("label", {
183
+ htmlFor: "conv-title",
184
+ className: "text-sm font-semibold text-foreground",
185
+ children: [
186
+ N("conversations.name", "Name"),
187
+ " ",
188
+ /* @__PURE__ */ C("span", {
189
+ className: "text-destructive",
190
+ children: "*"
191
+ })
192
+ ]
193
+ }), /* @__PURE__ */ C("input", {
194
+ id: "conv-title",
195
+ type: "text",
196
+ value: R,
197
+ onChange: (e) => z(e.target.value),
198
+ placeholder: I === "CHANNEL" ? N("conversations.channelNamePlaceholder", "e.g., engineering-general") : N("conversations.conversationNamePlaceholder", "e.g., Product Launch Q1"),
199
+ maxLength: 200,
200
+ className: "mt-1.5 w-full px-3 py-2 text-sm rounded-lg border border-border bg-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
201
+ })] }), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("label", {
202
+ htmlFor: "conv-desc",
203
+ className: "text-sm font-semibold text-foreground",
204
+ children: N("conversations.description", "Description")
205
+ }), /* @__PURE__ */ C("textarea", {
206
+ id: "conv-desc",
207
+ value: B,
208
+ onChange: (e) => V(e.target.value),
209
+ placeholder: N("conversations.descriptionPlaceholder", "What is this conversation about?"),
210
+ rows: 2,
211
+ maxLength: 1e3,
212
+ className: "mt-1.5 w-full px-3 py-2 text-sm rounded-lg border border-border bg-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring resize-none"
213
+ })] })]
214
+ }),
215
+ /* @__PURE__ */ w("section", {
216
+ className: "space-y-3",
217
+ children: [
218
+ /* @__PURE__ */ w("h3", {
219
+ className: "text-sm font-semibold text-foreground",
220
+ children: [J ? N("conversations.participantId", "Participant ID") : N("conversations.participantIds", "Participant IDs"), !Q && /* @__PURE__ */ w("span", {
221
+ className: "ml-1.5 text-xs font-normal text-muted-foreground",
222
+ children: [
223
+ "(",
224
+ N("conversations.optional", "optional"),
225
+ ")"
226
+ ]
227
+ })]
228
+ }),
229
+ K.length > 0 && /* @__PURE__ */ C("div", {
230
+ className: "flex flex-wrap gap-2",
231
+ children: K.map((e) => /* @__PURE__ */ w("span", {
232
+ className: "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-primary/10 text-primary text-xs font-medium",
233
+ children: [e, /* @__PURE__ */ C("button", {
234
+ type: "button",
235
+ onClick: () => Z(e),
236
+ className: "p-0.5 rounded-full hover:bg-primary/20",
237
+ children: /* @__PURE__ */ C(b, { size: 12 })
238
+ })]
239
+ }, e))
240
+ }),
241
+ /* @__PURE__ */ w("div", {
242
+ className: "flex items-center gap-2",
243
+ children: [/* @__PURE__ */ C("input", {
244
+ type: "text",
245
+ value: W,
246
+ onChange: (e) => G(e.target.value),
247
+ onKeyDown: (e) => {
248
+ e.key === "Enter" && (e.preventDefault(), X());
249
+ },
250
+ placeholder: N("conversations.participantInputPlaceholder", "Enter user ID and press Enter"),
251
+ className: "w-full px-3 py-2 text-sm rounded-lg border border-border bg-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
252
+ }), /* @__PURE__ */ C("button", {
253
+ type: "button",
254
+ onClick: X,
255
+ className: "px-3 py-2 text-sm rounded-lg border border-border hover:bg-muted/50",
256
+ children: N("conversations.add", "Add")
257
+ })]
258
+ })
259
+ ]
260
+ }),
261
+ A && /* @__PURE__ */ C("div", {
262
+ className: "text-xs text-destructive rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2",
263
+ children: te(A)
264
+ }),
265
+ /* @__PURE__ */ w("div", {
266
+ className: "flex justify-end gap-3 pt-4 border-t border-border",
267
+ children: [/* @__PURE__ */ C("button", {
268
+ type: "button",
269
+ onClick: () => E(".."),
270
+ className: "px-4 py-2 text-sm font-medium rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
271
+ children: N("conversations.cancel", "Cancel")
272
+ }), /* @__PURE__ */ C("button", {
273
+ type: "button",
274
+ onClick: () => void ne(),
275
+ disabled: !$ || k,
276
+ className: n("inline-flex items-center gap-2 px-5 py-2 text-sm font-medium rounded-lg transition-all", $ && !k ? "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm" : "bg-muted text-muted-foreground cursor-not-allowed"),
277
+ children: k ? N("conversations.creating", "Creating...") : N("conversations.createConversation", "Create Conversation")
278
+ })]
279
+ })
280
+ ]
281
+ })
282
+ });
283
+ }
284
+ //#endregion
285
+ export { E as NewConversationPage };
286
+
287
+ //# sourceMappingURL=NewConversationPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NewConversationPage.js","names":[],"sources":["../../../src/conversations/pages/NewConversationPage.tsx"],"sourcesContent":["import { useState, useCallback, useMemo } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { useEventBus } from \"@burdenoff/fe-libs/shared/events\";\nimport { useNavigate } from \"react-router-dom\";\nimport {\n ArrowLeft,\n Globe,\n Hash,\n Lock,\n Megaphone,\n MessageCircle,\n Plus,\n Shield,\n Users,\n X,\n} from \"lucide-react\";\nimport { cn } from \"../utils/cn\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { useCreateConversation } from \"../hooks/useConversationQueries\";\nimport { useConversations } from \"../providers/ConversationsProvider\";\nimport type { ConversationType, ConversationVisibility } from \"../types\";\nimport { PermissionGuard } from \"../components/PermissionGuard\";\nimport { CONVERSATIONS_PERMISSIONS } from \"../constants/permissions\";\nimport { joinPath } from \"../utils/navigation\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\n/** Extract the first meaningful GraphQL error message from an ApolloError. */\nfunction getErrorMessage(error: Error): string {\n if (\"graphQLErrors\" in error) {\n const gqlErrors = (error as { graphQLErrors?: Array<{ message?: string }> })\n .graphQLErrors;\n if (gqlErrors && gqlErrors.length > 0 && gqlErrors[0]?.message) {\n return gqlErrors[0].message;\n }\n }\n return error.message;\n}\n\ninterface ConversationTypeOption {\n type: ConversationType;\n label: string;\n description: string;\n icon: React.ReactNode;\n}\n\nexport function NewConversationPage() {\n const navigate = useNavigate();\n const { basePath } = useConversations();\n const { createConversation, loading, error } = useCreateConversation();\n const bus = useEventBus();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n const CONVERSATION_TYPES: ConversationTypeOption[] = useMemo(\n () => [\n {\n type: \"DIRECT\" as ConversationType,\n label: tr(\"conversations.directMessage\", \"Direct Message\"),\n description: tr(\n \"conversations.directMessageDescription\",\n \"One-on-one private conversation\",\n ),\n icon: <MessageCircle size={20} />,\n },\n {\n type: \"GROUP\" as ConversationType,\n label: tr(\"conversations.groupChat\", \"Group Chat\"),\n description: tr(\n \"conversations.groupChatDescription\",\n \"Invite multiple people to a group conversation\",\n ),\n icon: <Users size={20} />,\n },\n {\n type: \"CHANNEL\" as ConversationType,\n label: tr(\"conversations.channel\", \"Channel\"),\n description: tr(\n \"conversations.channelDescription\",\n \"A topic-based channel that anyone can join\",\n ),\n icon: <Hash size={20} />,\n },\n {\n type: \"ANNOUNCEMENT\" as ConversationType,\n label: tr(\"conversations.announcement\", \"Announcement\"),\n description: tr(\n \"conversations.announcementDescription\",\n \"Broadcast messages to a large audience\",\n ),\n icon: <Megaphone size={20} />,\n },\n ],\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [t],\n );\n\n const VISIBILITY_OPTIONS: Array<{\n value: ConversationVisibility;\n label: string;\n description: string;\n icon: React.ReactNode;\n }> = useMemo(\n () => [\n {\n value: \"PUBLIC\" as ConversationVisibility,\n label: tr(\"conversations.public\", \"Public\"),\n description: tr(\n \"conversations.publicDescription\",\n \"Anyone in the workspace can discover and join\",\n ),\n icon: <Globe size={16} />,\n },\n {\n value: \"PRIVATE\" as ConversationVisibility,\n label: tr(\"conversations.private\", \"Private\"),\n description: tr(\n \"conversations.privateDescription\",\n \"Only invited members can access\",\n ),\n icon: <Lock size={16} />,\n },\n {\n value: \"PROTECTED\" as ConversationVisibility,\n label: tr(\"conversations.protected\", \"Protected\"),\n description: tr(\n \"conversations.protectedDescription\",\n \"Discoverable but requires approval to join\",\n ),\n icon: <Shield size={16} />,\n },\n ],\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [t],\n );\n\n const [selectedType, setSelectedType] = useState<ConversationType>(\"GROUP\");\n const [title, setTitle] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [visibility, setVisibility] =\n useState<ConversationVisibility>(\"PRIVATE\");\n const [participantInput, setParticipantInput] = useState(\"\");\n const [participantIds, setParticipantIds] = useState<string[]>([]);\n\n const isDirectMessage = selectedType === \"DIRECT\";\n const needsTitle = !isDirectMessage;\n\n const addParticipant = useCallback(() => {\n const value = participantInput.trim();\n if (!value || participantIds.includes(value)) return;\n if (isDirectMessage) {\n setParticipantIds([value]);\n } else {\n setParticipantIds((prev) => [...prev, value]);\n }\n setParticipantInput(\"\");\n }, [participantInput, participantIds, isDirectMessage]);\n\n const removeParticipant = useCallback((participantId: string) => {\n setParticipantIds((prev) => prev.filter((id) => id !== participantId));\n }, []);\n\n const requiresParticipants =\n selectedType === \"DIRECT\" || selectedType === \"GROUP\";\n\n const handleCreate = useCallback(async () => {\n if (requiresParticipants && participantIds.length === 0) return;\n if (needsTitle && !title.trim()) return;\n\n nativeImpact(\"light\");\n try {\n const conversation = await createConversation({\n type: selectedType,\n title: needsTitle ? title.trim() : undefined,\n description: description.trim() || undefined,\n participantIds,\n visibility,\n });\n\n if (!conversation) {\n nativeNotify(\"error\");\n return;\n }\n nativeNotify(\"success\");\n bus.emit(\"conversations.conversation.created\", {\n conversationId: conversation.id,\n conversationType: selectedType,\n source: \"new-conversation-page\",\n });\n navigate(joinPath(basePath || \"/conversations\", conversation.id));\n } catch (error) {\n nativeNotify(\"error\");\n throw error;\n }\n }, [\n basePath,\n bus,\n requiresParticipants,\n participantIds,\n needsTitle,\n title,\n createConversation,\n selectedType,\n description,\n visibility,\n navigate,\n ]);\n\n const canCreate =\n (!requiresParticipants || participantIds.length > 0) &&\n (!needsTitle || title.trim().length > 0);\n\n return (\n <PermissionGuard\n permission={CONVERSATIONS_PERMISSIONS.CONVERSATION_CREATE}\n allowUnavailablePermissions\n >\n <PageLayout\n title={tr(\"conversations.newConversation\", \"New Conversation\")}\n subtitle={tr(\n \"conversations.newConversationSubtitle\",\n \"Start a new conversation with your team\",\n )}\n icon={<Plus size={24} />}\n maxWidth=\"lg\"\n headerActions={\n <button\n type=\"button\"\n onClick={() => navigate(basePath || \"/conversations\")}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors\"\n >\n <ArrowLeft size={16} />\n {tr(\"conversations.back\", \"Back\")}\n </button>\n }\n >\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {tr(\"conversations.conversationType\", \"Conversation Type\")}\n </h3>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n {CONVERSATION_TYPES.map((option) => (\n <button\n key={option.type}\n type=\"button\"\n onClick={() => {\n setSelectedType(option.type);\n if (option.type === \"DIRECT\") {\n setParticipantIds((prev) => prev.slice(0, 1));\n }\n }}\n className={cn(\n \"flex items-start gap-3 p-4 rounded-xl border text-left transition-all duration-150\",\n selectedType === option.type\n ? \"border-primary bg-primary/5 ring-1 ring-primary/20\"\n : \"border-border hover:border-muted-foreground/30 hover:bg-muted/30\",\n )}\n >\n <div\n className={cn(\n \"p-2 rounded-lg\",\n selectedType === option.type\n ? \"bg-primary/10 text-primary\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {option.icon}\n </div>\n <div>\n <p className=\"text-sm font-medium text-foreground\">\n {option.label}\n </p>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {option.description}\n </p>\n </div>\n </button>\n ))}\n </div>\n </section>\n\n {!isDirectMessage && (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {tr(\"conversations.visibility\", \"Visibility\")}\n </h3>\n <div className=\"flex gap-2\">\n {VISIBILITY_OPTIONS.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => setVisibility(option.value)}\n className={cn(\n \"flex items-center gap-2 px-4 py-2.5 rounded-lg border text-sm transition-all\",\n visibility === option.value\n ? \"border-primary bg-primary/5 text-primary font-medium\"\n : \"border-border text-muted-foreground hover:text-foreground hover:bg-muted/30\",\n )}\n >\n {option.icon}\n {option.label}\n </button>\n ))}\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {\n VISIBILITY_OPTIONS.find((option) => option.value === visibility)\n ?.description\n }\n </p>\n </section>\n )}\n\n {needsTitle && (\n <section className=\"space-y-3\">\n <div>\n <label\n htmlFor=\"conv-title\"\n className=\"text-sm font-semibold text-foreground\"\n >\n {tr(\"conversations.name\", \"Name\")}{\" \"}\n <span className=\"text-destructive\">*</span>\n </label>\n <input\n id=\"conv-title\"\n type=\"text\"\n value={title}\n onChange={(event) => setTitle(event.target.value)}\n placeholder={\n selectedType === \"CHANNEL\"\n ? tr(\n \"conversations.channelNamePlaceholder\",\n \"e.g., engineering-general\",\n )\n : tr(\n \"conversations.conversationNamePlaceholder\",\n \"e.g., Product Launch Q1\",\n )\n }\n maxLength={200}\n className=\"mt-1.5 w-full px-3 py-2 text-sm rounded-lg border border-border bg-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n </div>\n <div>\n <label\n htmlFor=\"conv-desc\"\n className=\"text-sm font-semibold text-foreground\"\n >\n {tr(\"conversations.description\", \"Description\")}\n </label>\n <textarea\n id=\"conv-desc\"\n value={description}\n onChange={(event) => setDescription(event.target.value)}\n placeholder={tr(\n \"conversations.descriptionPlaceholder\",\n \"What is this conversation about?\",\n )}\n rows={2}\n maxLength={1000}\n className=\"mt-1.5 w-full px-3 py-2 text-sm rounded-lg border border-border bg-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring resize-none\"\n />\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n {isDirectMessage\n ? tr(\"conversations.participantId\", \"Participant ID\")\n : tr(\"conversations.participantIds\", \"Participant IDs\")}\n {!requiresParticipants && (\n <span className=\"ml-1.5 text-xs font-normal text-muted-foreground\">\n ({tr(\"conversations.optional\", \"optional\")})\n </span>\n )}\n </h3>\n\n {participantIds.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {participantIds.map((participantId) => (\n <span\n key={participantId}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-primary/10 text-primary text-xs font-medium\"\n >\n {participantId}\n <button\n type=\"button\"\n onClick={() => removeParticipant(participantId)}\n className=\"p-0.5 rounded-full hover:bg-primary/20\"\n >\n <X size={12} />\n </button>\n </span>\n ))}\n </div>\n )}\n\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={participantInput}\n onChange={(event) => setParticipantInput(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== \"Enter\") return;\n event.preventDefault();\n addParticipant();\n }}\n placeholder={tr(\n \"conversations.participantInputPlaceholder\",\n \"Enter user ID and press Enter\",\n )}\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border bg-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n <button\n type=\"button\"\n onClick={addParticipant}\n className=\"px-3 py-2 text-sm rounded-lg border border-border hover:bg-muted/50\"\n >\n {tr(\"conversations.add\", \"Add\")}\n </button>\n </div>\n </section>\n\n {error && (\n <div className=\"text-xs text-destructive rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2\">\n {getErrorMessage(error)}\n </div>\n )}\n\n <div className=\"flex justify-end gap-3 pt-4 border-t border-border\">\n <button\n type=\"button\"\n onClick={() => navigate(\"..\")}\n className=\"px-4 py-2 text-sm font-medium rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors\"\n >\n {tr(\"conversations.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleCreate()}\n disabled={!canCreate || loading}\n className={cn(\n \"inline-flex items-center gap-2 px-5 py-2 text-sm font-medium rounded-lg transition-all\",\n canCreate && !loading\n ? \"bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm\"\n : \"bg-muted text-muted-foreground cursor-not-allowed\",\n )}\n >\n {loading\n ? tr(\"conversations.creating\", \"Creating...\")\n : tr(\"conversations.createConversation\", \"Create Conversation\")}\n </button>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ import { ConversationsRootProps } from '../types';
3
+
4
+ /**
5
+ * Hook to access Conversations context
6
+ */
7
+ export declare const useConversations: () => ConversationsRootProps;
8
+ /**
9
+ * Provider component for Conversations microfrontend
10
+ * Sets up routing, context, Apollo Client, and React Query client
11
+ */
12
+ export declare const ConversationsProvider: FC<PropsWithChildren<ConversationsRootProps>>;
13
+ //# sourceMappingURL=ConversationsProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConversationsProvider.d.ts","sourceRoot":"","sources":["../../../src/conversations/providers/ConversationsProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAmBnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAoDvD;;GAEG;AACH,eAAO,MAAM,gBAAgB,8BAQ5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CACpC,iBAAiB,CAAC,sBAAsB,CAAC,CAqL1C,CAAC"}