@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,78 +1,160 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { FormModal as t, useFormModal as n } from "../components/forms/FormModal.js";
|
|
3
|
+
import { FolderKanban as r, Plus as i, Users as a } from "lucide-react";
|
|
4
|
+
import { useNavigate as o } from "react-router-dom";
|
|
5
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
6
|
+
import { Badge as l, Button as u, CardContent as d, CardDescription as f, CardHeader as p, CardTitle as m, GlassCard as h, GradientText as g, IllustratedEmptyState as _, PagePurpose as v, Pagination as y } from "@burdenoff/fe-libs/ui";
|
|
7
|
+
import { usePagination as b } from "@burdenoff/fe-libs/shared/hooks";
|
|
5
8
|
//#region src/crewfoundry/pages/CommunicationsTeamsPagePage.tsx
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
var x = [
|
|
10
|
+
{
|
|
11
|
+
name: "name",
|
|
12
|
+
label: "Channel Name",
|
|
13
|
+
type: "text",
|
|
14
|
+
required: !0
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: "department",
|
|
18
|
+
label: "Department",
|
|
19
|
+
type: "text",
|
|
20
|
+
placeholder: "e.g. Engineering"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "leadName",
|
|
24
|
+
label: "Channel Lead",
|
|
25
|
+
type: "text",
|
|
26
|
+
placeholder: "Lead full name"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "status",
|
|
30
|
+
label: "Status",
|
|
31
|
+
type: "select",
|
|
32
|
+
options: [{
|
|
33
|
+
label: "Active",
|
|
34
|
+
value: "active"
|
|
35
|
+
}, {
|
|
36
|
+
label: "Forming",
|
|
37
|
+
value: "forming"
|
|
38
|
+
}]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "description",
|
|
42
|
+
label: "Description",
|
|
43
|
+
type: "textarea",
|
|
44
|
+
colSpan: 2
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
function S() {
|
|
48
|
+
let S = o(), { teams: C } = e(), w = e((e) => e.addTeam), T = n(), { page: E, pageSize: D, setPage: O } = b({ initialPageSize: 12 }), k = C.slice((E - 1) * D, (E - 1) * D + D), A = (e) => S(`../../teams/team-detail-page?id=${encodeURIComponent(e.id)}`);
|
|
49
|
+
return /* @__PURE__ */ c("div", {
|
|
9
50
|
className: "space-y-6 p-6",
|
|
10
|
-
children: [
|
|
11
|
-
/* @__PURE__ */
|
|
12
|
-
className: "
|
|
13
|
-
children: /* @__PURE__ */
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ c("div", {
|
|
53
|
+
className: "flex items-start justify-between gap-4",
|
|
54
|
+
children: [/* @__PURE__ */ c("div", { children: [
|
|
55
|
+
/* @__PURE__ */ s("h1", {
|
|
56
|
+
className: "text-2xl font-semibold",
|
|
57
|
+
children: /* @__PURE__ */ s(g, { children: "Team Channels" })
|
|
58
|
+
}),
|
|
59
|
+
/* @__PURE__ */ c("p", {
|
|
60
|
+
className: "text-sm text-text-secondary",
|
|
61
|
+
children: [C.length, " active team channels"]
|
|
62
|
+
}),
|
|
63
|
+
/* @__PURE__ */ s(v, {
|
|
64
|
+
className: "mt-1",
|
|
65
|
+
children: "Jump into team channels to collaborate with your groups — a focused place for each team's ongoing discussion."
|
|
66
|
+
})
|
|
67
|
+
] }), /* @__PURE__ */ c(u, {
|
|
68
|
+
size: "sm",
|
|
69
|
+
onClick: () => T.openModal(),
|
|
70
|
+
children: [/* @__PURE__ */ s(i, { className: "h-4 w-4 mr-1" }), "New Channel"]
|
|
71
|
+
})]
|
|
14
72
|
}),
|
|
15
|
-
/* @__PURE__ */
|
|
16
|
-
className: "
|
|
17
|
-
children:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
})]
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
73
|
+
/* @__PURE__ */ s("div", {
|
|
74
|
+
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
75
|
+
children: C.length === 0 ? /* @__PURE__ */ s("div", {
|
|
76
|
+
className: "col-span-full",
|
|
77
|
+
children: /* @__PURE__ */ s(_, {
|
|
78
|
+
illustration: "empty-people",
|
|
79
|
+
title: "No team channels",
|
|
80
|
+
description: "Create a channel to give a team a focused place to collaborate."
|
|
81
|
+
})
|
|
82
|
+
}) : k.map((e, t) => /* @__PURE__ */ c(h, {
|
|
83
|
+
treatment: t === 0 && E === 1 ? "glass" : "plain",
|
|
84
|
+
glow: t === 0 && E === 1,
|
|
85
|
+
role: "button",
|
|
86
|
+
tabIndex: 0,
|
|
87
|
+
"aria-label": `Open ${e.name} channel`,
|
|
88
|
+
onClick: () => A(e),
|
|
89
|
+
onKeyDown: (t) => {
|
|
90
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), A(e));
|
|
91
|
+
},
|
|
92
|
+
className: "cursor-pointer hover:shadow-md transition-shadow focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]",
|
|
93
|
+
children: [/* @__PURE__ */ c(p, { children: [/* @__PURE__ */ c("div", {
|
|
94
|
+
className: "flex items-center justify-between",
|
|
95
|
+
children: [/* @__PURE__ */ s(m, {
|
|
96
|
+
className: "text-base",
|
|
97
|
+
children: e.name
|
|
98
|
+
}), /* @__PURE__ */ s(l, {
|
|
99
|
+
variant: e.status === "active" ? "default" : "secondary",
|
|
100
|
+
className: "text-[10px]",
|
|
101
|
+
children: e.status
|
|
102
|
+
})]
|
|
103
|
+
}), /* @__PURE__ */ s(f, { children: e.description })] }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ c("div", {
|
|
104
|
+
className: "flex items-center justify-between text-sm text-text-secondary",
|
|
105
|
+
children: [/* @__PURE__ */ c("span", {
|
|
106
|
+
className: "flex items-center gap-1",
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ s(a, { className: "h-3 w-3" }),
|
|
109
|
+
e.memberCount,
|
|
110
|
+
" members"
|
|
111
|
+
]
|
|
112
|
+
}), /* @__PURE__ */ c("span", {
|
|
113
|
+
className: "flex items-center gap-1",
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ s(r, { className: "h-3 w-3" }),
|
|
116
|
+
e.projectCount,
|
|
117
|
+
" projects"
|
|
118
|
+
]
|
|
119
|
+
})]
|
|
120
|
+
}), /* @__PURE__ */ c("div", {
|
|
121
|
+
className: "mt-2 text-xs text-text-secondary",
|
|
57
122
|
children: [
|
|
58
|
-
/* @__PURE__ */
|
|
59
|
-
|
|
60
|
-
"
|
|
123
|
+
/* @__PURE__ */ c("span", { children: ["Lead: ", e.leadName] }),
|
|
124
|
+
" · ",
|
|
125
|
+
/* @__PURE__ */ s("span", { children: e.department })
|
|
61
126
|
]
|
|
62
|
-
})]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
127
|
+
})] })]
|
|
128
|
+
}, e.id))
|
|
129
|
+
}),
|
|
130
|
+
C.length > D && /* @__PURE__ */ s(y, {
|
|
131
|
+
page: E,
|
|
132
|
+
pageSize: D,
|
|
133
|
+
totalItems: C.length,
|
|
134
|
+
onPageChange: O
|
|
135
|
+
}),
|
|
136
|
+
/* @__PURE__ */ s(t, {
|
|
137
|
+
open: T.open,
|
|
138
|
+
onOpenChange: T.onOpenChange,
|
|
139
|
+
title: "New Channel",
|
|
140
|
+
description: "Give a team a focused place to collaborate.",
|
|
141
|
+
fields: x,
|
|
142
|
+
submitLabel: "Create Channel",
|
|
143
|
+
onSubmit: async (e) => {
|
|
144
|
+
await w({
|
|
145
|
+
name: String(e.name ?? "").trim(),
|
|
146
|
+
description: String(e.description ?? "").trim(),
|
|
147
|
+
department: String(e.department ?? "").trim() || "operations",
|
|
148
|
+
leadName: String(e.leadName ?? "").trim(),
|
|
149
|
+
status: String(e.status ?? "forming") || "forming",
|
|
150
|
+
members: []
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
]
|
|
73
155
|
});
|
|
74
156
|
}
|
|
75
157
|
//#endregion
|
|
76
|
-
export {
|
|
158
|
+
export { S as CommunicationsTeamsPagePage };
|
|
77
159
|
|
|
78
160
|
//# sourceMappingURL=CommunicationsTeamsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommunicationsTeamsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsTeamsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { FolderKanban, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function CommunicationsTeamsPagePage() {\n const { teams } = useCrewFoundryStore();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n
|
|
1
|
+
{"version":3,"file":"CommunicationsTeamsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsTeamsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n Pagination,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { FolderKanban, Plus, Users } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Team } from '../store/crewfoundryStore';\n\n// CreateCrewTeamInput accepts only this field subset; the store spreads the\n// object straight into `input`, so we send exactly the accepted shape.\nconst CHANNEL_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Channel Name', type: 'text', required: true },\n { name: 'department', label: 'Department', type: 'text', placeholder: 'e.g. Engineering' },\n { name: 'leadName', label: 'Channel Lead', type: 'text', placeholder: 'Lead full name' },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Forming', value: 'forming' },\n ],\n },\n { name: 'description', label: 'Description', type: 'textarea', colSpan: 2 },\n];\n\nexport function CommunicationsTeamsPagePage() {\n const navigate = useNavigate();\n const { teams } = useCrewFoundryStore();\n const addTeam = useCrewFoundryStore((state) => state.addTeam);\n const createModal = useFormModal();\n const { page, pageSize, setPage } = usePagination({ initialPageSize: 12 });\n\n const pageTeams = teams.slice((page - 1) * pageSize, (page - 1) * pageSize + pageSize);\n\n const openTeam = (team: Team) =>\n navigate(`../../teams/team-detail-page?id=${encodeURIComponent(team.id)}`);\n\n const handleCreate = async (values: FormValues) => {\n const payload: Partial<Team> = {\n name: String(values.name ?? '').trim(),\n description: String(values.description ?? '').trim(),\n department: String(values.department ?? '').trim() || 'operations',\n leadName: String(values.leadName ?? '').trim(),\n status: (String(values.status ?? 'forming') as Team['status']) || 'forming',\n members: [],\n };\n await addTeam(payload as Team);\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Team Channels</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{teams.length} active team channels</p>\n <PagePurpose className=\"mt-1\">Jump into team channels to collaborate with your groups — a focused place for each team's ongoing discussion.</PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => createModal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n New Channel\n </Button>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {teams.length === 0 ? (\n <div className=\"col-span-full\">\n <IllustratedEmptyState illustration=\"empty-people\" title=\"No team channels\" description=\"Create a channel to give a team a focused place to collaborate.\" />\n </div>\n ) : (\n pageTeams.map((team, _idx) => (\n <GlassCard\n key={team.id}\n treatment={_idx === 0 && page === 1 ? 'glass' : 'plain'}\n glow={_idx === 0 && page === 1}\n role=\"button\"\n tabIndex={0}\n aria-label={`Open ${team.name} channel`}\n onClick={() => openTeam(team)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openTeam(team);\n }\n }}\n className=\"cursor-pointer hover:shadow-md transition-shadow focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]\"\n >\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{team.name}</CardTitle>\n <Badge\n variant={team.status === 'active' ? 'default' : 'secondary'}\n className=\"text-[10px]\"\n >\n {team.status}\n </Badge>\n </div>\n <CardDescription>{team.description}</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-center justify-between text-sm text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Users className=\"h-3 w-3\" />\n {team.memberCount} members\n </span>\n <span className=\"flex items-center gap-1\">\n <FolderKanban className=\"h-3 w-3\" />\n {team.projectCount} projects\n </span>\n </div>\n <div className=\"mt-2 text-xs text-text-secondary\">\n <span>Lead: {team.leadName}</span> · <span>{team.department}</span>\n </div>\n </CardContent>\n </GlassCard>\n )))}\n </div>\n\n {teams.length > pageSize && (\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={teams.length}\n onPageChange={setPage}\n />\n )}\n\n <FormModal\n open={createModal.open}\n onOpenChange={createModal.onOpenChange}\n title=\"New Channel\"\n description=\"Give a team a focused place to collaborate.\"\n fields={CHANNEL_FIELDS}\n submitLabel=\"Create Channel\"\n onSubmit={handleCreate}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,213 +1,62 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { Badge as l, Button as u, Card as d, CardContent as f, CardHeader as p, CardTitle as m, GlassCard as h, GradientText as g, PagePurpose as _ } from "@burdenoff/fe-libs/ui";
|
|
6
|
-
import { useGlobalUi as v } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
1
|
+
import { Calendar as e, Video as t } from "lucide-react";
|
|
2
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
3
|
+
import { Badge as i, Button as a, Card as o, CardContent as s, CardHeader as c, CardTitle as l, GradientText as u, IllustratedEmptyState as d, PagePurpose as f } from "@burdenoff/fe-libs/ui";
|
|
4
|
+
import { useGlobalUi as p } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
7
5
|
//#region src/crewfoundry/pages/CommunicationsVideoCallsPagePage.tsx
|
|
8
|
-
|
|
9
|
-
let
|
|
10
|
-
return
|
|
11
|
-
}, x = (e) => {
|
|
12
|
-
let t = new Date(e);
|
|
13
|
-
return Number.isNaN(t.getTime()) ? "Upcoming" : t.toLocaleDateString();
|
|
14
|
-
};
|
|
15
|
-
function S() {
|
|
16
|
-
let { showToast: S } = v(), { teams: C, interviews: w, announcements: T } = e(), E = () => S("Video meetings are on the CrewFoundry roadmap — coming soon.", "info"), D = t(() => {
|
|
17
|
-
let e = C.slice(0, 6).map((e, t) => ({
|
|
18
|
-
id: `team-${e.id}`,
|
|
19
|
-
title: `${e.name} Sync`,
|
|
20
|
-
host: e.leadName,
|
|
21
|
-
time: x(e.createdAt),
|
|
22
|
-
duration: y(15 + t * 10),
|
|
23
|
-
participants: Math.max(e.memberCount, 2),
|
|
24
|
-
recurring: t % 2 == 0
|
|
25
|
-
})), t = w.slice(0, 4).map((e) => ({
|
|
26
|
-
id: `interview-${e.id}`,
|
|
27
|
-
title: `Interview · ${e.candidateName}`,
|
|
28
|
-
host: e.interviewerName,
|
|
29
|
-
time: x(e.date),
|
|
30
|
-
duration: y(Number.parseInt(e.time.split(":")[0] || "30", 10)),
|
|
31
|
-
participants: 3,
|
|
32
|
-
recurring: !1
|
|
33
|
-
}));
|
|
34
|
-
return [...e, ...t];
|
|
35
|
-
}, [w, C]), O = t(() => T.slice(0, 6).map((e) => {
|
|
36
|
-
let t = Math.max(12, Math.round(e.content.length / 40));
|
|
37
|
-
return {
|
|
38
|
-
id: `recording-${e.id}`,
|
|
39
|
-
title: `${e.title} recording`,
|
|
40
|
-
date: x(e.createdAt),
|
|
41
|
-
duration: b(t),
|
|
42
|
-
size: `${(t / 10).toFixed(1)} GB`
|
|
43
|
-
};
|
|
44
|
-
}), [T]), k = D.length ? Math.round(D.map((e) => Number.parseInt(e.duration.split(" ")[0], 10)).reduce((e, t) => e + t, 0) / D.length) : 0;
|
|
45
|
-
return /* @__PURE__ */ c("div", {
|
|
6
|
+
function m() {
|
|
7
|
+
let { showToast: m } = p(), h = () => m("Video meetings are on the CrewFoundry roadmap — coming soon.", "info");
|
|
8
|
+
return /* @__PURE__ */ r("div", {
|
|
46
9
|
className: "space-y-6 p-6",
|
|
47
|
-
children: [
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
className: "flex items-center gap-2",
|
|
65
|
-
children: [
|
|
66
|
-
/* @__PURE__ */ s(l, {
|
|
67
|
-
variant: "secondary",
|
|
68
|
-
className: "text-[10px]",
|
|
69
|
-
children: "Coming soon"
|
|
70
|
-
}),
|
|
71
|
-
/* @__PURE__ */ c(u, {
|
|
72
|
-
variant: "outline",
|
|
73
|
-
size: "sm",
|
|
74
|
-
onClick: E,
|
|
75
|
-
children: [/* @__PURE__ */ s(n, { className: "mr-1 h-4 w-4" }), "Schedule"]
|
|
76
|
-
}),
|
|
77
|
-
/* @__PURE__ */ c(u, {
|
|
78
|
-
size: "sm",
|
|
79
|
-
onClick: E,
|
|
80
|
-
children: [/* @__PURE__ */ s(o, { className: "mr-1 h-4 w-4" }), "Start Meeting"]
|
|
81
|
-
})
|
|
82
|
-
]
|
|
83
|
-
})]
|
|
84
|
-
}),
|
|
85
|
-
/* @__PURE__ */ c("div", {
|
|
86
|
-
className: "grid gap-4 md:grid-cols-3",
|
|
10
|
+
children: [/* @__PURE__ */ r("div", {
|
|
11
|
+
className: "flex items-center justify-between",
|
|
12
|
+
children: [/* @__PURE__ */ r("div", { children: [
|
|
13
|
+
/* @__PURE__ */ n("h1", {
|
|
14
|
+
className: "text-2xl font-semibold",
|
|
15
|
+
children: /* @__PURE__ */ n(u, { children: "Video Calls" })
|
|
16
|
+
}),
|
|
17
|
+
/* @__PURE__ */ n("p", {
|
|
18
|
+
className: "text-sm text-text-secondary",
|
|
19
|
+
children: "Video meetings and recordings"
|
|
20
|
+
}),
|
|
21
|
+
/* @__PURE__ */ n(f, {
|
|
22
|
+
className: "mt-1",
|
|
23
|
+
children: "Host and join video meetings with your teams — schedule a call or start one instantly for face-to-face collaboration."
|
|
24
|
+
})
|
|
25
|
+
] }), /* @__PURE__ */ r("div", {
|
|
26
|
+
className: "flex items-center gap-2",
|
|
87
27
|
children: [
|
|
88
|
-
/* @__PURE__ */
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
children: [/* @__PURE__ */ c(p, {
|
|
93
|
-
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
94
|
-
children: [/* @__PURE__ */ s(m, {
|
|
95
|
-
className: "text-sm font-medium",
|
|
96
|
-
children: "Upcoming"
|
|
97
|
-
}), /* @__PURE__ */ s(n, { className: "h-4 w-4 text-status-info-text" })]
|
|
98
|
-
}), /* @__PURE__ */ c(f, { children: [/* @__PURE__ */ s("div", {
|
|
99
|
-
className: "text-2xl font-bold tabular-nums",
|
|
100
|
-
children: D.length
|
|
101
|
-
}), /* @__PURE__ */ s("p", {
|
|
102
|
-
className: "text-xs text-text-secondary",
|
|
103
|
-
children: "meetings scheduled"
|
|
104
|
-
})] })]
|
|
28
|
+
/* @__PURE__ */ n(i, {
|
|
29
|
+
variant: "secondary",
|
|
30
|
+
className: "text-[10px]",
|
|
31
|
+
children: "Coming soon"
|
|
105
32
|
}),
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
children: [/* @__PURE__ */ s(m, {
|
|
112
|
-
className: "text-sm font-medium",
|
|
113
|
-
children: "Recordings"
|
|
114
|
-
}), /* @__PURE__ */ s(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
115
|
-
}), /* @__PURE__ */ c(f, { children: [/* @__PURE__ */ s("div", {
|
|
116
|
-
className: "text-2xl font-bold tabular-nums",
|
|
117
|
-
children: O.length
|
|
118
|
-
}), /* @__PURE__ */ s("p", {
|
|
119
|
-
className: "text-xs text-text-secondary",
|
|
120
|
-
children: "available"
|
|
121
|
-
})] })]
|
|
33
|
+
/* @__PURE__ */ r(a, {
|
|
34
|
+
variant: "outline",
|
|
35
|
+
size: "sm",
|
|
36
|
+
onClick: h,
|
|
37
|
+
children: [/* @__PURE__ */ n(e, { className: "mr-1 h-4 w-4" }), "Schedule"]
|
|
122
38
|
}),
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
children: [/* @__PURE__ */
|
|
127
|
-
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
128
|
-
children: [/* @__PURE__ */ s(m, {
|
|
129
|
-
className: "text-sm font-medium",
|
|
130
|
-
children: "Avg Duration"
|
|
131
|
-
}), /* @__PURE__ */ s(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
132
|
-
}), /* @__PURE__ */ s(f, { children: /* @__PURE__ */ c("div", {
|
|
133
|
-
className: "text-2xl font-bold tabular-nums",
|
|
134
|
-
children: [k, " min"]
|
|
135
|
-
}) })]
|
|
39
|
+
/* @__PURE__ */ r(a, {
|
|
40
|
+
size: "sm",
|
|
41
|
+
onClick: h,
|
|
42
|
+
children: [/* @__PURE__ */ n(t, { className: "mr-1 h-4 w-4" }), "Start Meeting"]
|
|
136
43
|
})
|
|
137
44
|
]
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
className: "flex items-center gap-3",
|
|
151
|
-
children: [
|
|
152
|
-
/* @__PURE__ */ s("span", {
|
|
153
|
-
className: "text-xs text-text-secondary",
|
|
154
|
-
children: e.time
|
|
155
|
-
}),
|
|
156
|
-
/* @__PURE__ */ s(l, {
|
|
157
|
-
variant: "outline",
|
|
158
|
-
className: "text-[10px]",
|
|
159
|
-
children: e.duration
|
|
160
|
-
}),
|
|
161
|
-
/* @__PURE__ */ c("span", {
|
|
162
|
-
className: "flex items-center gap-1 text-xs",
|
|
163
|
-
children: [/* @__PURE__ */ s(a, { className: "h-3 w-3" }), e.participants]
|
|
164
|
-
}),
|
|
165
|
-
e.recurring && /* @__PURE__ */ s(l, {
|
|
166
|
-
variant: "secondary",
|
|
167
|
-
className: "text-[10px]",
|
|
168
|
-
children: "recurring"
|
|
169
|
-
}),
|
|
170
|
-
/* @__PURE__ */ c(u, {
|
|
171
|
-
size: "sm",
|
|
172
|
-
className: "h-7 text-xs",
|
|
173
|
-
"aria-label": `Join ${e.title} (coming soon)`,
|
|
174
|
-
onClick: E,
|
|
175
|
-
children: [/* @__PURE__ */ s(o, { className: "mr-1 h-3 w-3" }), "Join"]
|
|
176
|
-
})
|
|
177
|
-
]
|
|
178
|
-
})]
|
|
179
|
-
}, e.id))
|
|
180
|
-
})] }),
|
|
181
|
-
/* @__PURE__ */ c(d, { children: [/* @__PURE__ */ s(p, { children: /* @__PURE__ */ s(m, { children: "Recent Recordings" }) }), /* @__PURE__ */ s(f, {
|
|
182
|
-
className: "space-y-3",
|
|
183
|
-
children: O.map((e) => /* @__PURE__ */ c("div", {
|
|
184
|
-
className: "flex items-center justify-between rounded border p-3",
|
|
185
|
-
children: [/* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
|
|
186
|
-
className: "text-sm font-medium",
|
|
187
|
-
children: e.title
|
|
188
|
-
}), /* @__PURE__ */ c("p", {
|
|
189
|
-
className: "text-xs text-text-secondary",
|
|
190
|
-
children: [
|
|
191
|
-
e.date,
|
|
192
|
-
" · ",
|
|
193
|
-
e.duration,
|
|
194
|
-
" · ",
|
|
195
|
-
e.size
|
|
196
|
-
]
|
|
197
|
-
})] }), /* @__PURE__ */ s(u, {
|
|
198
|
-
variant: "outline",
|
|
199
|
-
size: "sm",
|
|
200
|
-
className: "h-7 text-xs",
|
|
201
|
-
"aria-label": `Watch ${e.title} (coming soon)`,
|
|
202
|
-
onClick: E,
|
|
203
|
-
children: "Watch"
|
|
204
|
-
})]
|
|
205
|
-
}, e.id))
|
|
206
|
-
})] })
|
|
207
|
-
]
|
|
45
|
+
})]
|
|
46
|
+
}), /* @__PURE__ */ r(o, { children: [/* @__PURE__ */ n(c, { children: /* @__PURE__ */ n(l, { children: "Meetings & Recordings" }) }), /* @__PURE__ */ n(s, {
|
|
47
|
+
className: "p-0",
|
|
48
|
+
children: /* @__PURE__ */ n("div", {
|
|
49
|
+
className: "p-6",
|
|
50
|
+
children: /* @__PURE__ */ n(d, {
|
|
51
|
+
illustration: "empty-notifications",
|
|
52
|
+
title: "Video meetings are coming soon",
|
|
53
|
+
description: "Scheduling, hosting, and recordings are on the CrewFoundry roadmap. Once the meeting backend ships, your upcoming meetings and recordings will appear here."
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
})] })]
|
|
208
57
|
});
|
|
209
58
|
}
|
|
210
59
|
//#endregion
|
|
211
|
-
export {
|
|
60
|
+
export { m as CommunicationsVideoCallsPagePage };
|
|
212
61
|
|
|
213
62
|
//# sourceMappingURL=CommunicationsVideoCallsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommunicationsVideoCallsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsVideoCallsPagePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, Clock, Monitor, Users, Video } from 'lucide-react';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\ntype Meeting = {\n id: string;\n title: string;\n host: string;\n time: string;\n duration: string;\n participants: number;\n recurring: boolean;\n};\n\ntype Recording = {\n id: string;\n title: string;\n date: string;\n duration: string;\n size: string;\n};\n\nconst formatMeetingDuration = (minutes: number): string => `${Math.max(minutes, 15)} min`;\n\nconst formatRecordingDuration = (minutes: number): string => {\n const safeMinutes = Math.max(minutes, 1);\n const mm = String(safeMinutes).padStart(2, '0');\n const ss = String((safeMinutes * 7) % 60).padStart(2, '0');\n return `${mm}:${ss}`;\n};\n\nconst formatDate = (value: string): string => {\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return 'Upcoming';\n }\n return parsed.toLocaleDateString();\n};\n\nexport function CommunicationsVideoCallsPagePage() {\n const { showToast } = useGlobalUi();\n const { teams, interviews, announcements } = useCrewFoundryStore();\n\n // Video meetings and recordings are a planned surface — there is no meeting\n // backend yet, so these controls honestly signal their roadmap status.\n const notifyComingSoon = () =>\n showToast('Video meetings are on the CrewFoundry roadmap — coming soon.', 'info');\n\n const upcomingMeetings = useMemo<Meeting[]>(() => {\n const teamMeetings = teams.slice(0, 6).map((team, index) => ({\n id: `team-${team.id}`,\n title: `${team.name} Sync`,\n host: team.leadName,\n time: formatDate(team.createdAt),\n duration: formatMeetingDuration(15 + index * 10),\n participants: Math.max(team.memberCount, 2),\n recurring: index % 2 === 0,\n }));\n\n const interviewMeetings = interviews.slice(0, 4).map((interview) => ({\n id: `interview-${interview.id}`,\n title: `Interview · ${interview.candidateName}`,\n host: interview.interviewerName,\n time: formatDate(interview.date),\n duration: formatMeetingDuration(Number.parseInt(interview.time.split(':')[0] || '30', 10)),\n participants: 3,\n recurring: false,\n }));\n\n return [...teamMeetings, ...interviewMeetings];\n }, [interviews, teams]);\n\n const recentRecordings = useMemo<Recording[]>(() => {\n const source = announcements.slice(0, 6);\n return source.map((announcement) => {\n const durationMinutes = Math.max(12, Math.round(announcement.content.length / 40));\n return {\n id: `recording-${announcement.id}`,\n title: `${announcement.title} recording`,\n date: formatDate(announcement.createdAt),\n duration: formatRecordingDuration(durationMinutes),\n size: `${(durationMinutes / 10).toFixed(1)} GB`,\n };\n });\n }, [announcements]);\n\n const averageDurationMinutes = upcomingMeetings.length\n ? Math.round(\n upcomingMeetings\n .map((meeting) => Number.parseInt(meeting.duration.split(' ')[0], 10))\n .reduce((total, value) => total + value, 0) / upcomingMeetings.length\n )\n : 0;\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>Video Calls</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Video meetings and recordings</p>\n <PagePurpose className=\"mt-1\">Host and join video meetings with your teams — schedule a call or start one instantly for face-to-face collaboration.</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 variant=\"outline\" size=\"sm\" onClick={notifyComingSoon}>\n <Calendar className=\"mr-1 h-4 w-4\" />\n Schedule\n </Button>\n <Button size=\"sm\" onClick={notifyComingSoon}>\n <Video className=\"mr-1 h-4 w-4\" />\n Start Meeting\n </Button>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Upcoming</CardTitle>\n <Calendar className=\"h-4 w-4 text-status-info-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{upcomingMeetings.length}</div>\n <p className=\"text-xs text-text-secondary\">meetings scheduled</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Recordings</CardTitle>\n <Monitor className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{recentRecordings.length}</div>\n <p className=\"text-xs text-text-secondary\">available</p>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Avg Duration</CardTitle>\n <Clock className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{averageDurationMinutes} min</div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Upcoming Meetings</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {upcomingMeetings.map((meeting) => (\n <div key={meeting.id} className=\"flex items-center justify-between rounded border p-3\">\n <div>\n <p className=\"text-sm font-medium\">{meeting.title}</p>\n <p className=\"text-xs text-text-secondary\">Hosted by {meeting.host}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs text-text-secondary\">{meeting.time}</span>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {meeting.duration}\n </Badge>\n <span className=\"flex items-center gap-1 text-xs\">\n <Users className=\"h-3 w-3\" />\n {meeting.participants}\n </span>\n {meeting.recurring && (\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n recurring\n </Badge>\n )}\n <Button\n size=\"sm\"\n className=\"h-7 text-xs\"\n aria-label={`Join ${meeting.title} (coming soon)`}\n onClick={notifyComingSoon}\n >\n <Video className=\"mr-1 h-3 w-3\" />\n Join\n </Button>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Recent Recordings</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {recentRecordings.map((recording) => (\n <div\n key={recording.id}\n className=\"flex items-center justify-between rounded border p-3\"\n >\n <div>\n <p className=\"text-sm font-medium\">{recording.title}</p>\n <p className=\"text-xs text-text-secondary\">\n {recording.date} · {recording.duration} · {recording.size}\n </p>\n </div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 text-xs\"\n aria-label={`Watch ${recording.title} (coming soon)`}\n onClick={notifyComingSoon}\n >\n Watch\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CommunicationsVideoCallsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsVideoCallsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, Video } from 'lucide-react';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\n\nexport function CommunicationsVideoCallsPagePage() {\n const { showToast } = useGlobalUi();\n\n // Video meetings and recordings are a planned surface — there is no meeting\n // backend yet, so these controls honestly signal their roadmap status. No\n // meetings or recordings are fabricated in the meantime.\n const notifyComingSoon = () =>\n showToast('Video meetings are 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>Video Calls</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Video meetings and recordings</p>\n <PagePurpose className=\"mt-1\">Host and join video meetings with your teams — schedule a call or start one instantly for face-to-face collaboration.</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 variant=\"outline\" size=\"sm\" onClick={notifyComingSoon}>\n <Calendar className=\"mr-1 h-4 w-4\" />\n Schedule\n </Button>\n <Button size=\"sm\" onClick={notifyComingSoon}>\n <Video className=\"mr-1 h-4 w-4\" />\n Start Meeting\n </Button>\n </div>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Meetings & Recordings</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title=\"Video meetings are coming soon\"\n description=\"Scheduling, hosting, and recordings are on the CrewFoundry roadmap. Once the meeting backend ships, your upcoming meetings and recordings will appear here.\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;AAcA,SAAgB,IAAmC;CACjD,IAAM,EAAE,iBAAc,GAAa,EAK7B,UACJ,EAAU,gEAAgE,OAAO;AAEnF,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,eAA0B,CAAA;KACrC,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAAiC,CAAA;IAC5E,kBAAC,GAAD;KAAa,WAAU;eAAO;KAAmI,CAAA;IAC7J,EAAA,CAAA,EACN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAO,SAAQ;MAAY,WAAU;gBAAc;MAE3C,CAAA;KACR,kBAAC,GAAD;MAAQ,SAAQ;MAAU,MAAK;MAAK,SAAS;gBAA7C,CACE,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA,EAAA,WAE9B;;KACT,kBAAC,GAAD;MAAQ,MAAK;MAAK,SAAS;gBAA3B,CACE,kBAAC,GAAD,EAAO,WAAU,gBAAiB,CAAA,EAAA,gBAE3B;;KACL;MACF;MAEN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,yBAAqC,CAAA,EACrC,CAAA,EACb,kBAAC,GAAD;GAAa,WAAU;aACrB,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,CAAA;IACE,CAAA;GACM,CAAA,CACT,EAAA,CAAA,CACH"}
|