@burdenoff/microfe-crewfoundry 2026.1029.2 → 2026.1030.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 (36) hide show
  1. package/dist/crewfoundry/lib/useFocusedRecordParam.d.ts +51 -0
  2. package/dist/crewfoundry/lib/useFocusedRecordParam.d.ts.map +1 -0
  3. package/dist/crewfoundry/lib/useFocusedRecordParam.js +38 -0
  4. package/dist/crewfoundry/lib/useFocusedRecordParam.js.map +1 -0
  5. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.d.ts.map +1 -1
  6. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +119 -112
  7. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
  8. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.d.ts.map +1 -1
  9. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +78 -71
  10. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  11. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.d.ts.map +1 -1
  12. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +88 -81
  13. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  14. package/dist/crewfoundry/pages/HiringCandidatesPagePage.d.ts.map +1 -1
  15. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +133 -126
  16. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  17. package/dist/crewfoundry/pages/HiringInterviewsPagePage.d.ts.map +1 -1
  18. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +150 -143
  19. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  20. package/dist/crewfoundry/pages/HrDepartmentsPagePage.d.ts.map +1 -1
  21. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +110 -103
  22. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  23. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.d.ts.map +1 -1
  24. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +173 -162
  25. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  26. package/dist/crewfoundry/pages/HrPayrollPagePage.d.ts.map +1 -1
  27. package/dist/crewfoundry/pages/HrPayrollPagePage.js +169 -158
  28. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  29. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.d.ts.map +1 -1
  30. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +179 -163
  31. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  32. package/dist/utils/pageContext.d.ts +43 -4
  33. package/dist/utils/pageContext.d.ts.map +1 -1
  34. package/dist/utils/pageContext.js +10 -3
  35. package/dist/utils/pageContext.js.map +1 -1
  36. package/package.json +3 -2
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The search param that names the record a page is focused on.
3
+ *
4
+ * It is the same `?id=` the detail pages (`hiring/job-details-page?id=…`)
5
+ * already read, so `resolveCrewFoundryConversationContext` in
6
+ * `src/utils/pageContext.ts` resolves every focused record the same way: the
7
+ * assistant's "this interview" / "approve this" works without the user naming
8
+ * the record.
9
+ */
10
+ export declare const FOCUSED_RECORD_PARAM = "id";
11
+ interface UseFocusedRecordParamOptions<T extends {
12
+ id: string;
13
+ }> {
14
+ /** The records the page can focus. Restoring waits until the URL's id is among them. */
15
+ records: readonly T[];
16
+ /** The record the page is showing right now (selected row, open edit dialog), or null. */
17
+ activeId: string | null;
18
+ /** Re-focus the record named by the URL when the page is opened from a link or reloaded. */
19
+ onRestore: (record: T) => void;
20
+ }
21
+ /**
22
+ * Keeps `?id=` in step with the record a list page is focused on.
23
+ *
24
+ * List pages (leave, time, payroll, interviews, departments, clients, vendors,
25
+ * announcements, candidates) have no detail route of their own: the user
26
+ * focuses a record in place, by selecting a row or opening its edit dialog.
27
+ * Writing that focus to the URL is what lets the assistant's page context name
28
+ * the record, and makes the focused record linkable.
29
+ *
30
+ * - On first load, an `?id=` already in the URL is restored once, as soon as
31
+ * the record is loaded (`onRestore`). Until then the id is left alone, so a
32
+ * slow list load cannot erase a deep link.
33
+ * - After that, the URL follows `activeId`: set while a record is focused,
34
+ * removed when focus is cleared. Updates use `replace` so focusing rows does
35
+ * not fill the browser history.
36
+ */
37
+ export declare function useFocusedRecordParam<T extends {
38
+ id: string;
39
+ }>({ records, activeId, onRestore, }: UseFocusedRecordParamOptions<T>): void;
40
+ /**
41
+ * Marks the focused row's primary cell. `ResponsiveTable` has no row-state
42
+ * styling, so the highlight sits on the cell; the classes match the selected
43
+ * state of the interview schedule list.
44
+ */
45
+ export declare const FOCUSED_CELL_CLASS = "rounded-[var(--radius-input)] bg-action-primary-bg/10 ring-1 ring-action-primary-bg";
46
+ /** The 1-based `usePagination` page that holds `id` in `list` (1 when it is absent). */
47
+ export declare function pageContaining(list: readonly {
48
+ id: string;
49
+ }[], id: string, pageSize: number): number;
50
+ export {};
51
+ //# sourceMappingURL=useFocusedRecordParam.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFocusedRecordParam.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/lib/useFocusedRecordParam.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,UAAU,4BAA4B,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAC7D,wFAAwF;IACxF,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;IACtB,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,4FAA4F;IAC5F,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;CAChC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EAC9D,OAAO,EACP,QAAQ,EACR,SAAS,GACV,EAAE,4BAA4B,CAAC,CAAC,CAAC,GAAG,IAAI,CA6DxC;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,wFACwD,CAAC;AAExF,wFAAwF;AACxF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,GACf,MAAM,CAGR"}
@@ -0,0 +1,38 @@
1
+ import { useEffect as e, useRef as t } from "react";
2
+ import { useSearchParams as n } from "react-router";
3
+ function r({ records: r, activeId: i, onRestore: a }) {
4
+ let [o, s] = n(), c = o.get("id"), l = t(c === null), u = t(null), d = t(a), f = t(c), p = t(s);
5
+ e(() => {
6
+ d.current = a, f.current = c, p.current = s;
7
+ }), e(() => {
8
+ if (l.current) return;
9
+ if (c === null) {
10
+ l.current = !0;
11
+ return;
12
+ }
13
+ let e = r.find((e) => e.id === c);
14
+ e && (l.current = !0, u.current = e.id, d.current(e));
15
+ }, [r, c]), e(() => {
16
+ if (!l.current) {
17
+ if (i === null) return;
18
+ l.current = !0;
19
+ }
20
+ if (u.current !== null) {
21
+ if (i !== u.current) return;
22
+ u.current = null;
23
+ }
24
+ i !== f.current && p.current((e) => {
25
+ let t = new URLSearchParams(e);
26
+ return i ? t.set("id", i) : t.delete("id"), t;
27
+ }, { replace: !0 });
28
+ }, [i]);
29
+ }
30
+ var i = "rounded-[var(--radius-input)] bg-action-primary-bg/10 ring-1 ring-action-primary-bg";
31
+ function a(e, t, n) {
32
+ let r = e.findIndex((e) => e.id === t);
33
+ return r < 0 || n <= 0 ? 1 : Math.floor(r / n) + 1;
34
+ }
35
+ //#endregion
36
+ export { i as FOCUSED_CELL_CLASS, a as pageContaining, r as useFocusedRecordParam };
37
+
38
+ //# sourceMappingURL=useFocusedRecordParam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFocusedRecordParam.js","names":[],"sources":["../../../src/crewfoundry/lib/useFocusedRecordParam.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { useSearchParams } from 'react-router';\n\n/**\n * The search param that names the record a page is focused on.\n *\n * It is the same `?id=` the detail pages (`hiring/job-details-page?id=…`)\n * already read, so `resolveCrewFoundryConversationContext` in\n * `src/utils/pageContext.ts` resolves every focused record the same way: the\n * assistant's \"this interview\" / \"approve this\" works without the user naming\n * the record.\n */\nexport const FOCUSED_RECORD_PARAM = 'id';\n\ninterface UseFocusedRecordParamOptions<T extends { id: string }> {\n /** The records the page can focus. Restoring waits until the URL's id is among them. */\n records: readonly T[];\n /** The record the page is showing right now (selected row, open edit dialog), or null. */\n activeId: string | null;\n /** Re-focus the record named by the URL when the page is opened from a link or reloaded. */\n onRestore: (record: T) => void;\n}\n\n/**\n * Keeps `?id=` in step with the record a list page is focused on.\n *\n * List pages (leave, time, payroll, interviews, departments, clients, vendors,\n * announcements, candidates) have no detail route of their own: the user\n * focuses a record in place, by selecting a row or opening its edit dialog.\n * Writing that focus to the URL is what lets the assistant's page context name\n * the record, and makes the focused record linkable.\n *\n * - On first load, an `?id=` already in the URL is restored once, as soon as\n * the record is loaded (`onRestore`). Until then the id is left alone, so a\n * slow list load cannot erase a deep link.\n * - After that, the URL follows `activeId`: set while a record is focused,\n * removed when focus is cleared. Updates use `replace` so focusing rows does\n * not fill the browser history.\n */\nexport function useFocusedRecordParam<T extends { id: string }>({\n records,\n activeId,\n onRestore,\n}: UseFocusedRecordParamOptions<T>): void {\n const [searchParams, setSearchParams] = useSearchParams();\n const urlId = searchParams.get(FOCUSED_RECORD_PARAM);\n\n // The initial URL id is restored at most once; afterwards the page owns focus.\n const restoredRef = useRef<boolean>(urlId === null);\n // Set while a restored record has been handed to the page but the page's\n // focus has not caught up yet, so the sync below does not erase the id in\n // the render between the two.\n const awaitingFocusRef = useRef<string | null>(null);\n const onRestoreRef = useRef(onRestore);\n // Read the latest URL state inside the sync effect without re-running it on\n // every navigation: it must fire only when the page's focus changes.\n const urlIdRef = useRef(urlId);\n const setSearchParamsRef = useRef(setSearchParams);\n\n // Runs before the effects below in every commit, so they see this render's values.\n useEffect(() => {\n onRestoreRef.current = onRestore;\n urlIdRef.current = urlId;\n setSearchParamsRef.current = setSearchParams;\n });\n\n useEffect(() => {\n if (restoredRef.current) return;\n if (urlId === null) {\n restoredRef.current = true;\n return;\n }\n const record = records.find((candidate) => candidate.id === urlId);\n if (!record) return;\n restoredRef.current = true;\n awaitingFocusRef.current = record.id;\n onRestoreRef.current(record);\n }, [records, urlId]);\n\n useEffect(() => {\n if (!restoredRef.current) {\n // The linked record never loaded (deleted, or not visible to this\n // user). Once the user focuses something else, the page owns the URL.\n if (activeId === null) return;\n restoredRef.current = true;\n }\n if (awaitingFocusRef.current !== null) {\n if (activeId !== awaitingFocusRef.current) return;\n awaitingFocusRef.current = null;\n }\n if (activeId === urlIdRef.current) return;\n setSearchParamsRef.current(\n (previous) => {\n const next = new URLSearchParams(previous);\n if (activeId) {\n next.set(FOCUSED_RECORD_PARAM, activeId);\n } else {\n next.delete(FOCUSED_RECORD_PARAM);\n }\n return next;\n },\n { replace: true }\n );\n }, [activeId]);\n}\n\n/**\n * Marks the focused row's primary cell. `ResponsiveTable` has no row-state\n * styling, so the highlight sits on the cell; the classes match the selected\n * state of the interview schedule list.\n */\nexport const FOCUSED_CELL_CLASS =\n 'rounded-[var(--radius-input)] bg-action-primary-bg/10 ring-1 ring-action-primary-bg';\n\n/** The 1-based `usePagination` page that holds `id` in `list` (1 when it is absent). */\nexport function pageContaining(\n list: readonly { id: string }[],\n id: string,\n pageSize: number\n): number {\n const index = list.findIndex((item) => item.id === id);\n return index < 0 || pageSize <= 0 ? 1 : Math.floor(index / pageSize) + 1;\n}\n"],"mappings":";;AAuCA,SAAgB,EAAgD,EAC9D,YACA,aACA,gBACwC;CACxC,IAAM,CAAC,GAAc,KAAmB,GAAiB,EACnD,IAAQ,EAAa,IAAA,KAAyB,EAG9C,IAAc,EAAgB,MAAU,KAAK,EAI7C,IAAmB,EAAsB,KAAK,EAC9C,IAAe,EAAO,EAAU,EAGhC,IAAW,EAAO,EAAM,EACxB,IAAqB,EAAO,EAAgB;AAsBlD,CAnBA,QAAgB;AAGd,EAFA,EAAa,UAAU,GACvB,EAAS,UAAU,GACnB,EAAmB,UAAU;GAC7B,EAEF,QAAgB;AACd,MAAI,EAAY,QAAS;AACzB,MAAI,MAAU,MAAM;AAClB,KAAY,UAAU;AACtB;;EAEF,IAAM,IAAS,EAAQ,MAAM,MAAc,EAAU,OAAO,EAAM;AAC7D,QACL,EAAY,UAAU,IACtB,EAAiB,UAAU,EAAO,IAClC,EAAa,QAAQ,EAAO;IAC3B,CAAC,GAAS,EAAM,CAAC,EAEpB,QAAgB;AACd,MAAI,CAAC,EAAY,SAAS;AAGxB,OAAI,MAAa,KAAM;AACvB,KAAY,UAAU;;AAExB,MAAI,EAAiB,YAAY,MAAM;AACrC,OAAI,MAAa,EAAiB,QAAS;AAC3C,KAAiB,UAAU;;AAEzB,QAAa,EAAS,WAC1B,EAAmB,SAChB,MAAa;GACZ,IAAM,IAAO,IAAI,gBAAgB,EAAS;AAM1C,UALI,IACF,EAAK,IAAA,MAA0B,EAAS,GAExC,EAAK,OAAA,KAA4B,EAE5B;KAET,EAAE,SAAS,IAAM,CAClB;IACA,CAAC,EAAS,CAAC;;AAQhB,IAAa,IACX;AAGF,SAAgB,EACd,GACA,GACA,GACQ;CACR,IAAM,IAAQ,EAAK,WAAW,MAAS,EAAK,OAAO,EAAG;AACtD,QAAO,IAAQ,KAAK,KAAY,IAAI,IAAI,KAAK,MAAM,IAAQ,EAAS,GAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommunicationsAnnouncementsPagePage.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/pages/CommunicationsAnnouncementsPagePage.tsx"],"names":[],"mappings":"AAiHA,wBAAgB,mCAAmC,gCAiVlD"}
1
+ {"version":3,"file":"CommunicationsAnnouncementsPagePage.d.ts","sourceRoot":"","sources":["../../../src/crewfoundry/pages/CommunicationsAnnouncementsPagePage.tsx"],"names":[],"mappings":"AAkHA,wBAAgB,mCAAmC,gCAuVlD"}
@@ -2,12 +2,13 @@ import { CONVERSATIONS_ROUTE as e, useCrewFoundryStore as t } from "../store/cre
2
2
  import { formatEnumLabel as n } from "../utils/formatEnumLabel.js";
