@burdenoff/microfe-crewfoundry 2026.703.1 → 2026.704.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.
- package/dist/crewfoundry/pages/AdminAdminPagePage.js +117 -164
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +99 -82
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +160 -192
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +238 -231
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +196 -166
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +45 -147
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +20 -11
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +45 -152
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +50 -138
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +149 -67
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +50 -201
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +205 -136
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +25 -31
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +118 -104
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +117 -58
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +90 -94
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +210 -191
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +213 -180
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +133 -264
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +279 -212
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +131 -105
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +167 -148
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +3 -3
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +13 -5
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +151 -152
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +38 -21
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +3 -3
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +134 -127
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +163 -132
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +202 -160
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +104 -91
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +29 -147
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +22 -106
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +74 -74
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +101 -97
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +64 -47
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +111 -121
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +131 -110
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +65 -64
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +58 -43
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +66 -82
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +38 -88
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +59 -65
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +209 -323
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +175 -220
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +74 -59
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +96 -80
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +28 -100
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +27 -20
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +73 -73
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +62 -56
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +40 -138
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +126 -93
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +99 -77
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +73 -74
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +122 -122
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +130 -113
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +68 -59
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +73 -62
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +82 -58
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +153 -153
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +63 -48
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +35 -3
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,161 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
6
|
-
import { Badge as p, Button as m, CardContent as h, CardHeader as g, CardTitle as _, GlassCard as v, GradientText as y, IllustratedEmptyState as b, Input as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
|
|
1
|
+
import { FolderInput as e } from "lucide-react";
|
|
2
|
+
import { useNavigate as t } from "react-router-dom";
|
|
3
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
4
|
+
import { Button as i, GlassCard as a, GradientText as o, IllustratedEmptyState as s, PagePurpose as c } from "@burdenoff/fe-libs/ui";
|
|
7
5
|
//#region src/crewfoundry/pages/CommunicationsFilesPagePage.tsx
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
function E() {
|
|
13
|
-
let [r, i] = n(""), o = l(), { announcements: E, invoices: D, projects: O, employees: k } = e(), A = t(() => {
|
|
14
|
-
let e = E.slice(0, 8).map((e, t) => {
|
|
15
|
-
let n = k[t % Math.max(k.length, 1)];
|
|
16
|
-
return {
|
|
17
|
-
id: `announcement-${e.id}`,
|
|
18
|
-
name: `${e.title}.pdf`,
|
|
19
|
-
type: "pdf",
|
|
20
|
-
size: `${Math.max(1, Math.round(e.content.length / 300))}.${t % 9} MB`,
|
|
21
|
-
uploadedBy: n ? `${n.firstName} ${n.lastName}`.trim() : e.author,
|
|
22
|
-
date: T(e.createdAt),
|
|
23
|
-
department: n?.department || "Operations"
|
|
24
|
-
};
|
|
25
|
-
}), t = D.slice(0, 6).map((e, t) => ({
|
|
26
|
-
id: `invoice-${e.id}`,
|
|
27
|
-
name: `${e.number}-invoice.xlsx`,
|
|
28
|
-
type: "spreadsheet",
|
|
29
|
-
size: `${(e.amount / 1e3).toFixed(1)} MB`,
|
|
30
|
-
uploadedBy: e.clientName,
|
|
31
|
-
date: T(e.issueDate),
|
|
32
|
-
department: t % 2 == 0 ? "Finance" : "Billing"
|
|
33
|
-
})), n = O.slice(0, 6).map((e, t) => ({
|
|
34
|
-
id: `project-${e.id}`,
|
|
35
|
-
name: `${e.name}-brief.docx`,
|
|
36
|
-
type: t % 2 == 0 ? "doc" : "image",
|
|
37
|
-
size: `${(Math.max(e.tasks, 1) / 10).toFixed(1)} MB`,
|
|
38
|
-
uploadedBy: e.managerName,
|
|
39
|
-
date: T(e.startDate),
|
|
40
|
-
department: "Projects"
|
|
41
|
-
}));
|
|
42
|
-
return [
|
|
43
|
-
...e,
|
|
44
|
-
...t,
|
|
45
|
-
...n
|
|
46
|
-
];
|
|
47
|
-
}, [
|
|
48
|
-
E,
|
|
49
|
-
k,
|
|
50
|
-
D,
|
|
51
|
-
O
|
|
52
|
-
]), j = A.filter((e) => e.name.toLowerCase().includes(r.toLowerCase()));
|
|
53
|
-
return /* @__PURE__ */ f("div", {
|
|
6
|
+
var l = "/files/browse";
|
|
7
|
+
function u() {
|
|
8
|
+
let u = t();
|
|
9
|
+
return /* @__PURE__ */ r("div", {
|
|
54
10
|
className: "space-y-6 p-6",
|
|
55
|
-
children: [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
11
|
+
children: [/* @__PURE__ */ r("div", {
|
|
12
|
+
className: "flex items-center justify-between",
|
|
13
|
+
children: [/* @__PURE__ */ r("div", { children: [
|
|
14
|
+
/* @__PURE__ */ n("h1", {
|
|
15
|
+
className: "text-2xl font-semibold",
|
|
16
|
+
children: /* @__PURE__ */ n(o, { children: "Shared Files" })
|
|
17
|
+
}),
|
|
18
|
+
/* @__PURE__ */ n("p", {
|
|
19
|
+
className: "text-sm text-text-secondary",
|
|
20
|
+
children: "Company documents live in the Files workspace"
|
|
21
|
+
}),
|
|
22
|
+
/* @__PURE__ */ n(c, {
|
|
23
|
+
className: "mt-1",
|
|
24
|
+
children: "A shared space for company documents and files — store, search, and share the resources your teams need to get work done."
|
|
25
|
+
})
|
|
26
|
+
] }), /* @__PURE__ */ r(i, {
|
|
27
|
+
size: "sm",
|
|
28
|
+
onClick: () => u(l),
|
|
29
|
+
children: [/* @__PURE__ */ n(e, { className: "mr-1 h-4 w-4" }), "Browse Files"]
|
|
30
|
+
})]
|
|
31
|
+
}), /* @__PURE__ */ n(a, {
|
|
32
|
+
treatment: "glass",
|
|
33
|
+
glow: !0,
|
|
34
|
+
className: "border-border-seam",
|
|
35
|
+
children: /* @__PURE__ */ n("div", {
|
|
36
|
+
className: "p-6",
|
|
37
|
+
children: /* @__PURE__ */ n(s, {
|
|
38
|
+
illustration: "empty-files",
|
|
39
|
+
title: "Files live in the Files workspace",
|
|
40
|
+
description: "CrewFoundry shares documents through the platform Files service. Open the Files workspace to browse, upload, and manage the files your teams work with.",
|
|
41
|
+
action: /* @__PURE__ */ r(i, {
|
|
42
|
+
size: "sm",
|
|
43
|
+
onClick: () => u(l),
|
|
44
|
+
children: [/* @__PURE__ */ n(e, { className: "mr-1 h-4 w-4" }), "Browse Files"]
|
|
70
45
|
})
|
|
71
|
-
|
|
72
|
-
size: "sm",
|
|
73
|
-
onClick: () => o(C),
|
|
74
|
-
children: [/* @__PURE__ */ d(c, { className: "mr-1 h-4 w-4" }), "Upload via Files"]
|
|
75
|
-
})]
|
|
76
|
-
}),
|
|
77
|
-
/* @__PURE__ */ f("div", {
|
|
78
|
-
className: "relative max-w-sm",
|
|
79
|
-
children: [/* @__PURE__ */ d(s, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ d(x, {
|
|
80
|
-
placeholder: "Search files...",
|
|
81
|
-
className: "pl-9",
|
|
82
|
-
value: r,
|
|
83
|
-
onChange: (e) => i(e.target.value)
|
|
84
|
-
})]
|
|
85
|
-
}),
|
|
86
|
-
/* @__PURE__ */ f(v, {
|
|
87
|
-
treatment: "glass",
|
|
88
|
-
glow: !0,
|
|
89
|
-
className: "border-border-seam",
|
|
90
|
-
children: [/* @__PURE__ */ d(g, { children: /* @__PURE__ */ d(_, { children: "Workspace Files" }) }), /* @__PURE__ */ d(h, {
|
|
91
|
-
className: "p-0",
|
|
92
|
-
children: j.length === 0 ? /* @__PURE__ */ d("div", {
|
|
93
|
-
className: "p-6",
|
|
94
|
-
children: /* @__PURE__ */ d(b, {
|
|
95
|
-
illustration: "empty-files",
|
|
96
|
-
title: "No files found",
|
|
97
|
-
description: "Upload files in the Files app or adjust your search to see results here."
|
|
98
|
-
})
|
|
99
|
-
}) : /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ f("div", {
|
|
100
|
-
className: "grid grid-cols-6 gap-2 border-b p-4 text-xs font-medium text-text-secondary",
|
|
101
|
-
children: [
|
|
102
|
-
/* @__PURE__ */ d("span", {
|
|
103
|
-
className: "col-span-2",
|
|
104
|
-
children: "Name"
|
|
105
|
-
}),
|
|
106
|
-
/* @__PURE__ */ d("span", { children: "Uploaded By" }),
|
|
107
|
-
/* @__PURE__ */ d("span", { children: "Department" }),
|
|
108
|
-
/* @__PURE__ */ d("span", { children: "Date" }),
|
|
109
|
-
/* @__PURE__ */ d("span", {
|
|
110
|
-
className: "text-right",
|
|
111
|
-
children: "Size"
|
|
112
|
-
})
|
|
113
|
-
]
|
|
114
|
-
}), j.map((e) => /* @__PURE__ */ f("div", {
|
|
115
|
-
className: "grid grid-cols-6 items-center gap-2 border-b px-4 py-3 text-sm last:border-0 hover:bg-bg-sunken/50",
|
|
116
|
-
children: [
|
|
117
|
-
/* @__PURE__ */ f("div", {
|
|
118
|
-
className: "col-span-2 flex items-center gap-2",
|
|
119
|
-
children: [w(e.type), /* @__PURE__ */ d("span", {
|
|
120
|
-
className: "truncate font-medium",
|
|
121
|
-
children: e.name
|
|
122
|
-
})]
|
|
123
|
-
}),
|
|
124
|
-
/* @__PURE__ */ d("span", {
|
|
125
|
-
className: "text-text-secondary",
|
|
126
|
-
children: e.uploadedBy
|
|
127
|
-
}),
|
|
128
|
-
/* @__PURE__ */ d(p, {
|
|
129
|
-
variant: "outline",
|
|
130
|
-
className: "w-fit text-[10px]",
|
|
131
|
-
children: e.department
|
|
132
|
-
}),
|
|
133
|
-
/* @__PURE__ */ d("span", {
|
|
134
|
-
className: "text-text-secondary",
|
|
135
|
-
children: e.date
|
|
136
|
-
}),
|
|
137
|
-
/* @__PURE__ */ f("div", {
|
|
138
|
-
className: "flex items-center justify-end gap-2",
|
|
139
|
-
children: [/* @__PURE__ */ d("span", {
|
|
140
|
-
className: "text-text-secondary",
|
|
141
|
-
children: e.size
|
|
142
|
-
}), /* @__PURE__ */ d(m, {
|
|
143
|
-
variant: "outline",
|
|
144
|
-
size: "sm",
|
|
145
|
-
className: "h-7",
|
|
146
|
-
"aria-label": `Open ${e.name} in Files`,
|
|
147
|
-
onClick: () => o(C),
|
|
148
|
-
children: /* @__PURE__ */ d(a, { className: "h-3 w-3" })
|
|
149
|
-
})]
|
|
150
|
-
})
|
|
151
|
-
]
|
|
152
|
-
}, e.id))] })
|
|
153
|
-
})]
|
|
46
|
+
})
|
|
154
47
|
})
|
|
155
|
-
]
|
|
48
|
+
})]
|
|
156
49
|
});
|
|
157
50
|
}
|
|
158
51
|
//#endregion
|
|
159
|
-
export {
|
|
52
|
+
export { u as CommunicationsFilesPagePage };
|
|
160
53
|
|
|
161
54
|
//# sourceMappingURL=CommunicationsFilesPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommunicationsFilesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsFilesPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useNavigate } from 'react-router-dom';\nimport { File, FileText, FolderInput, Image, Search, Upload } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\n// Files are owned by the platform Files service (wspace-files-svc), surfaced in\n// this app shell at the `/files` route. CrewFoundry does not keep a bespoke file\n// store — upload and per-file actions route into the real Files experience.\nconst FILES_BROWSE_ROUTE = '/files/browse';\n\ntype SharedFile = {\n id: string;\n name: string;\n type: 'pdf' | 'spreadsheet' | 'image' | 'doc';\n size: string;\n uploadedBy: string;\n date: string;\n department: string;\n};\n\nconst fileIcon = (type: SharedFile['type']) => {\n if (type === 'image') return <Image className=\"h-5 w-5 text-action-primary-bg\" />;\n if (type === 'pdf') return <FileText className=\"h-5 w-5 text-status-error-text\" />;\n return <File className=\"h-5 w-5 text-status-info-text\" />;\n};\n\nconst formatDate = (input: string): string => {\n const parsed = new Date(input);\n if (Number.isNaN(parsed.getTime())) {\n return 'Unknown';\n }\n return parsed.toISOString().split('T')[0];\n};\n\nexport function CommunicationsFilesPagePage() {\n const [search, setSearch] = useState('');\n const navigate = useNavigate();\n const { announcements, invoices, projects, employees } = useCrewFoundryStore();\n\n const sharedFiles = useMemo<SharedFile[]>(() => {\n const announcementFiles = announcements.slice(0, 8).map((announcement, index) => {\n const uploader = employees[index % Math.max(employees.length, 1)];\n return {\n id: `announcement-${announcement.id}`,\n name: `${announcement.title}.pdf`,\n type: 'pdf' as const,\n size: `${Math.max(1, Math.round(announcement.content.length / 300))}.${index % 9} MB`,\n uploadedBy: uploader\n ? `${uploader.firstName} ${uploader.lastName}`.trim()\n : announcement.author,\n date: formatDate(announcement.createdAt),\n department: uploader?.department || 'Operations',\n };\n });\n\n const financeFiles = invoices.slice(0, 6).map((invoice, index) => ({\n id: `invoice-${invoice.id}`,\n name: `${invoice.number}-invoice.xlsx`,\n type: 'spreadsheet' as const,\n size: `${(invoice.amount / 1000).toFixed(1)} MB`,\n uploadedBy: invoice.clientName,\n date: formatDate(invoice.issueDate),\n department: index % 2 === 0 ? 'Finance' : 'Billing',\n }));\n\n const projectFiles = projects.slice(0, 6).map((project, index) => ({\n id: `project-${project.id}`,\n name: `${project.name}-brief.docx`,\n type: index % 2 === 0 ? ('doc' as const) : ('image' as const),\n size: `${(Math.max(project.tasks, 1) / 10).toFixed(1)} MB`,\n uploadedBy: project.managerName,\n date: formatDate(project.startDate),\n department: 'Projects',\n }));\n\n return [...announcementFiles, ...financeFiles, ...projectFiles];\n }, [announcements, employees, invoices, projects]);\n\n const filteredFiles = sharedFiles.filter((file) =>\n file.name.toLowerCase().includes(search.toLowerCase())\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>Shared Files</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {sharedFiles.length} files shared across teams\n </p>\n <PagePurpose className=\"mt-1\">A shared space for company documents and files — store, search, and share the resources your teams need to get work done.</PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => navigate(FILES_BROWSE_ROUTE)}>\n <Upload className=\"mr-1 h-4 w-4\" />\n Upload via Files\n </Button>\n </div>\n\n <div className=\"relative max-w-sm\">\n <Search className=\"absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search files...\"\n className=\"pl-9\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Workspace Files</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n {filteredFiles.length === 0 ? (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-files\"\n title=\"No files found\"\n description=\"Upload files in the Files app or adjust your search to see results here.\"\n />\n </div>\n ) : (\n <>\n <div className=\"grid grid-cols-6 gap-2 border-b p-4 text-xs font-medium text-text-secondary\">\n <span className=\"col-span-2\">Name</span>\n <span>Uploaded By</span>\n <span>Department</span>\n <span>Date</span>\n <span className=\"text-right\">Size</span>\n </div>\n {filteredFiles.map((file) => (\n <div\n key={file.id}\n className=\"grid grid-cols-6 items-center gap-2 border-b px-4 py-3 text-sm last:border-0 hover:bg-bg-sunken/50\"\n >\n <div className=\"col-span-2 flex items-center gap-2\">\n {fileIcon(file.type)}\n <span className=\"truncate font-medium\">{file.name}</span>\n </div>\n <span className=\"text-text-secondary\">{file.uploadedBy}</span>\n <Badge variant=\"outline\" className=\"w-fit text-[10px]\">\n {file.department}\n </Badge>\n <span className=\"text-text-secondary\">{file.date}</span>\n <div className=\"flex items-center justify-end gap-2\">\n <span className=\"text-text-secondary\">{file.size}</span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7\"\n aria-label={`Open ${file.name} in Files`}\n onClick={() => navigate(FILES_BROWSE_ROUTE)}\n >\n <FolderInput className=\"h-3 w-3\" />\n </Button>\n </div>\n </div>\n ))}\n </>\n )}\n </CardContent>\n </GlassCard>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CommunicationsFilesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsFilesPagePage.tsx"],"sourcesContent":["import {\n Button,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useNavigate } from 'react-router-dom';\nimport { FolderInput } from 'lucide-react';\n\n// Files are owned by the platform Files service (wspace-files-svc), surfaced in\n// this app shell at the `/files` route. CrewFoundry keeps no bespoke file store,\n// so this page routes into the real Files experience rather than manufacturing\n// a fabricated file list.\nconst FILES_BROWSE_ROUTE = '/files/browse';\n\nexport function CommunicationsFilesPagePage() {\n const navigate = useNavigate();\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>Shared Files</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Company documents live in the Files workspace\n </p>\n <PagePurpose className=\"mt-1\">A shared space for company documents and files — store, search, and share the resources your teams need to get work done.</PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => navigate(FILES_BROWSE_ROUTE)}>\n <FolderInput className=\"mr-1 h-4 w-4\" />\n Browse Files\n </Button>\n </div>\n\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-files\"\n title=\"Files live in the Files workspace\"\n description=\"CrewFoundry shares documents through the platform Files service. Open the Files workspace to browse, upload, and manage the files your teams work with.\"\n action={\n <Button size=\"sm\" onClick={() => navigate(FILES_BROWSE_ROUTE)}>\n <FolderInput className=\"mr-1 h-4 w-4\" />\n Browse Files\n </Button>\n }\n />\n </div>\n </GlassCard>\n </div>\n );\n}\n"],"mappings":";;;;;AAcA,IAAM,IAAqB;AAE3B,SAAgB,IAA8B;CAC5C,IAAM,IAAW,GAAa;AAE9B,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAA,UAAA;IACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAc,gBAA2B,CAAA;KACtC,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAEvC,CAAA;IACJ,kBAAC,GAAD;KAAa,WAAU;eAAO;KAAuI,CAAA;IACjK,EAAA,CAAA,EACN,kBAAC,GAAD;IAAQ,MAAK;IAAK,eAAe,EAAS,EAAmB;cAA7D,CACE,kBAAC,GAAD,EAAa,WAAU,gBAAiB,CAAA,EAAA,eAEjC;MACL;MAEN,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAC1C,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,QACE,kBAAC,GAAD;MAAQ,MAAK;MAAK,eAAe,EAAS,EAAmB;gBAA7D,CACE,kBAAC,GAAD,EAAa,WAAU,gBAAiB,CAAA,EAAA,eAEjC;;KAEX,CAAA;IACE,CAAA;GACI,CAAA,CACR"}
|
|
@@ -1,146 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { Badge as s, Button as c, CardContent as l, CardHeader as u, CardTitle as d, GlassCard as f, GradientText as p, IllustratedEmptyState as m, Input as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
|
|
6
|
-
import { useGlobalUi as _ } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
1
|
+
import { MessageSquare as e } from "lucide-react";
|
|
2
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
3
|
+
import { Badge as r, Button as i, CardContent as a, CardHeader as o, CardTitle as s, GlassCard as c, GradientText as l, IllustratedEmptyState as u, PagePurpose as d } from "@burdenoff/fe-libs/ui";
|
|
4
|
+
import { useGlobalUi as f } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
7
5
|
//#region src/crewfoundry/pages/CommunicationsMessagesPagePage.tsx
|
|
8
|
-
|
|
9
|
-
let
|
|
10
|
-
|
|
11
|
-
let n = Date.now() - t.getTime(), r = Math.max(0, Math.floor(n / (1e3 * 60 * 60)));
|
|
12
|
-
return r < 1 ? "Just now" : r < 24 ? `${r}h ago` : `${Math.floor(r / 24)}d ago`;
|
|
13
|
-
};
|
|
14
|
-
function y() {
|
|
15
|
-
let [y, b] = n(""), { showToast: x } = _(), { teams: S, employees: C, announcements: w, notifications: T } = e(), E = () => x("Direct messaging is on the CrewFoundry roadmap — coming soon.", "info"), D = t(() => {
|
|
16
|
-
let e = C.slice(0, 8).map((e, t) => {
|
|
17
|
-
let n = w[t % Math.max(w.length, 1)], r = n?.content || `Status update for ${e.department} initiatives.`;
|
|
18
|
-
return {
|
|
19
|
-
id: `person-${e.id}`,
|
|
20
|
-
name: `${e.firstName} ${e.lastName}`.trim(),
|
|
21
|
-
role: e.position,
|
|
22
|
-
lastMessage: r,
|
|
23
|
-
time: v(n?.createdAt || e.startDate),
|
|
24
|
-
unread: Math.min(3, Math.round(e.performanceScore) % 4),
|
|
25
|
-
online: e.status === "active" && t % 2 == 0
|
|
26
|
-
};
|
|
27
|
-
}), t = S.slice(0, 5).map((e, t) => {
|
|
28
|
-
let n = T.slice(t, t + 3).filter((e) => !e.read).length;
|
|
29
|
-
return {
|
|
30
|
-
id: `team-${e.id}`,
|
|
31
|
-
name: `#${e.name.toLowerCase().replaceAll(" ", "-")}`,
|
|
32
|
-
role: `Channel · ${e.memberCount} members`,
|
|
33
|
-
lastMessage: w[t % Math.max(w.length, 1)]?.title || `${e.leadName} posted an update in ${e.name}.`,
|
|
34
|
-
time: v(e.createdAt),
|
|
35
|
-
unread: n,
|
|
36
|
-
online: !1
|
|
37
|
-
};
|
|
38
|
-
});
|
|
39
|
-
return [...e, ...t];
|
|
40
|
-
}, [
|
|
41
|
-
w,
|
|
42
|
-
C,
|
|
43
|
-
T,
|
|
44
|
-
S
|
|
45
|
-
]).filter((e) => e.name.toLowerCase().includes(y.toLowerCase()));
|
|
46
|
-
return /* @__PURE__ */ o("div", {
|
|
6
|
+
function p() {
|
|
7
|
+
let { showToast: p } = f();
|
|
8
|
+
return /* @__PURE__ */ n("div", {
|
|
47
9
|
className: "space-y-6 p-6",
|
|
48
|
-
children: [
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
children: [/* @__PURE__ */ a(r, { className: "mr-1 h-4 w-4" }), "New Message"]
|
|
74
|
-
})]
|
|
75
|
-
})]
|
|
76
|
-
}),
|
|
77
|
-
/* @__PURE__ */ o("div", {
|
|
78
|
-
className: "relative max-w-sm",
|
|
79
|
-
children: [/* @__PURE__ */ a(i, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ a(h, {
|
|
80
|
-
placeholder: "Search conversations...",
|
|
81
|
-
className: "pl-9",
|
|
82
|
-
value: y,
|
|
83
|
-
onChange: (e) => b(e.target.value)
|
|
10
|
+
children: [/* @__PURE__ */ n("div", {
|
|
11
|
+
className: "flex items-center justify-between",
|
|
12
|
+
children: [/* @__PURE__ */ n("div", { children: [
|
|
13
|
+
/* @__PURE__ */ t("h1", {
|
|
14
|
+
className: "text-2xl font-semibold",
|
|
15
|
+
children: /* @__PURE__ */ t(l, { children: "Messages" })
|
|
16
|
+
}),
|
|
17
|
+
/* @__PURE__ */ t("p", {
|
|
18
|
+
className: "text-sm text-text-secondary",
|
|
19
|
+
children: "Team conversations and channels"
|
|
20
|
+
}),
|
|
21
|
+
/* @__PURE__ */ t(d, {
|
|
22
|
+
className: "mt-1",
|
|
23
|
+
children: "Chat directly with colleagues and keep conversations in one thread — use it for quick questions, follow-ups, and day-to-day coordination."
|
|
24
|
+
})
|
|
25
|
+
] }), /* @__PURE__ */ n("div", {
|
|
26
|
+
className: "flex items-center gap-2",
|
|
27
|
+
children: [/* @__PURE__ */ t(r, {
|
|
28
|
+
variant: "secondary",
|
|
29
|
+
className: "text-[10px]",
|
|
30
|
+
children: "Coming soon"
|
|
31
|
+
}), /* @__PURE__ */ n(i, {
|
|
32
|
+
size: "sm",
|
|
33
|
+
onClick: () => p("Direct messaging is on the CrewFoundry roadmap — coming soon.", "info"),
|
|
34
|
+
children: [/* @__PURE__ */ t(e, { className: "mr-1 h-4 w-4" }), "New Message"]
|
|
84
35
|
})]
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
/* @__PURE__ */ o("div", {
|
|
103
|
-
className: "relative",
|
|
104
|
-
children: [/* @__PURE__ */ a("div", {
|
|
105
|
-
className: "flex h-10 w-10 items-center justify-center rounded-full bg-action-primary-bg/10 text-sm font-medium",
|
|
106
|
-
children: e.name.startsWith("#") ? "#" : e.name.split(" ").map((e) => e[0]).join("")
|
|
107
|
-
}), e.online && /* @__PURE__ */ a("div", { className: "absolute right-0 bottom-0 h-3 w-3 rounded-full border-2 border-background bg-status-success-text" })]
|
|
108
|
-
}),
|
|
109
|
-
/* @__PURE__ */ o("div", {
|
|
110
|
-
className: "min-w-0 flex-1",
|
|
111
|
-
children: [
|
|
112
|
-
/* @__PURE__ */ o("div", {
|
|
113
|
-
className: "flex items-center justify-between",
|
|
114
|
-
children: [/* @__PURE__ */ a("p", {
|
|
115
|
-
className: "text-sm font-medium",
|
|
116
|
-
children: e.name
|
|
117
|
-
}), /* @__PURE__ */ a("span", {
|
|
118
|
-
className: "text-xs text-text-secondary",
|
|
119
|
-
children: e.time
|
|
120
|
-
})]
|
|
121
|
-
}),
|
|
122
|
-
/* @__PURE__ */ a("p", {
|
|
123
|
-
className: "text-xs text-text-secondary",
|
|
124
|
-
children: e.role
|
|
125
|
-
}),
|
|
126
|
-
/* @__PURE__ */ a("p", {
|
|
127
|
-
className: "mt-0.5 truncate text-xs text-text-secondary",
|
|
128
|
-
children: e.lastMessage
|
|
129
|
-
})
|
|
130
|
-
]
|
|
131
|
-
}),
|
|
132
|
-
e.unread > 0 && /* @__PURE__ */ a(s, {
|
|
133
|
-
className: "flex h-5 w-5 items-center justify-center rounded-full p-0 text-[10px]",
|
|
134
|
-
children: e.unread
|
|
135
|
-
})
|
|
136
|
-
]
|
|
137
|
-
}, e.id))
|
|
138
|
-
})]
|
|
139
|
-
})
|
|
140
|
-
]
|
|
36
|
+
})]
|
|
37
|
+
}), /* @__PURE__ */ n(c, {
|
|
38
|
+
treatment: "glass",
|
|
39
|
+
glow: !0,
|
|
40
|
+
className: "border-border-seam",
|
|
41
|
+
children: [/* @__PURE__ */ t(o, { children: /* @__PURE__ */ t(s, { children: "Conversation Inbox" }) }), /* @__PURE__ */ t(a, {
|
|
42
|
+
className: "p-0",
|
|
43
|
+
children: /* @__PURE__ */ t("div", {
|
|
44
|
+
className: "p-6",
|
|
45
|
+
children: /* @__PURE__ */ t(u, {
|
|
46
|
+
illustration: "empty-notifications",
|
|
47
|
+
title: "Messaging is coming soon",
|
|
48
|
+
description: "Direct messages and team channels are on the CrewFoundry roadmap. Once the chat backend ships, your conversations will appear here."
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
})]
|
|
52
|
+
})]
|
|
141
53
|
});
|
|
142
54
|
}
|
|
143
55
|
//#endregion
|
|
144
|
-
export {
|
|
56
|
+
export { p as CommunicationsMessagesPagePage };
|
|
145
57
|
|
|
146
58
|
//# sourceMappingURL=CommunicationsMessagesPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommunicationsMessagesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsMessagesPagePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { MessageSquare, Search } from 'lucide-react';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Conversation = {\n id: string;\n name: string;\n role: string;\n lastMessage: string;\n time: string;\n unread: number;\n online: boolean;\n};\n\nconst formatRelativeDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Recently';\n }\n const diffMs = Date.now() - parsed.getTime();\n const diffHours = Math.max(0, Math.floor(diffMs / (1000 * 60 * 60)));\n if (diffHours < 1) return 'Just now';\n if (diffHours < 24) return `${diffHours}h ago`;\n const diffDays = Math.floor(diffHours / 24);\n return `${diffDays}d ago`;\n};\n\nexport function CommunicationsMessagesPagePage() {\n const [search, setSearch] = useState('');\n const { showToast } = useGlobalUi();\n const { teams, employees, announcements, notifications } = useCrewFoundryStore();\n\n // Real-time direct messaging is a planned surface — there is no chat backend\n // yet, so this control honestly signals its roadmap status instead of failing\n // silently.\n const notifyComingSoon = () =>\n showToast('Direct messaging is on the CrewFoundry roadmap — coming soon.', 'info');\n\n const conversations = useMemo<Conversation[]>(() => {\n const peopleConversations = employees.slice(0, 8).map((employee, index) => {\n const announcement = announcements[index % Math.max(announcements.length, 1)];\n const message =\n announcement?.content || `Status update for ${employee.department} initiatives.`;\n return {\n id: `person-${employee.id}`,\n name: `${employee.firstName} ${employee.lastName}`.trim(),\n role: employee.position,\n lastMessage: message,\n time: formatRelativeDate(announcement?.createdAt || employee.startDate),\n unread: Math.min(3, Math.round(employee.performanceScore) % 4),\n online: employee.status === 'active' && index % 2 === 0,\n };\n });\n\n const teamConversations = teams.slice(0, 5).map((team, index) => {\n const unread = notifications\n .slice(index, index + 3)\n .filter((notification) => !notification.read).length;\n return {\n id: `team-${team.id}`,\n name: `#${team.name.toLowerCase().replaceAll(' ', '-')}`,\n role: `Channel · ${team.memberCount} members`,\n lastMessage:\n announcements[index % Math.max(announcements.length, 1)]?.title ||\n `${team.leadName} posted an update in ${team.name}.`,\n time: formatRelativeDate(team.createdAt),\n unread,\n online: false,\n };\n });\n\n return [...peopleConversations, ...teamConversations];\n }, [announcements, employees, notifications, teams]);\n\n const filteredConversations = conversations.filter((conversation) =>\n conversation.name.toLowerCase().includes(search.toLowerCase())\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>Messages</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Team conversations and channels</p>\n <PagePurpose className=\"mt-1\">Chat directly with colleagues and keep conversations in one thread — use it for quick questions, follow-ups, and day-to-day coordination.</PagePurpose>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n Coming soon\n </Badge>\n <Button size=\"sm\" onClick={notifyComingSoon}>\n <MessageSquare className=\"mr-1 h-4 w-4\" />\n New Message\n </Button>\n </div>\n </div>\n\n <div className=\"relative max-w-sm\">\n <Search className=\"absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search conversations...\"\n className=\"pl-9\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Conversation Inbox</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n {filteredConversations.length === 0 ? (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title=\"No conversations\"\n description=\"Messages with your colleagues will show up here.\"\n />\n </div>\n ) : (\n filteredConversations.map((conversation) => (\n <div\n key={conversation.id}\n className=\"flex items-center gap-3 border-b p-4 last:border-0\"\n >\n <div className=\"relative\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-action-primary-bg/10 text-sm font-medium\">\n {conversation.name.startsWith('#')\n ? '#'\n : conversation.name\n .split(' ')\n .map((part) => part[0])\n .join('')}\n </div>\n {conversation.online && (\n <div className=\"absolute right-0 bottom-0 h-3 w-3 rounded-full border-2 border-background bg-status-success-text\" />\n )}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm font-medium\">{conversation.name}</p>\n <span className=\"text-xs text-text-secondary\">{conversation.time}</span>\n </div>\n <p className=\"text-xs text-text-secondary\">{conversation.role}</p>\n <p className=\"mt-0.5 truncate text-xs text-text-secondary\">\n {conversation.lastMessage}\n </p>\n </div>\n\n {conversation.unread > 0 && (\n <Badge className=\"flex h-5 w-5 items-center justify-center rounded-full p-0 text-[10px]\">\n {conversation.unread}\n </Badge>\n )}\n </div>\n ))\n )}\n </CardContent>\n </GlassCard>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CommunicationsMessagesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsMessagesPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { MessageSquare } from 'lucide-react';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\n\nexport function CommunicationsMessagesPagePage() {\n const { showToast } = useGlobalUi();\n\n // Real-time direct messaging is a planned surface — there is no chat backend\n // yet, so this control honestly signals its roadmap status instead of failing\n // silently. No conversation data is fabricated in the meantime.\n const notifyComingSoon = () =>\n showToast('Direct messaging is on the CrewFoundry roadmap — coming soon.', 'info');\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>Messages</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Team conversations and channels</p>\n <PagePurpose className=\"mt-1\">Chat directly with colleagues and keep conversations in one thread — use it for quick questions, follow-ups, and day-to-day coordination.</PagePurpose>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n Coming soon\n </Badge>\n <Button size=\"sm\" onClick={notifyComingSoon}>\n <MessageSquare className=\"mr-1 h-4 w-4\" />\n New Message\n </Button>\n </div>\n </div>\n\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Conversation Inbox</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title=\"Messaging is coming soon\"\n description=\"Direct messages and team channels are on the CrewFoundry roadmap. Once the chat backend ships, your conversations will appear here.\"\n />\n </div>\n </CardContent>\n </GlassCard>\n </div>\n );\n}\n"],"mappings":";;;;;AAcA,SAAgB,IAAiC;CAC/C,IAAM,EAAE,iBAAc,GAAa;AAQnC,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAA,UAAA;IACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAc,YAAuB,CAAA;KAClC,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAAmC,CAAA;IAC9E,kBAAC,GAAD;KAAa,WAAU;eAAO;KAAuJ,CAAA;IACjL,EAAA,CAAA,EACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAO,SAAQ;KAAY,WAAU;eAAc;KAE3C,CAAA,EACR,kBAAC,GAAD;KAAQ,MAAK;KAAK,eAhBxB,EAAU,iEAAiE,OAAO;eAgB5E,CACE,kBAAC,GAAD,EAAe,WAAU,gBAAiB,CAAA,EAAA,cAEnC;OACL;MACF;MAEN,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAA5C,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,sBAA8B,CAAA,EAC9B,CAAA,EACb,kBAAC,GAAD;IAAa,WAAU;cACrB,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MACE,cAAa;MACb,OAAM;MACN,aAAY;MACZ,CAAA;KACE,CAAA;IACM,CAAA,CACJ;KACR"}
|