@burdenoff/microfe-crewfoundry 2026.704.3 → 2026.704.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crewfoundry/pages/AdminAdminPagePage.js +76 -75
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +118 -117
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +115 -114
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +105 -104
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +52 -51
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +94 -93
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +97 -96
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +68 -67
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +96 -95
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +153 -152
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +107 -106
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +77 -76
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +80 -79
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +102 -101
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +126 -125
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +64 -63
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +96 -95
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +127 -126
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +118 -117
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +123 -122
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +77 -76
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +49 -48
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +62 -61
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +72 -71
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +70 -69
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +57 -56
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +58 -57
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +122 -121
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +70 -69
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +41 -40
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +65 -64
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +75 -74
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +60 -59
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +53 -52
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +37 -36
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +126 -125
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +62 -61
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +50 -49
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +72 -71
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +40 -39
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +130 -129
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +60 -59
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +177 -146
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/crewfoundry/utils/formatEnumLabel.js +8 -0
- package/dist/crewfoundry/utils/formatEnumLabel.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
+
import { FormModal as n, useFormModal as r } from "../components/forms/FormModal.js";
|
|
4
|
+
import { useState as i } from "react";
|
|
5
|
+
import { Eye as a, Pencil as o, Pin as s, Plus as c, Trash2 as l } from "lucide-react";
|
|
6
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
7
|
+
import { AlertDialog as f, AlertDialogAction as p, AlertDialogCancel as m, AlertDialogContent as h, AlertDialogDescription as g, AlertDialogFooter as _, AlertDialogHeader as v, AlertDialogTitle as y, Badge as b, Button as x, Card as S, CardContent as C, CardHeader as w, CardTitle as T, GlassCard as E, GradientText as D, IllustratedEmptyState as O, PagePurpose as k } from "@burdenoff/fe-libs/ui";
|
|
8
|
+
import { useGlobalUi as A } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
8
9
|
//#region src/crewfoundry/pages/CommunicationsAnnouncementsPagePage.tsx
|
|
9
|
-
var
|
|
10
|
+
var j = [
|
|
10
11
|
{
|
|
11
12
|
name: "title",
|
|
12
13
|
label: "Title",
|
|
@@ -98,22 +99,22 @@ var A = [
|
|
|
98
99
|
label: "Pin to top",
|
|
99
100
|
type: "switch"
|
|
100
101
|
}
|
|
101
|
-
],
|
|
102
|
-
function
|
|
103
|
-
let { announcements:
|
|
102
|
+
], M = j.filter((e) => e.name !== "author" && e.name !== "authorRole");
|
|
103
|
+
function N() {
|
|
104
|
+
let { announcements: N, addAnnouncement: P, updateAnnouncement: F, removeAnnouncement: I } = e(), { showToast: L } = A(), R = r(), [z, B] = i(null), [V, H] = i(!1), U = R.context, W = N.filter((e) => e.isPinned), G = N.filter((e) => !e.isPinned), K = async (e) => {
|
|
104
105
|
let t = Array.isArray(e.tags) ? e.tags : [];
|
|
105
|
-
if (
|
|
106
|
-
await
|
|
106
|
+
if (U) {
|
|
107
|
+
await F(U.id, {
|
|
107
108
|
title: String(e.title),
|
|
108
109
|
content: String(e.content),
|
|
109
110
|
category: String(e.category),
|
|
110
111
|
priority: String(e.priority),
|
|
111
112
|
isPinned: !!e.isPinned,
|
|
112
113
|
tags: t
|
|
113
|
-
}),
|
|
114
|
+
}), L("Announcement updated", "success");
|
|
114
115
|
return;
|
|
115
116
|
}
|
|
116
|
-
await
|
|
117
|
+
await P({
|
|
117
118
|
id: crypto.randomUUID(),
|
|
118
119
|
title: String(e.title),
|
|
119
120
|
content: String(e.content),
|
|
@@ -125,163 +126,163 @@ function M() {
|
|
|
125
126
|
createdAt: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
126
127
|
viewCount: 0,
|
|
127
128
|
tags: t
|
|
128
|
-
}),
|
|
129
|
-
},
|
|
130
|
-
if (
|
|
131
|
-
|
|
129
|
+
}), L("Announcement published", "success");
|
|
130
|
+
}, q = async () => {
|
|
131
|
+
if (z) {
|
|
132
|
+
H(!0);
|
|
132
133
|
try {
|
|
133
|
-
await
|
|
134
|
+
await I(z.id), L("Announcement deleted", "success"), B(null);
|
|
134
135
|
} catch (e) {
|
|
135
|
-
|
|
136
|
+
L(e instanceof Error ? e.message : "Unable to delete announcement", "error");
|
|
136
137
|
} finally {
|
|
137
|
-
|
|
138
|
+
H(!1);
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
|
-
},
|
|
141
|
-
title:
|
|
142
|
-
content:
|
|
143
|
-
category:
|
|
144
|
-
priority:
|
|
145
|
-
tags:
|
|
146
|
-
isPinned:
|
|
147
|
-
} : void 0,
|
|
141
|
+
}, J = U ? {
|
|
142
|
+
title: U.title,
|
|
143
|
+
content: U.content,
|
|
144
|
+
category: U.category,
|
|
145
|
+
priority: U.priority,
|
|
146
|
+
tags: U.tags,
|
|
147
|
+
isPinned: U.isPinned
|
|
148
|
+
} : void 0, Y = (e) => /* @__PURE__ */ d("div", {
|
|
148
149
|
className: "flex gap-1",
|
|
149
|
-
children: [/* @__PURE__ */
|
|
150
|
+
children: [/* @__PURE__ */ u(x, {
|
|
150
151
|
variant: "ghost",
|
|
151
152
|
size: "icon",
|
|
152
153
|
className: "h-7 w-7",
|
|
153
154
|
"aria-label": `Edit announcement ${e.title}`,
|
|
154
|
-
onClick: () =>
|
|
155
|
-
children: /* @__PURE__ */
|
|
156
|
-
}), /* @__PURE__ */
|
|
155
|
+
onClick: () => R.openModal(e),
|
|
156
|
+
children: /* @__PURE__ */ u(o, { className: "h-3.5 w-3.5" })
|
|
157
|
+
}), /* @__PURE__ */ u(x, {
|
|
157
158
|
variant: "ghost",
|
|
158
159
|
size: "icon",
|
|
159
160
|
className: "h-7 w-7 text-status-error-text",
|
|
160
161
|
"aria-label": `Delete announcement ${e.title}`,
|
|
161
|
-
onClick: () =>
|
|
162
|
-
children: /* @__PURE__ */ l
|
|
162
|
+
onClick: () => B(e),
|
|
163
|
+
children: /* @__PURE__ */ u(l, { className: "h-3.5 w-3.5" })
|
|
163
164
|
})]
|
|
164
165
|
});
|
|
165
|
-
return /* @__PURE__ */
|
|
166
|
+
return /* @__PURE__ */ d("div", {
|
|
166
167
|
className: "space-y-6 p-6",
|
|
167
168
|
children: [
|
|
168
|
-
/* @__PURE__ */
|
|
169
|
+
/* @__PURE__ */ d("div", {
|
|
169
170
|
className: "flex items-center justify-between",
|
|
170
|
-
children: [/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
171
|
+
children: [/* @__PURE__ */ d("div", { children: [
|
|
172
|
+
/* @__PURE__ */ u("h1", {
|
|
172
173
|
className: "text-2xl font-semibold",
|
|
173
|
-
children: /* @__PURE__ */
|
|
174
|
+
children: /* @__PURE__ */ u(D, { children: "Announcements" })
|
|
174
175
|
}),
|
|
175
|
-
/* @__PURE__ */
|
|
176
|
+
/* @__PURE__ */ d("p", {
|
|
176
177
|
className: "text-sm text-text-secondary",
|
|
177
|
-
children: [
|
|
178
|
+
children: [N.length, " company announcements"]
|
|
178
179
|
}),
|
|
179
|
-
/* @__PURE__ */
|
|
180
|
+
/* @__PURE__ */ u(k, {
|
|
180
181
|
className: "mt-1",
|
|
181
182
|
children: "Broadcast company-wide news and updates so everyone stays informed — post announcements here when you have something the whole team needs to see."
|
|
182
183
|
})
|
|
183
|
-
] }), /* @__PURE__ */
|
|
184
|
+
] }), /* @__PURE__ */ d(x, {
|
|
184
185
|
size: "sm",
|
|
185
|
-
onClick: () =>
|
|
186
|
-
children: [/* @__PURE__ */
|
|
186
|
+
onClick: () => R.openModal(),
|
|
187
|
+
children: [/* @__PURE__ */ u(c, { className: "h-4 w-4 mr-1" }), "New Announcement"]
|
|
187
188
|
})]
|
|
188
189
|
}),
|
|
189
|
-
|
|
190
|
+
W.length > 0 && /* @__PURE__ */ d("div", {
|
|
190
191
|
className: "space-y-3",
|
|
191
|
-
children: [/* @__PURE__ */
|
|
192
|
+
children: [/* @__PURE__ */ d("h2", {
|
|
192
193
|
className: "text-sm font-medium flex items-center gap-1",
|
|
193
|
-
children: [/* @__PURE__ */
|
|
194
|
-
}),
|
|
194
|
+
children: [/* @__PURE__ */ u(s, { className: "h-4 w-4" }), "Pinned"]
|
|
195
|
+
}), W.map((e) => /* @__PURE__ */ d(E, {
|
|
195
196
|
treatment: "glass",
|
|
196
197
|
glow: !0,
|
|
197
|
-
children: [/* @__PURE__ */
|
|
198
|
+
children: [/* @__PURE__ */ u(w, { children: /* @__PURE__ */ d("div", {
|
|
198
199
|
className: "flex items-center justify-between",
|
|
199
|
-
children: [/* @__PURE__ */
|
|
200
|
+
children: [/* @__PURE__ */ u(T, {
|
|
200
201
|
className: "text-base",
|
|
201
202
|
children: e.title
|
|
202
|
-
}), /* @__PURE__ */
|
|
203
|
+
}), /* @__PURE__ */ d("div", {
|
|
203
204
|
className: "flex items-center gap-2",
|
|
204
|
-
children: [/* @__PURE__ */
|
|
205
|
+
children: [/* @__PURE__ */ d("div", {
|
|
205
206
|
className: "flex gap-1",
|
|
206
|
-
children: [/* @__PURE__ */
|
|
207
|
+
children: [/* @__PURE__ */ u(b, {
|
|
207
208
|
variant: e.priority === "urgent" ? "destructive" : e.priority === "high" ? "default" : "secondary",
|
|
208
209
|
className: "text-[10px]",
|
|
209
|
-
children: e.priority
|
|
210
|
-
}), /* @__PURE__ */
|
|
210
|
+
children: t(e.priority)
|
|
211
|
+
}), /* @__PURE__ */ u(b, {
|
|
211
212
|
variant: "outline",
|
|
212
213
|
className: "text-[10px]",
|
|
213
214
|
children: e.category
|
|
214
215
|
})]
|
|
215
|
-
}),
|
|
216
|
+
}), Y(e)]
|
|
216
217
|
})]
|
|
217
|
-
}) }), /* @__PURE__ */
|
|
218
|
+
}) }), /* @__PURE__ */ d(C, { children: [/* @__PURE__ */ u("p", {
|
|
218
219
|
className: "text-sm text-text-secondary",
|
|
219
220
|
children: e.content
|
|
220
|
-
}), /* @__PURE__ */
|
|
221
|
+
}), /* @__PURE__ */ d("div", {
|
|
221
222
|
className: "flex items-center justify-between mt-3 text-xs text-text-secondary",
|
|
222
|
-
children: [/* @__PURE__ */
|
|
223
|
+
children: [/* @__PURE__ */ d("span", { children: [
|
|
223
224
|
e.author,
|
|
224
225
|
" · ",
|
|
225
226
|
e.authorRole
|
|
226
|
-
] }), /* @__PURE__ */
|
|
227
|
+
] }), /* @__PURE__ */ d("div", {
|
|
227
228
|
className: "flex items-center gap-3",
|
|
228
|
-
children: [/* @__PURE__ */
|
|
229
|
+
children: [/* @__PURE__ */ d("span", {
|
|
229
230
|
className: "flex items-center gap-1",
|
|
230
|
-
children: [/* @__PURE__ */
|
|
231
|
-
}), /* @__PURE__ */
|
|
231
|
+
children: [/* @__PURE__ */ u(a, { className: "h-3 w-3" }), e.viewCount]
|
|
232
|
+
}), /* @__PURE__ */ u("span", { children: e.createdAt })]
|
|
232
233
|
})]
|
|
233
234
|
})] })]
|
|
234
235
|
}, e.id))]
|
|
235
236
|
}),
|
|
236
|
-
|
|
237
|
+
N.length === 0 && /* @__PURE__ */ u(O, {
|
|
237
238
|
illustration: "empty-notifications",
|
|
238
239
|
title: "No announcements yet",
|
|
239
240
|
description: "Post an announcement to share news with the whole team."
|
|
240
241
|
}),
|
|
241
|
-
/* @__PURE__ */
|
|
242
|
+
/* @__PURE__ */ u("div", {
|
|
242
243
|
className: "space-y-3",
|
|
243
|
-
children:
|
|
244
|
+
children: G.map((e) => /* @__PURE__ */ d(S, { children: [/* @__PURE__ */ u(w, { children: /* @__PURE__ */ d("div", {
|
|
244
245
|
className: "flex items-center justify-between",
|
|
245
|
-
children: [/* @__PURE__ */
|
|
246
|
+
children: [/* @__PURE__ */ u(T, {
|
|
246
247
|
className: "text-base",
|
|
247
248
|
children: e.title
|
|
248
|
-
}), /* @__PURE__ */
|
|
249
|
+
}), /* @__PURE__ */ d("div", {
|
|
249
250
|
className: "flex items-center gap-2",
|
|
250
|
-
children: [/* @__PURE__ */
|
|
251
|
+
children: [/* @__PURE__ */ d("div", {
|
|
251
252
|
className: "flex gap-1",
|
|
252
|
-
children: [/* @__PURE__ */
|
|
253
|
+
children: [/* @__PURE__ */ u(b, {
|
|
253
254
|
variant: e.priority === "urgent" ? "destructive" : e.priority === "high" ? "default" : "secondary",
|
|
254
255
|
className: "text-[10px]",
|
|
255
|
-
children: e.priority
|
|
256
|
-
}), /* @__PURE__ */
|
|
256
|
+
children: t(e.priority)
|
|
257
|
+
}), /* @__PURE__ */ u(b, {
|
|
257
258
|
variant: "outline",
|
|
258
259
|
className: "text-[10px]",
|
|
259
260
|
children: e.category
|
|
260
261
|
})]
|
|
261
|
-
}),
|
|
262
|
+
}), Y(e)]
|
|
262
263
|
})]
|
|
263
|
-
}) }), /* @__PURE__ */
|
|
264
|
-
/* @__PURE__ */
|
|
264
|
+
}) }), /* @__PURE__ */ d(C, { children: [
|
|
265
|
+
/* @__PURE__ */ u("p", {
|
|
265
266
|
className: "text-sm text-text-secondary",
|
|
266
267
|
children: e.content
|
|
267
268
|
}),
|
|
268
|
-
/* @__PURE__ */
|
|
269
|
+
/* @__PURE__ */ d("div", {
|
|
269
270
|
className: "flex items-center justify-between mt-3 text-xs text-text-secondary",
|
|
270
|
-
children: [/* @__PURE__ */
|
|
271
|
+
children: [/* @__PURE__ */ d("span", { children: [
|
|
271
272
|
e.author,
|
|
272
273
|
" · ",
|
|
273
274
|
e.authorRole
|
|
274
|
-
] }), /* @__PURE__ */
|
|
275
|
+
] }), /* @__PURE__ */ d("div", {
|
|
275
276
|
className: "flex items-center gap-3",
|
|
276
|
-
children: [/* @__PURE__ */
|
|
277
|
+
children: [/* @__PURE__ */ d("span", {
|
|
277
278
|
className: "flex items-center gap-1",
|
|
278
|
-
children: [/* @__PURE__ */
|
|
279
|
-
}), /* @__PURE__ */
|
|
279
|
+
children: [/* @__PURE__ */ u(a, { className: "h-3 w-3" }), e.viewCount]
|
|
280
|
+
}), /* @__PURE__ */ u("span", { children: e.createdAt })]
|
|
280
281
|
})]
|
|
281
282
|
}),
|
|
282
|
-
/* @__PURE__ */
|
|
283
|
+
/* @__PURE__ */ u("div", {
|
|
283
284
|
className: "flex gap-1 mt-2",
|
|
284
|
-
children: e.tags.map((e) => /* @__PURE__ */
|
|
285
|
+
children: e.tags.map((e) => /* @__PURE__ */ u(b, {
|
|
285
286
|
variant: "outline",
|
|
286
287
|
className: "text-[9px]",
|
|
287
288
|
children: e
|
|
@@ -289,36 +290,36 @@ function M() {
|
|
|
289
290
|
})
|
|
290
291
|
] })] }, e.id))
|
|
291
292
|
}),
|
|
292
|
-
/* @__PURE__ */
|
|
293
|
-
open:
|
|
294
|
-
onOpenChange:
|
|
295
|
-
title:
|
|
296
|
-
description:
|
|
297
|
-
fields:
|
|
298
|
-
initialValues:
|
|
299
|
-
submitLabel:
|
|
300
|
-
onSubmit:
|
|
293
|
+
/* @__PURE__ */ u(n, {
|
|
294
|
+
open: R.open,
|
|
295
|
+
onOpenChange: R.onOpenChange,
|
|
296
|
+
title: U ? "Edit Announcement" : "New Announcement",
|
|
297
|
+
description: U ? "Update this announcement for the whole team." : "Share news and updates across the company.",
|
|
298
|
+
fields: U ? M : j,
|
|
299
|
+
initialValues: J,
|
|
300
|
+
submitLabel: U ? "Save changes" : "Publish",
|
|
301
|
+
onSubmit: K
|
|
301
302
|
}),
|
|
302
|
-
/* @__PURE__ */
|
|
303
|
-
open:
|
|
303
|
+
/* @__PURE__ */ u(f, {
|
|
304
|
+
open: z !== null,
|
|
304
305
|
onOpenChange: (e) => {
|
|
305
|
-
e ||
|
|
306
|
+
e || B(null);
|
|
306
307
|
},
|
|
307
|
-
children: /* @__PURE__ */
|
|
308
|
-
disabled:
|
|
308
|
+
children: /* @__PURE__ */ d(h, { children: [/* @__PURE__ */ d(v, { children: [/* @__PURE__ */ u(y, { children: "Delete announcement?" }), /* @__PURE__ */ u(g, { children: z ? `"${z.title}" will be permanently removed. This cannot be undone.` : "" })] }), /* @__PURE__ */ d(_, { children: [/* @__PURE__ */ u(m, {
|
|
309
|
+
disabled: V,
|
|
309
310
|
children: "Cancel"
|
|
310
|
-
}), /* @__PURE__ */
|
|
311
|
+
}), /* @__PURE__ */ u(p, {
|
|
311
312
|
onClick: (e) => {
|
|
312
|
-
e.preventDefault(),
|
|
313
|
+
e.preventDefault(), q();
|
|
313
314
|
},
|
|
314
|
-
disabled:
|
|
315
|
-
children:
|
|
315
|
+
disabled: V,
|
|
316
|
+
children: V ? "Deleting…" : "Delete"
|
|
316
317
|
})] })] })
|
|
317
318
|
})
|
|
318
319
|
]
|
|
319
320
|
});
|
|
320
321
|
}
|
|
321
322
|
//#endregion
|
|
322
|
-
export {
|
|
323
|
+
export { N as CommunicationsAnnouncementsPagePage };
|
|
323
324
|
|
|
324
325
|
//# sourceMappingURL=CommunicationsAnnouncementsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommunicationsAnnouncementsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsAnnouncementsPagePage.tsx"],"sourcesContent":["import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { Eye, Pencil, Pin, Plus, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\nimport { useCrewFoundryStore, type Announcement } from '../store/crewfoundryStore';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\n\nconst CATEGORY_OPTIONS = [\n { label: 'General', value: 'general' },\n { label: 'HR', value: 'hr' },\n { label: 'IT', value: 'it' },\n { label: 'Emergency', value: 'emergency' },\n { label: 'Event', value: 'event' },\n];\n\nconst PRIORITY_OPTIONS = [\n { label: 'Low', value: 'low' },\n { label: 'Medium', value: 'medium' },\n { label: 'High', value: 'high' },\n { label: 'Urgent', value: 'urgent' },\n];\n\nconst CREATE_FIELDS: FieldConfig[] = [\n { name: 'title', label: 'Title', type: 'text', required: true, colSpan: 2 },\n { name: 'content', label: 'Content', type: 'textarea', required: true, colSpan: 2 },\n { name: 'author', label: 'Author', type: 'text', required: true },\n { name: 'authorRole', label: 'Author Role', type: 'text', required: true },\n {\n name: 'category',\n label: 'Category',\n type: 'select',\n required: true,\n options: CATEGORY_OPTIONS,\n placeholder: 'Select a category',\n },\n {\n name: 'priority',\n label: 'Priority',\n type: 'select',\n required: true,\n options: PRIORITY_OPTIONS,\n placeholder: 'Select a priority',\n },\n { name: 'tags', label: 'Tags', type: 'tags', placeholder: 'Add a tag and press Enter' },\n { name: 'isPinned', label: 'Pin to top', type: 'switch' },\n];\n\n// Author/role are immutable after creation (they are not part of the update\n// input), so the edit form omits them.\nconst EDIT_FIELDS: FieldConfig[] = CREATE_FIELDS.filter(\n (field) => field.name !== 'author' && field.name !== 'authorRole'\n);\n\nexport function CommunicationsAnnouncementsPagePage() {\n const { announcements, addAnnouncement, updateAnnouncement, removeAnnouncement } =\n useCrewFoundryStore();\n const { showToast } = useGlobalUi();\n const form = useFormModal<Announcement>();\n const [deleteTarget, setDeleteTarget] = useState<Announcement | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const editing = form.context;\n const pinned = announcements.filter((a) => a.isPinned);\n const regular = announcements.filter((a) => !a.isPinned);\n\n const handleSubmit = async (values: FormValues) => {\n const tags = Array.isArray(values.tags) ? values.tags : [];\n if (editing) {\n await updateAnnouncement(editing.id, {\n title: String(values.title),\n content: String(values.content),\n category: String(values.category) as Announcement['category'],\n priority: String(values.priority) as Announcement['priority'],\n isPinned: Boolean(values.isPinned),\n tags,\n });\n showToast('Announcement updated', 'success');\n return;\n }\n await addAnnouncement({\n id: crypto.randomUUID(),\n title: String(values.title),\n content: String(values.content),\n author: String(values.author),\n authorRole: String(values.authorRole),\n category: String(values.category) as Announcement['category'],\n priority: String(values.priority) as Announcement['priority'],\n isPinned: Boolean(values.isPinned),\n createdAt: new Date().toISOString().slice(0, 10),\n viewCount: 0,\n tags,\n });\n showToast('Announcement published', 'success');\n };\n\n const confirmDelete = async () => {\n if (!deleteTarget) {\n return;\n }\n setDeleting(true);\n try {\n await removeAnnouncement(deleteTarget.id);\n showToast('Announcement deleted', 'success');\n setDeleteTarget(null);\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to delete announcement', 'error');\n } finally {\n setDeleting(false);\n }\n };\n\n const initialValues: FormValues | undefined = editing\n ? {\n title: editing.title,\n content: editing.content,\n category: editing.category,\n priority: editing.priority,\n tags: editing.tags,\n isPinned: editing.isPinned,\n }\n : undefined;\n\n const renderActions = (announcement: Announcement) => (\n <div className=\"flex gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n aria-label={`Edit announcement ${announcement.title}`}\n onClick={() => form.openModal(announcement)}\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-status-error-text\"\n aria-label={`Delete announcement ${announcement.title}`}\n onClick={() => setDeleteTarget(announcement)}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Announcements</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {announcements.length} company announcements\n </p>\n <PagePurpose className=\"mt-1\">\n Broadcast company-wide news and updates so everyone stays informed — post announcements\n here when you have something the whole team needs to see.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => form.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n New Announcement\n </Button>\n </div>\n {pinned.length > 0 && (\n <div className=\"space-y-3\">\n <h2 className=\"text-sm font-medium flex items-center gap-1\">\n <Pin className=\"h-4 w-4\" />\n Pinned\n </h2>\n {pinned.map((ann) => (\n <GlassCard key={ann.id} treatment=\"glass\" glow>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{ann.title}</CardTitle>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-1\">\n <Badge\n variant={\n ann.priority === 'urgent'\n ? 'destructive'\n : ann.priority === 'high'\n ? 'default'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {ann.priority}\n </Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {ann.category}\n </Badge>\n </div>\n {renderActions(ann)}\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary\">{ann.content}</p>\n <div className=\"flex items-center justify-between mt-3 text-xs text-text-secondary\">\n <span>\n {ann.author} · {ann.authorRole}\n </span>\n <div className=\"flex items-center gap-3\">\n <span className=\"flex items-center gap-1\">\n <Eye className=\"h-3 w-3\" />\n {ann.viewCount}\n </span>\n <span>{ann.createdAt}</span>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n ))}\n </div>\n )}\n {announcements.length === 0 && (\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title=\"No announcements yet\"\n description=\"Post an announcement to share news with the whole team.\"\n />\n )}\n <div className=\"space-y-3\">\n {regular.map((ann) => (\n <Card key={ann.id}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{ann.title}</CardTitle>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-1\">\n <Badge\n variant={\n ann.priority === 'urgent'\n ? 'destructive'\n : ann.priority === 'high'\n ? 'default'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {ann.priority}\n </Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {ann.category}\n </Badge>\n </div>\n {renderActions(ann)}\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary\">{ann.content}</p>\n <div className=\"flex items-center justify-between mt-3 text-xs text-text-secondary\">\n <span>\n {ann.author} · {ann.authorRole}\n </span>\n <div className=\"flex items-center gap-3\">\n <span className=\"flex items-center gap-1\">\n <Eye className=\"h-3 w-3\" />\n {ann.viewCount}\n </span>\n <span>{ann.createdAt}</span>\n </div>\n </div>\n <div className=\"flex gap-1 mt-2\">\n {ann.tags.map((t) => (\n <Badge key={t} variant=\"outline\" className=\"text-[9px]\">\n {t}\n </Badge>\n ))}\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <FormModal\n open={form.open}\n onOpenChange={form.onOpenChange}\n title={editing ? 'Edit Announcement' : 'New Announcement'}\n description={\n editing\n ? 'Update this announcement for the whole team.'\n : 'Share news and updates across the company.'\n }\n fields={editing ? EDIT_FIELDS : CREATE_FIELDS}\n initialValues={initialValues}\n submitLabel={editing ? 'Save changes' : 'Publish'}\n onSubmit={handleSubmit}\n />\n\n <AlertDialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open) {\n setDeleteTarget(null);\n }\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete announcement?</AlertDialogTitle>\n <AlertDialogDescription>\n {deleteTarget\n ? `\"${deleteTarget.title}\" will be permanently removed. This cannot be undone.`\n : ''}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deleting}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(event) => {\n event.preventDefault();\n void confirmDelete();\n }}\n disabled={deleting}\n >\n {deleting ? 'Deleting…' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CommunicationsAnnouncementsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsAnnouncementsPagePage.tsx"],"sourcesContent":["import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { Eye, Pencil, Pin, Plus, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\nimport { useCrewFoundryStore, type Announcement } from '../store/crewfoundryStore';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst CATEGORY_OPTIONS = [\n { label: 'General', value: 'general' },\n { label: 'HR', value: 'hr' },\n { label: 'IT', value: 'it' },\n { label: 'Emergency', value: 'emergency' },\n { label: 'Event', value: 'event' },\n];\n\nconst PRIORITY_OPTIONS = [\n { label: 'Low', value: 'low' },\n { label: 'Medium', value: 'medium' },\n { label: 'High', value: 'high' },\n { label: 'Urgent', value: 'urgent' },\n];\n\nconst CREATE_FIELDS: FieldConfig[] = [\n { name: 'title', label: 'Title', type: 'text', required: true, colSpan: 2 },\n { name: 'content', label: 'Content', type: 'textarea', required: true, colSpan: 2 },\n { name: 'author', label: 'Author', type: 'text', required: true },\n { name: 'authorRole', label: 'Author Role', type: 'text', required: true },\n {\n name: 'category',\n label: 'Category',\n type: 'select',\n required: true,\n options: CATEGORY_OPTIONS,\n placeholder: 'Select a category',\n },\n {\n name: 'priority',\n label: 'Priority',\n type: 'select',\n required: true,\n options: PRIORITY_OPTIONS,\n placeholder: 'Select a priority',\n },\n { name: 'tags', label: 'Tags', type: 'tags', placeholder: 'Add a tag and press Enter' },\n { name: 'isPinned', label: 'Pin to top', type: 'switch' },\n];\n\n// Author/role are immutable after creation (they are not part of the update\n// input), so the edit form omits them.\nconst EDIT_FIELDS: FieldConfig[] = CREATE_FIELDS.filter(\n (field) => field.name !== 'author' && field.name !== 'authorRole'\n);\n\nexport function CommunicationsAnnouncementsPagePage() {\n const { announcements, addAnnouncement, updateAnnouncement, removeAnnouncement } =\n useCrewFoundryStore();\n const { showToast } = useGlobalUi();\n const form = useFormModal<Announcement>();\n const [deleteTarget, setDeleteTarget] = useState<Announcement | null>(null);\n const [deleting, setDeleting] = useState(false);\n\n const editing = form.context;\n const pinned = announcements.filter((a) => a.isPinned);\n const regular = announcements.filter((a) => !a.isPinned);\n\n const handleSubmit = async (values: FormValues) => {\n const tags = Array.isArray(values.tags) ? values.tags : [];\n if (editing) {\n await updateAnnouncement(editing.id, {\n title: String(values.title),\n content: String(values.content),\n category: String(values.category) as Announcement['category'],\n priority: String(values.priority) as Announcement['priority'],\n isPinned: Boolean(values.isPinned),\n tags,\n });\n showToast('Announcement updated', 'success');\n return;\n }\n await addAnnouncement({\n id: crypto.randomUUID(),\n title: String(values.title),\n content: String(values.content),\n author: String(values.author),\n authorRole: String(values.authorRole),\n category: String(values.category) as Announcement['category'],\n priority: String(values.priority) as Announcement['priority'],\n isPinned: Boolean(values.isPinned),\n createdAt: new Date().toISOString().slice(0, 10),\n viewCount: 0,\n tags,\n });\n showToast('Announcement published', 'success');\n };\n\n const confirmDelete = async () => {\n if (!deleteTarget) {\n return;\n }\n setDeleting(true);\n try {\n await removeAnnouncement(deleteTarget.id);\n showToast('Announcement deleted', 'success');\n setDeleteTarget(null);\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to delete announcement', 'error');\n } finally {\n setDeleting(false);\n }\n };\n\n const initialValues: FormValues | undefined = editing\n ? {\n title: editing.title,\n content: editing.content,\n category: editing.category,\n priority: editing.priority,\n tags: editing.tags,\n isPinned: editing.isPinned,\n }\n : undefined;\n\n const renderActions = (announcement: Announcement) => (\n <div className=\"flex gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n aria-label={`Edit announcement ${announcement.title}`}\n onClick={() => form.openModal(announcement)}\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-status-error-text\"\n aria-label={`Delete announcement ${announcement.title}`}\n onClick={() => setDeleteTarget(announcement)}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Announcements</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {announcements.length} company announcements\n </p>\n <PagePurpose className=\"mt-1\">\n Broadcast company-wide news and updates so everyone stays informed — post announcements\n here when you have something the whole team needs to see.\n </PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => form.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n New Announcement\n </Button>\n </div>\n {pinned.length > 0 && (\n <div className=\"space-y-3\">\n <h2 className=\"text-sm font-medium flex items-center gap-1\">\n <Pin className=\"h-4 w-4\" />\n Pinned\n </h2>\n {pinned.map((ann) => (\n <GlassCard key={ann.id} treatment=\"glass\" glow>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{ann.title}</CardTitle>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-1\">\n <Badge\n variant={\n ann.priority === 'urgent'\n ? 'destructive'\n : ann.priority === 'high'\n ? 'default'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {formatEnumLabel(ann.priority)}\n </Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {ann.category}\n </Badge>\n </div>\n {renderActions(ann)}\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary\">{ann.content}</p>\n <div className=\"flex items-center justify-between mt-3 text-xs text-text-secondary\">\n <span>\n {ann.author} · {ann.authorRole}\n </span>\n <div className=\"flex items-center gap-3\">\n <span className=\"flex items-center gap-1\">\n <Eye className=\"h-3 w-3\" />\n {ann.viewCount}\n </span>\n <span>{ann.createdAt}</span>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n ))}\n </div>\n )}\n {announcements.length === 0 && (\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title=\"No announcements yet\"\n description=\"Post an announcement to share news with the whole team.\"\n />\n )}\n <div className=\"space-y-3\">\n {regular.map((ann) => (\n <Card key={ann.id}>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{ann.title}</CardTitle>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-1\">\n <Badge\n variant={\n ann.priority === 'urgent'\n ? 'destructive'\n : ann.priority === 'high'\n ? 'default'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {formatEnumLabel(ann.priority)}\n </Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {ann.category}\n </Badge>\n </div>\n {renderActions(ann)}\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary\">{ann.content}</p>\n <div className=\"flex items-center justify-between mt-3 text-xs text-text-secondary\">\n <span>\n {ann.author} · {ann.authorRole}\n </span>\n <div className=\"flex items-center gap-3\">\n <span className=\"flex items-center gap-1\">\n <Eye className=\"h-3 w-3\" />\n {ann.viewCount}\n </span>\n <span>{ann.createdAt}</span>\n </div>\n </div>\n <div className=\"flex gap-1 mt-2\">\n {ann.tags.map((t) => (\n <Badge key={t} variant=\"outline\" className=\"text-[9px]\">\n {t}\n </Badge>\n ))}\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <FormModal\n open={form.open}\n onOpenChange={form.onOpenChange}\n title={editing ? 'Edit Announcement' : 'New Announcement'}\n description={\n editing\n ? 'Update this announcement for the whole team.'\n : 'Share news and updates across the company.'\n }\n fields={editing ? EDIT_FIELDS : CREATE_FIELDS}\n initialValues={initialValues}\n submitLabel={editing ? 'Save changes' : 'Publish'}\n onSubmit={handleSubmit}\n />\n\n <AlertDialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open) {\n setDeleteTarget(null);\n }\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete announcement?</AlertDialogTitle>\n <AlertDialogDescription>\n {deleteTarget\n ? `\"${deleteTarget.title}\" will be permanently removed. This cannot be undone.`\n : ''}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deleting}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(event) => {\n event.preventDefault();\n void confirmDelete();\n }}\n disabled={deleting}\n >\n {deleting ? 'Deleting…' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
+
import { FormModal as n, useFormModal as r } from "../components/forms/FormModal.js";
|
|
4
|
+
import { FolderKanban as i, Plus as a, Users as o } from "lucide-react";
|
|
5
|
+
import { useNavigate as s } from "react-router-dom";
|
|
6
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
7
|
+
import { Badge as u, Button as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, GlassCard as g, GradientText as _, IllustratedEmptyState as v, PagePurpose as y, Pagination as b } from "@burdenoff/fe-libs/ui";
|
|
8
|
+
import { usePagination as x } from "@burdenoff/fe-libs/shared/hooks";
|
|
8
9
|
//#region src/crewfoundry/pages/CommunicationsTeamsPagePage.tsx
|
|
9
|
-
var
|
|
10
|
+
var S = [
|
|
10
11
|
{
|
|
11
12
|
name: "name",
|
|
12
13
|
label: "Channel Name",
|
|
@@ -44,104 +45,104 @@ var x = [
|
|
|
44
45
|
colSpan: 2
|
|
45
46
|
}
|
|
46
47
|
];
|
|
47
|
-
function
|
|
48
|
-
let
|
|
49
|
-
return /* @__PURE__ */
|
|
48
|
+
function C() {
|
|
49
|
+
let C = s(), { teams: w } = e(), T = e((e) => e.addTeam), E = r(), { page: D, pageSize: O, setPage: k } = x({ initialPageSize: 12 }), A = w.slice((D - 1) * O, (D - 1) * O + O), j = (e) => C(`../../teams/team-detail-page?id=${encodeURIComponent(e.id)}`);
|
|
50
|
+
return /* @__PURE__ */ l("div", {
|
|
50
51
|
className: "space-y-6 p-6",
|
|
51
52
|
children: [
|
|
52
|
-
/* @__PURE__ */
|
|
53
|
+
/* @__PURE__ */ l("div", {
|
|
53
54
|
className: "flex items-start justify-between gap-4",
|
|
54
|
-
children: [/* @__PURE__ */
|
|
55
|
-
/* @__PURE__ */
|
|
55
|
+
children: [/* @__PURE__ */ l("div", { children: [
|
|
56
|
+
/* @__PURE__ */ c("h1", {
|
|
56
57
|
className: "text-2xl font-semibold",
|
|
57
|
-
children: /* @__PURE__ */
|
|
58
|
+
children: /* @__PURE__ */ c(_, { children: "Team Channels" })
|
|
58
59
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ l("p", {
|
|
60
61
|
className: "text-sm text-text-secondary",
|
|
61
|
-
children: [
|
|
62
|
+
children: [w.length, " active team channels"]
|
|
62
63
|
}),
|
|
63
|
-
/* @__PURE__ */
|
|
64
|
+
/* @__PURE__ */ c(y, {
|
|
64
65
|
className: "mt-1",
|
|
65
66
|
children: "Jump into team channels to collaborate with your groups — a focused place for each team's ongoing discussion."
|
|
66
67
|
})
|
|
67
|
-
] }), /* @__PURE__ */
|
|
68
|
+
] }), /* @__PURE__ */ l(d, {
|
|
68
69
|
size: "sm",
|
|
69
|
-
onClick: () =>
|
|
70
|
-
children: [/* @__PURE__ */
|
|
70
|
+
onClick: () => E.openModal(),
|
|
71
|
+
children: [/* @__PURE__ */ c(a, { className: "h-4 w-4 mr-1" }), "New Channel"]
|
|
71
72
|
})]
|
|
72
73
|
}),
|
|
73
|
-
/* @__PURE__ */
|
|
74
|
+
/* @__PURE__ */ c("div", {
|
|
74
75
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
75
|
-
children:
|
|
76
|
+
children: w.length === 0 ? /* @__PURE__ */ c("div", {
|
|
76
77
|
className: "col-span-full",
|
|
77
|
-
children: /* @__PURE__ */
|
|
78
|
+
children: /* @__PURE__ */ c(v, {
|
|
78
79
|
illustration: "empty-people",
|
|
79
80
|
title: "No team channels",
|
|
80
81
|
description: "Create a channel to give a team a focused place to collaborate."
|
|
81
82
|
})
|
|
82
|
-
}) :
|
|
83
|
-
treatment:
|
|
84
|
-
glow:
|
|
83
|
+
}) : A.map((e, n) => /* @__PURE__ */ l(g, {
|
|
84
|
+
treatment: n === 0 && D === 1 ? "glass" : "plain",
|
|
85
|
+
glow: n === 0 && D === 1,
|
|
85
86
|
role: "button",
|
|
86
87
|
tabIndex: 0,
|
|
87
88
|
"aria-label": `Open ${e.name} channel`,
|
|
88
|
-
onClick: () =>
|
|
89
|
+
onClick: () => j(e),
|
|
89
90
|
onKeyDown: (t) => {
|
|
90
|
-
(t.key === "Enter" || t.key === " ") && (t.preventDefault(),
|
|
91
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), j(e));
|
|
91
92
|
},
|
|
92
93
|
className: "cursor-pointer hover:shadow-md transition-shadow focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]",
|
|
93
|
-
children: [/* @__PURE__ */
|
|
94
|
+
children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ l("div", {
|
|
94
95
|
className: "flex items-center justify-between",
|
|
95
|
-
children: [/* @__PURE__ */
|
|
96
|
+
children: [/* @__PURE__ */ c(h, {
|
|
96
97
|
className: "text-base",
|
|
97
98
|
children: e.name
|
|
98
|
-
}), /* @__PURE__ */
|
|
99
|
+
}), /* @__PURE__ */ c(u, {
|
|
99
100
|
variant: e.status === "active" ? "default" : "secondary",
|
|
100
101
|
className: "text-[10px]",
|
|
101
|
-
children: e.status
|
|
102
|
+
children: t(e.status)
|
|
102
103
|
})]
|
|
103
|
-
}), /* @__PURE__ */
|
|
104
|
+
}), /* @__PURE__ */ c(p, { children: e.description })] }), /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l("div", {
|
|
104
105
|
className: "flex items-center justify-between text-sm text-text-secondary",
|
|
105
|
-
children: [/* @__PURE__ */
|
|
106
|
+
children: [/* @__PURE__ */ l("span", {
|
|
106
107
|
className: "flex items-center gap-1",
|
|
107
108
|
children: [
|
|
108
|
-
/* @__PURE__ */
|
|
109
|
+
/* @__PURE__ */ c(o, { className: "h-3 w-3" }),
|
|
109
110
|
e.memberCount,
|
|
110
111
|
" members"
|
|
111
112
|
]
|
|
112
|
-
}), /* @__PURE__ */
|
|
113
|
+
}), /* @__PURE__ */ l("span", {
|
|
113
114
|
className: "flex items-center gap-1",
|
|
114
115
|
children: [
|
|
115
|
-
/* @__PURE__ */
|
|
116
|
+
/* @__PURE__ */ c(i, { className: "h-3 w-3" }),
|
|
116
117
|
e.projectCount,
|
|
117
118
|
" projects"
|
|
118
119
|
]
|
|
119
120
|
})]
|
|
120
|
-
}), /* @__PURE__ */
|
|
121
|
+
}), /* @__PURE__ */ l("div", {
|
|
121
122
|
className: "mt-2 text-xs text-text-secondary",
|
|
122
123
|
children: [
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
+
/* @__PURE__ */ l("span", { children: ["Lead: ", e.leadName] }),
|
|
124
125
|
" · ",
|
|
125
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ c("span", { children: e.department })
|
|
126
127
|
]
|
|
127
128
|
})] })]
|
|
128
129
|
}, e.id))
|
|
129
130
|
}),
|
|
130
|
-
|
|
131
|
-
page:
|
|
132
|
-
pageSize:
|
|
133
|
-
totalItems:
|
|
134
|
-
onPageChange:
|
|
131
|
+
w.length > O && /* @__PURE__ */ c(b, {
|
|
132
|
+
page: D,
|
|
133
|
+
pageSize: O,
|
|
134
|
+
totalItems: w.length,
|
|
135
|
+
onPageChange: k
|
|
135
136
|
}),
|
|
136
|
-
/* @__PURE__ */
|
|
137
|
-
open:
|
|
138
|
-
onOpenChange:
|
|
137
|
+
/* @__PURE__ */ c(n, {
|
|
138
|
+
open: E.open,
|
|
139
|
+
onOpenChange: E.onOpenChange,
|
|
139
140
|
title: "New Channel",
|
|
140
141
|
description: "Give a team a focused place to collaborate.",
|
|
141
|
-
fields:
|
|
142
|
+
fields: S,
|
|
142
143
|
submitLabel: "Create Channel",
|
|
143
144
|
onSubmit: async (e) => {
|
|
144
|
-
await
|
|
145
|
+
await T({
|
|
145
146
|
name: String(e.name ?? "").trim(),
|
|
146
147
|
description: String(e.description ?? "").trim(),
|
|
147
148
|
department: String(e.department ?? "").trim() || "operations",
|
|
@@ -155,6 +156,6 @@ function S() {
|
|
|
155
156
|
});
|
|
156
157
|
}
|
|
157
158
|
//#endregion
|
|
158
|
-
export {
|
|
159
|
+
export { C as CommunicationsTeamsPagePage };
|
|
159
160
|
|
|
160
161
|
//# sourceMappingURL=CommunicationsTeamsPagePage.js.map
|