3
3
  import { AvatarStack as r } from "../components/viz/AvatarStack.js";
4
4
  import "../components/viz/index.js";
5
- import { FormModal as ee, useFormModal as i } from "../components/forms/FormModal.js";
6
- import { useMemo as a, useState as o } from "react";
7
- import { Eye as s, MessageSquare as c, Pencil as l, Pin as u, PinOff as d, Plus as f, Search as te, Send as ne, Trash2 as re } from "lucide-react";
8
- import { useNavigate as ie } from "react-router";
9
- import { jsx as p, jsxs as m } from "react/jsx-runtime";
10
- import { AlertDialog as h, AlertDialogAction as g, AlertDialogCancel as _, AlertDialogContent as ae, AlertDialogDescription as oe, AlertDialogFooter as se, AlertDialogHeader as v, AlertDialogTitle as y, Badge as b, Button as x, Card as ce, CardContent as S, CardHeader as C, CardTitle as w, GlassCard as le, GradientText as ue, IllustratedEmptyState as de, Input as T, PagePurpose as E } from "@burdenoff/fe-libs/ui";
5
+ import { FormModal as i, useFormModal as a } from "../components/forms/FormModal.js";
6
+ import { useFocusedRecordParam as ee } from "../lib/useFocusedRecordParam.js";
7
+ import { useMemo as o, useState as s } from "react";
8
+ import { Eye as te, MessageSquare as ne, Pencil as re, Pin as c, PinOff as ie, Plus as l, Search as u, Send as d, Trash2 as f } from "lucide-react";
9
+ import { useNavigate as p } from "react-router";
10
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
11
+ import { AlertDialog as g, AlertDialogAction as _, AlertDialogCancel as ae, AlertDialogContent as oe, AlertDialogDescription as se, AlertDialogFooter as ce, AlertDialogHeader as le, AlertDialogTitle as ue, Badge as v, Button as y, Card as de, CardContent as b, CardHeader as x, CardTitle as S, GlassCard as fe, GradientText as C, IllustratedEmptyState as w, Input as T, PagePurpose as E } from "@burdenoff/fe-libs/ui";
11
12
  import { useGlobalUi as D } from "@burdenoff/fe-libs/shared/providers/shell";
12
13
  import { formatRelativeTime as O } from "@burdenoff/fe-libs/shared/utils";
13
14
  //#region src/crewfoundry/pages/CommunicationsAnnouncementsPagePage.tsx
@@ -123,10 +124,16 @@ var k = [
123
124
  }
124
125
  };
125
126
  function I() {
126
- let { announcements: O, notifications: k, addAnnouncement: A, updateAnnouncement: I, removeAnnouncement: L } = t(), { showToast: R } = D(), z = ie(), B = i(), [V, H] = o(null), [U, W] = o(!1), [G, fe] = o(""), K = B.context, q = a(() => k.filter((e) => e.category === "communications"), [k]), J = G.trim().toLowerCase(), Y = a(() => J.length === 0 ? O : O.filter((e) => `${e.title} ${e.content} ${e.tags.join(" ")}`.toLowerCase().includes(J)), [O, J]), X = Y.filter((e) => e.isPinned), Z = Y.filter((e) => !e.isPinned), pe = async (e) => {
127
+ let { announcements: O, notifications: k, addAnnouncement: A, updateAnnouncement: I, removeAnnouncement: L } = t(), { showToast: R } = D(), pe = p(), z = a();
128
+ ee({
129
+ records: O,
130
+ activeId: z.open ? z.context?.id ?? null : null,
131
+ onRestore: z.openModal
132
+ });
133
+ let [B, V] = s(null), [H, U] = s(!1), [W, me] = s(""), G = z.context, K = o(() => k.filter((e) => e.category === "communications"), [k]), q = W.trim().toLowerCase(), J = o(() => q.length === 0 ? O : O.filter((e) => `${e.title} ${e.content} ${e.tags.join(" ")}`.toLowerCase().includes(q)), [O, q]), Y = J.filter((e) => e.isPinned), X = J.filter((e) => !e.isPinned), he = async (e) => {
127
134
  let t = Array.isArray(e.tags) ? e.tags : [];
128
- if (K) {
129
- await I(K.id, {
135
+ if (G) {
136
+ await I(G.id, {
130
137
  title: String(e.title),
131
138
  content: String(e.content),
132
139
  category: String(e.category),
@@ -149,117 +156,117 @@ function I() {
149
156
  viewCount: 0,
150
157
  tags: t
151
158
  }), R("Announcement published", "success");
152
- }, me = async (e) => {
159
+ }, ge = async (e) => {
153
160
  try {
154
161
  await I(e.id, { isPinned: !e.isPinned }), R(e.isPinned ? "Unpinned" : "Pinned to top", "success");
155
162
  } catch (e) {
156
163
  R(e instanceof Error ? e.message : "Unable to update announcement", "error");
157
164
  }
158
- }, he = async () => {
159
- if (V) {
160
- W(!0);
165
+ }, _e = async () => {
166
+ if (B) {
167
+ U(!0);
161
168
  try {
162
- await L(V.id), R("Announcement deleted", "success"), H(null);
169
+ await L(B.id), R("Announcement deleted", "success"), V(null);
163
170
  } catch (e) {
164
171
  R(e instanceof Error ? e.message : "Unable to delete announcement", "error");
165
172
  } finally {
166
- W(!1);
173
+ U(!1);
167
174
  }
168
175
  }
169
- }, Q = () => z(e), ge = K ? {
170
- title: K.title,
171
- content: K.content,
172
- category: K.category,
173
- priority: K.priority,
174
- tags: K.tags,
175
- isPinned: K.isPinned
176
- } : void 0, $ = (e, t) => /* @__PURE__ */ m(le, {
176
+ }, Z = () => pe(e), Q = G ? {
177
+ title: G.title,
178
+ content: G.content,
179
+ category: G.category,
180
+ priority: G.priority,
181
+ tags: G.tags,
182
+ isPinned: G.isPinned
183
+ } : void 0, $ = (e, t) => /* @__PURE__ */ h(fe, {
177
184
  treatment: t ? "glass" : "plain",
178
185
  glow: t,
179
186
  className: "transition-shadow hover:shadow-elevation-2",
180
- children: [/* @__PURE__ */ m(C, {
187
+ children: [/* @__PURE__ */ h(x, {
181
188
  className: "pb-3",
182
- children: [/* @__PURE__ */ m("div", {
189
+ children: [/* @__PURE__ */ h("div", {
183
190
  className: "flex items-start justify-between gap-3",
184
- children: [/* @__PURE__ */ m("div", {
191
+ children: [/* @__PURE__ */ h("div", {
185
192
  className: "flex flex-wrap items-center gap-2",
186
193
  children: [
187
- /* @__PURE__ */ p(b, {
194
+ /* @__PURE__ */ m(v, {
188
195
  className: `border-transparent text-[10px] ${M[e.priority]}`,
189
196
  children: n(e.priority)
190
197
  }),
191
- /* @__PURE__ */ p(b, {
198
+ /* @__PURE__ */ m(v, {
192
199
  className: `border-transparent text-[10px] ${j[e.category]}`,
193
200
  children: n(e.category)
194
201
  }),
195
- /* @__PURE__ */ m("span", {
202
+ /* @__PURE__ */ h("span", {
196
203
  className: "flex items-center gap-1.5 text-xs text-text-secondary",
197
204
  children: [
198
- /* @__PURE__ */ p(r, {
205
+ /* @__PURE__ */ m(r, {
199
206
  people: [{ name: e.author }],
200
207
  size: 20
201
208
  }),
202
209
  e.author,
203
- /* @__PURE__ */ m("span", {
210
+ /* @__PURE__ */ h("span", {
204
211
  className: "text-text-muted",
205
212
  children: ["· ", F(e.createdAt)]
206
213
  })
207
214
  ]
208
215
  })
209
216
  ]
210
- }), /* @__PURE__ */ m("div", {
217
+ }), /* @__PURE__ */ h("div", {
211
218
  className: "flex items-center gap-0.5",
212
219
  children: [
213
- /* @__PURE__ */ p(x, {
220
+ /* @__PURE__ */ m(y, {
214
221
  variant: "ghost",
215
222
  size: "icon",
216
223
  className: `h-7 w-7 ${e.isPinned ? "text-status-info-text" : ""}`,
217
224
  "aria-label": e.isPinned ? `Unpin ${e.title}` : `Pin ${e.title}`,
218
225
  "aria-pressed": e.isPinned,
219
- onClick: () => void me(e),
220
- children: e.isPinned ? /* @__PURE__ */ p(d, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ p(u, { className: "h-3.5 w-3.5" })
226
+ onClick: () => void ge(e),
227
+ children: e.isPinned ? /* @__PURE__ */ m(ie, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ m(c, { className: "h-3.5 w-3.5" })
221
228
  }),
222
- /* @__PURE__ */ p(x, {
229
+ /* @__PURE__ */ m(y, {
223
230
  variant: "ghost",
224
231
  size: "icon",
225
232
  className: "h-7 w-7",
226
233
  "aria-label": `Edit announcement ${e.title}`,
227
- onClick: () => B.openModal(e),
228
- children: /* @__PURE__ */ p(l, { className: "h-3.5 w-3.5" })
234
+ onClick: () => z.openModal(e),
235
+ children: /* @__PURE__ */ m(re, { className: "h-3.5 w-3.5" })
229
236
  }),
230
- /* @__PURE__ */ p(x, {
237
+ /* @__PURE__ */ m(y, {
231
238
  variant: "ghost",
232
239
  size: "icon",
233
240
  className: "h-7 w-7 text-status-error-text",
234
241
  "aria-label": `Delete announcement ${e.title}`,
235
- onClick: () => H(e),
236
- children: /* @__PURE__ */ p(re, { className: "h-3.5 w-3.5" })
242
+ onClick: () => V(e),
243
+ children: /* @__PURE__ */ m(f, { className: "h-3.5 w-3.5" })
237
244
  })
238
245
  ]
239
246
  })]
240
- }), /* @__PURE__ */ p(w, {
247
+ }), /* @__PURE__ */ m(S, {
241
248
  className: "text-base",
242
249
  children: e.title
243
250
  })]
244
- }), /* @__PURE__ */ m(S, {
251
+ }), /* @__PURE__ */ h(b, {
245
252
  className: "pt-0",
246
253
  children: [
247
- /* @__PURE__ */ p("p", {
254
+ /* @__PURE__ */ m("p", {
248
255
  className: "text-sm text-text-secondary",
249
256
  children: e.content
250
257
  }),
251
- e.tags.length > 0 && /* @__PURE__ */ p("div", {
258
+ e.tags.length > 0 && /* @__PURE__ */ m("div", {
252
259
  className: "mt-3 flex flex-wrap gap-1",
253
- children: e.tags.map((e) => /* @__PURE__ */ p(b, {
260
+ children: e.tags.map((e) => /* @__PURE__ */ m(v, {
254
261
  variant: "outline",
255
262
  className: "text-[9px]",
256
263
  children: e
257
264
  }, e))
258
265
  }),
259
- /* @__PURE__ */ m("div", {
266
+ /* @__PURE__ */ h("div", {
260
267
  className: "mt-3 flex items-center gap-1 text-xs text-text-muted",
261
268
  children: [
262
- /* @__PURE__ */ p(s, { className: "h-3 w-3" }),
269
+ /* @__PURE__ */ m(te, { className: "h-3 w-3" }),
263
270
  e.viewCount,
264
271
  " read"
265
272
  ]
@@ -267,146 +274,146 @@ function I() {
267
274
  ]
268
275
  })]
269
276
  }, e.id);
270
- return /* @__PURE__ */ m("div", {
277
+ return /* @__PURE__ */ h("div", {
271
278
  className: "space-y-6 p-6",
272
279
  children: [
273
- /* @__PURE__ */ m("div", {
280
+ /* @__PURE__ */ h("div", {
274
281
  className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
275
- children: [/* @__PURE__ */ m("div", { children: [
276
- /* @__PURE__ */ p("h1", {
282
+ children: [/* @__PURE__ */ h("div", { children: [
283
+ /* @__PURE__ */ m("h1", {
277
284
  className: "text-2xl font-semibold",
278
- children: /* @__PURE__ */ p(ue, { children: "Announcements" })
285
+ children: /* @__PURE__ */ m(C, { children: "Announcements" })
279
286
  }),
280
- /* @__PURE__ */ m("p", {
287
+ /* @__PURE__ */ h("p", {
281
288
  className: "text-sm text-text-secondary",
282
289
  children: [O.length, " company announcements"]
283
290
  }),
284
- /* @__PURE__ */ p(E, {
291
+ /* @__PURE__ */ m(E, {
285
292
  className: "mt-1",
286
293
  children: "Broadcast company-wide news and updates so everyone stays informed — post announcements here when you have something the whole team needs to see."
287
294
  })
288
- ] }), /* @__PURE__ */ m(x, {
295
+ ] }), /* @__PURE__ */ h(y, {
289
296
  size: "sm",
290
- onClick: () => B.openModal(),
291
- children: [/* @__PURE__ */ p(f, { className: "h-4 w-4 mr-1" }), "New Announcement"]
297
+ onClick: () => z.openModal(),
298
+ children: [/* @__PURE__ */ m(l, { className: "h-4 w-4 mr-1" }), "New Announcement"]
292
299
  })]
293
300
  }),
294
- /* @__PURE__ */ m("div", {
301
+ /* @__PURE__ */ h("div", {
295
302
  className: "relative max-w-md",
296
- children: [/* @__PURE__ */ p(te, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ p(T, {
303
+ children: [/* @__PURE__ */ m(u, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ m(T, {
297
304
  placeholder: "Search announcements...",
298
305
  className: "pl-9",
299
- value: G,
300
- onChange: (e) => fe(e.target.value)
306
+ value: W,
307
+ onChange: (e) => me(e.target.value)
301
308
  })]
302
309
  }),
303
- /* @__PURE__ */ m("div", {
310
+ /* @__PURE__ */ h("div", {
304
311
  className: "grid gap-6 lg:grid-cols-3",
305
- children: [/* @__PURE__ */ m("div", {
312
+ children: [/* @__PURE__ */ h("div", {
306
313
  className: "space-y-4 lg:col-span-2",
307
314
  children: [
308
- Y.length === 0 && /* @__PURE__ */ p(de, {
315
+ J.length === 0 && /* @__PURE__ */ m(w, {
309
316
  illustration: "empty-notifications",
310
- title: J ? "No announcements match" : "No announcements yet",
311
- description: J ? "Try a different search term." : "Post an announcement to share news with the whole team."
317
+ title: q ? "No announcements match" : "No announcements yet",
318
+ description: q ? "Try a different search term." : "Post an announcement to share news with the whole team."
312
319
  }),
313
- X.length > 0 && /* @__PURE__ */ m("div", {
320
+ Y.length > 0 && /* @__PURE__ */ h("div", {
314
321
  className: "space-y-3",
315
- children: [/* @__PURE__ */ m("h2", {
322
+ children: [/* @__PURE__ */ h("h2", {
316
323
  className: "flex items-center gap-1 text-sm font-medium",
317
- children: [/* @__PURE__ */ p(u, { className: "h-4 w-4" }), "Pinned"]
318
- }), X.map((e) => $(e, !0))]
324
+ children: [/* @__PURE__ */ m(c, { className: "h-4 w-4" }), "Pinned"]
325
+ }), Y.map((e) => $(e, !0))]
319
326
  }),
320
- Z.length > 0 && /* @__PURE__ */ p("div", {
327
+ X.length > 0 && /* @__PURE__ */ m("div", {
321
328
  className: "space-y-3",
322
- children: Z.map((e) => $(e, !1))
329
+ children: X.map((e) => $(e, !1))
323
330
  })
324
331
  ]
325
- }), /* @__PURE__ */ p("div", {
332
+ }), /* @__PURE__ */ m("div", {
326
333
  className: "lg:col-span-1",
327
- children: /* @__PURE__ */ m(ce, {
334
+ children: /* @__PURE__ */ h(de, {
328
335
  className: "lg:sticky lg:top-6",
329
- children: [/* @__PURE__ */ m(C, {
336
+ children: [/* @__PURE__ */ h(x, {
330
337
  className: "flex flex-row items-center justify-between space-y-0 pb-3",
331
- children: [/* @__PURE__ */ p(w, {
338
+ children: [/* @__PURE__ */ m(S, {
332
339
  className: "text-base",
333
340
  children: "Conversations"
334
- }), /* @__PURE__ */ m(x, {
341
+ }), /* @__PURE__ */ h(y, {
335
342
  variant: "ghost",
336
343
  size: "sm",
337
- onClick: Q,
338
- children: [/* @__PURE__ */ p(c, { className: "mr-1 h-3.5 w-3.5" }), "Open"]
344
+ onClick: Z,
345
+ children: [/* @__PURE__ */ m(ne, { className: "mr-1 h-3.5 w-3.5" }), "Open"]
339
346
  })]
340
- }), /* @__PURE__ */ m(S, {
347
+ }), /* @__PURE__ */ h(b, {
341
348
  className: "space-y-1",
342
- children: [q.length === 0 ? /* @__PURE__ */ p("p", {
349
+ children: [K.length === 0 ? /* @__PURE__ */ m("p", {
343
350
  className: "py-6 text-center text-xs text-text-muted",
344
351
  children: "No active conversations yet. Team channels will appear here as they get activity."
345
- }) : q.map((e) => /* @__PURE__ */ m("button", {
352
+ }) : K.map((e) => /* @__PURE__ */ h("button", {
346
353
  type: "button",
347
- onClick: Q,
354
+ onClick: Z,
348
355
  className: "flex w-full items-start gap-3 rounded-[var(--radius-card)] p-2 text-left transition-colors hover:bg-bg-sunken",
349
356
  children: [
350
- /* @__PURE__ */ p(r, {
357
+ /* @__PURE__ */ m(r, {
351
358
  people: [{ name: e.title }],
352
359
  size: 32
353
360
  }),
354
- /* @__PURE__ */ m("div", {
361
+ /* @__PURE__ */ h("div", {
355
362
  className: "min-w-0 flex-1",
356
- children: [/* @__PURE__ */ m("div", {
363
+ children: [/* @__PURE__ */ h("div", {
357
364
  className: "flex items-center justify-between gap-2",
358
- children: [/* @__PURE__ */ p("p", {
365
+ children: [/* @__PURE__ */ m("p", {
359
366
  className: "truncate text-sm font-medium",
360
367
  children: e.title
361
- }), /* @__PURE__ */ p("span", {
368
+ }), /* @__PURE__ */ m("span", {
362
369
  className: "shrink-0 text-[10px] text-text-muted",
363
370
  children: F(e.createdAt)
364
371
  })]
365
- }), /* @__PURE__ */ p("p", {
372
+ }), /* @__PURE__ */ m("p", {
366
373
  className: "truncate text-xs text-text-secondary",
367
374
  children: e.message
368
375
  })]
369
376
  }),
370
- !e.read && /* @__PURE__ */ p("span", {
377
+ !e.read && /* @__PURE__ */ m("span", {
371
378
  className: "mt-1.5 h-2 w-2 shrink-0 rounded-full bg-status-success-text",
372
379
  "aria-label": "Unread"
373
380
  })
374
381
  ]
375
- }, e.id)), /* @__PURE__ */ m(x, {
382
+ }, e.id)), /* @__PURE__ */ h(y, {
376
383
  variant: "outline",
377
384
  size: "sm",
378
385
  className: "mt-3 w-full",
379
- onClick: Q,
380
- children: [/* @__PURE__ */ p(ne, { className: "mr-1 h-3.5 w-3.5" }), "Write a message in Conversations"]
386
+ onClick: Z,
387
+ children: [/* @__PURE__ */ m(d, { className: "mr-1 h-3.5 w-3.5" }), "Write a message in Conversations"]
381
388
  })]
382
389
  })]
383
390
  })
384
391
  })]
385
392
  }),
386
- /* @__PURE__ */ p(ee, {
387
- open: B.open,
388
- onOpenChange: B.onOpenChange,
389
- title: K ? "Edit Announcement" : "New Announcement",
390
- description: K ? "Update this announcement for the whole team." : "Share news and updates across the company.",
391
- fields: K ? P : N,
392
- initialValues: ge,
393
- submitLabel: K ? "Save changes" : "Publish",
394
- onSubmit: pe
393
+ /* @__PURE__ */ m(i, {
394
+ open: z.open,
395
+ onOpenChange: z.onOpenChange,
396
+ title: G ? "Edit Announcement" : "New Announcement",
397
+ description: G ? "Update this announcement for the whole team." : "Share news and updates across the company.",
398
+ fields: G ? P : N,
399
+ initialValues: Q,
400
+ submitLabel: G ? "Save changes" : "Publish",
401
+ onSubmit: he
395
402
  }),
396
- /* @__PURE__ */ p(h, {
397
- open: V !== null,
403
+ /* @__PURE__ */ m(g, {
404
+ open: B !== null,
398
405
  onOpenChange: (e) => {
399
- e || H(null);
406
+ e || V(null);
400
407
  },
401
- children: /* @__PURE__ */ m(ae, { children: [/* @__PURE__ */ m(v, { children: [/* @__PURE__ */ p(y, { children: "Delete announcement?" }), /* @__PURE__ */ p(oe, { children: V ? `"${V.title}" will be permanently removed. This cannot be undone.` : "" })] }), /* @__PURE__ */ m(se, { children: [/* @__PURE__ */ p(_, {
402
- disabled: U,
408
+ children: /* @__PURE__ */ h(oe, { children: [/* @__PURE__ */ h(le, { children: [/* @__PURE__ */ m(ue, { children: "Delete announcement?" }), /* @__PURE__ */ m(se, { children: B ? `"${B.title}" will be permanently removed. This cannot be undone.` : "" })] }), /* @__PURE__ */ h(ce, { children: [/* @__PURE__ */ m(ae, {
409
+ disabled: H,
403
410
  children: "Cancel"
404
- }), /* @__PURE__ */ p(g, {
411
+ }), /* @__PURE__ */ m(_, {
405
412
  onClick: (e) => {
406
- e.preventDefault(), he();
413
+ e.preventDefault(), _e();
407
414
  },
408
- disabled: U,
409
- children: U ? "Deleting…" : "Delete"
415
+ disabled: H,
416
+ children: H ? "Deleting…" : "Delete"
410
417
  })] })] })
411
418
  })
412
419
  ]