@burdenoff/microfe-crewfoundry 2026.608.1 → 2026.625.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 +94 -78
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +112 -96
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +101 -85
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +131 -115
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +116 -100
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +15 -15
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +63 -51
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +16 -16
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +26 -26
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +28 -28
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +10 -10
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +71 -59
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +59 -47
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +77 -61
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +40 -40
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +13 -13
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +102 -86
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +173 -139
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +59 -59
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +113 -97
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +45 -45
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +85 -69
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +23 -23
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +40 -40
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +59 -47
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +52 -48
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +31 -26
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +61 -49
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +83 -67
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +90 -74
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +90 -74
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +83 -67
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +54 -42
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +16 -16
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +39 -35
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +24 -24
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +14 -14
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +81 -65
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +73 -57
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +28 -28
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +12 -12
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +75 -59
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +57 -45
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +71 -59
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +48 -48
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +44 -43
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +58 -46
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +16 -16
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +23 -23
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +9 -9
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +43 -39
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +31 -27
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +59 -47
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +13 -13
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +66 -50
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +18 -18
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +74 -62
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +21 -21
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +47 -43
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +20 -20
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +58 -46
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +38 -34
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +14 -14
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +67 -67
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +16 -16
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/package.json +2 -2
|
@@ -2,46 +2,46 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
|
2
2
|
import { useMemo as t, useState as n } from "react";
|
|
3
3
|
import { MessageSquare as r, Search as i } from "lucide-react";
|
|
4
4
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
-
import { Badge as s, Button as c, Card as l, CardContent as u, CardHeader as d, CardTitle as f,
|
|
5
|
+
import { Badge as s, Button as c, Card as l, CardContent as u, CardHeader as d, CardTitle as f, GradientText as p, Input as m } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/crewfoundry/pages/CommunicationsMessagesPagePage.tsx
|
|
7
|
-
var
|
|
7
|
+
var h = (e) => {
|
|
8
8
|
let t = new Date(e);
|
|
9
9
|
if (Number.isNaN(t.getTime())) return "Recently";
|
|
10
10
|
let n = Date.now() - t.getTime(), r = Math.max(0, Math.floor(n / (1e3 * 60 * 60)));
|
|
11
11
|
return r < 1 ? "Just now" : r < 24 ? `${r}h ago` : `${Math.floor(r / 24)}d ago`;
|
|
12
12
|
};
|
|
13
|
-
function
|
|
14
|
-
let [
|
|
15
|
-
let e =
|
|
16
|
-
let n =
|
|
13
|
+
function g() {
|
|
14
|
+
let [g, _] = n(""), { teams: v, employees: y, announcements: b, notifications: x } = e(), S = t(() => {
|
|
15
|
+
let e = y.slice(0, 8).map((e, t) => {
|
|
16
|
+
let n = b[t % Math.max(b.length, 1)], r = n?.content || `Status update for ${e.department} initiatives.`;
|
|
17
17
|
return {
|
|
18
18
|
id: `person-${e.id}`,
|
|
19
19
|
name: `${e.firstName} ${e.lastName}`.trim(),
|
|
20
20
|
role: e.position,
|
|
21
21
|
lastMessage: r,
|
|
22
|
-
time:
|
|
22
|
+
time: h(n?.createdAt || e.startDate),
|
|
23
23
|
unread: Math.min(3, Math.round(e.performanceScore) % 4),
|
|
24
24
|
online: e.status === "active" && t % 2 == 0
|
|
25
25
|
};
|
|
26
|
-
}), t =
|
|
27
|
-
let n =
|
|
26
|
+
}), t = v.slice(0, 5).map((e, t) => {
|
|
27
|
+
let n = x.slice(t, t + 3).filter((e) => !e.read).length;
|
|
28
28
|
return {
|
|
29
29
|
id: `team-${e.id}`,
|
|
30
30
|
name: `#${e.name.toLowerCase().replaceAll(" ", "-")}`,
|
|
31
31
|
role: `Channel · ${e.memberCount} members`,
|
|
32
|
-
lastMessage:
|
|
33
|
-
time:
|
|
32
|
+
lastMessage: b[t % Math.max(b.length, 1)]?.title || `${e.leadName} posted an update in ${e.name}.`,
|
|
33
|
+
time: h(e.createdAt),
|
|
34
34
|
unread: n,
|
|
35
35
|
online: !1
|
|
36
36
|
};
|
|
37
37
|
});
|
|
38
38
|
return [...e, ...t];
|
|
39
39
|
}, [
|
|
40
|
-
y,
|
|
41
|
-
v,
|
|
42
40
|
b,
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
y,
|
|
42
|
+
x,
|
|
43
|
+
v
|
|
44
|
+
]).filter((e) => e.name.toLowerCase().includes(g.toLowerCase()));
|
|
45
45
|
return /* @__PURE__ */ o("div", {
|
|
46
46
|
className: "space-y-6 p-6",
|
|
47
47
|
children: [
|
|
@@ -49,9 +49,9 @@ function h() {
|
|
|
49
49
|
className: "flex items-center justify-between",
|
|
50
50
|
children: [/* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("h1", {
|
|
51
51
|
className: "text-2xl font-semibold",
|
|
52
|
-
children: "Messages"
|
|
52
|
+
children: /* @__PURE__ */ a(p, { children: "Messages" })
|
|
53
53
|
}), /* @__PURE__ */ a("p", {
|
|
54
|
-
className: "text-sm text-
|
|
54
|
+
className: "text-sm text-text-secondary",
|
|
55
55
|
children: "Team conversations and channels"
|
|
56
56
|
})] }), /* @__PURE__ */ o(c, {
|
|
57
57
|
size: "sm",
|
|
@@ -60,24 +60,24 @@ function h() {
|
|
|
60
60
|
}),
|
|
61
61
|
/* @__PURE__ */ o("div", {
|
|
62
62
|
className: "relative max-w-sm",
|
|
63
|
-
children: [/* @__PURE__ */ a(i, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-
|
|
63
|
+
children: [/* @__PURE__ */ a(i, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ a(m, {
|
|
64
64
|
placeholder: "Search conversations...",
|
|
65
65
|
className: "pl-9",
|
|
66
|
-
value:
|
|
67
|
-
onChange: (e) =>
|
|
66
|
+
value: g,
|
|
67
|
+
onChange: (e) => _(e.target.value)
|
|
68
68
|
})]
|
|
69
69
|
}),
|
|
70
70
|
/* @__PURE__ */ o(l, { children: [/* @__PURE__ */ a(d, { children: /* @__PURE__ */ a(f, { children: "Conversation Inbox" }) }), /* @__PURE__ */ a(u, {
|
|
71
71
|
className: "p-0",
|
|
72
|
-
children:
|
|
73
|
-
className: "flex cursor-pointer items-center gap-3 border-b p-4 last:border-0 hover:bg-
|
|
72
|
+
children: S.map((e) => /* @__PURE__ */ o("div", {
|
|
73
|
+
className: "flex cursor-pointer items-center gap-3 border-b p-4 last:border-0 hover:bg-bg-sunken/50",
|
|
74
74
|
children: [
|
|
75
75
|
/* @__PURE__ */ o("div", {
|
|
76
76
|
className: "relative",
|
|
77
77
|
children: [/* @__PURE__ */ a("div", {
|
|
78
|
-
className: "flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 text-sm font-medium",
|
|
78
|
+
className: "flex h-10 w-10 items-center justify-center rounded-full bg-action-primary-bg/10 text-sm font-medium",
|
|
79
79
|
children: e.name.startsWith("#") ? "#" : e.name.split(" ").map((e) => e[0]).join("")
|
|
80
|
-
}), e.online && /* @__PURE__ */ a("div", { className: "absolute right-0 bottom-0 h-3 w-3 rounded-full border-2 border-background bg-
|
|
80
|
+
}), 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" })]
|
|
81
81
|
}),
|
|
82
82
|
/* @__PURE__ */ o("div", {
|
|
83
83
|
className: "min-w-0 flex-1",
|
|
@@ -88,16 +88,16 @@ function h() {
|
|
|
88
88
|
className: "text-sm font-medium",
|
|
89
89
|
children: e.name
|
|
90
90
|
}), /* @__PURE__ */ a("span", {
|
|
91
|
-
className: "text-xs text-
|
|
91
|
+
className: "text-xs text-text-secondary",
|
|
92
92
|
children: e.time
|
|
93
93
|
})]
|
|
94
94
|
}),
|
|
95
95
|
/* @__PURE__ */ a("p", {
|
|
96
|
-
className: "text-xs text-
|
|
96
|
+
className: "text-xs text-text-secondary",
|
|
97
97
|
children: e.role
|
|
98
98
|
}),
|
|
99
99
|
/* @__PURE__ */ a("p", {
|
|
100
|
-
className: "mt-0.5 truncate text-xs text-
|
|
100
|
+
className: "mt-0.5 truncate text-xs text-text-secondary",
|
|
101
101
|
children: e.lastMessage
|
|
102
102
|
})
|
|
103
103
|
]
|
|
@@ -113,6 +113,6 @@ function h() {
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
//#endregion
|
|
116
|
-
export {
|
|
116
|
+
export { g as CommunicationsMessagesPagePage };
|
|
117
117
|
|
|
118
118
|
//# 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 Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport { MessageSquare, Search } from 'lucide-react';\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 { teams, employees, announcements, notifications } = useCrewFoundryStore();\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\">Messages</h1>\n <p className=\"text-sm text-
|
|
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 Card,\n CardContent,\n CardHeader,\n CardTitle,\n GradientText,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport { MessageSquare, Search } from 'lucide-react';\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 { teams, employees, announcements, notifications } = useCrewFoundryStore();\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 </div>\n <Button size=\"sm\">\n <MessageSquare className=\"mr-1 h-4 w-4\" />\n New Message\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 conversations...\"\n className=\"pl-9\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Conversation Inbox</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n {filteredConversations.map((conversation) => (\n <div\n key={conversation.id}\n className=\"flex cursor-pointer items-center gap-3 border-b p-4 last:border-0 hover:bg-bg-sunken/50\"\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 </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
2
|
import { FolderKanban as t, Users as n } from "lucide-react";
|
|
3
3
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
4
|
-
import { Badge as a, Card as o, CardContent as s, CardDescription as c, CardHeader as l, CardTitle as u } from "@burdenoff/fe-libs/ui";
|
|
4
|
+
import { Badge as a, Card as o, CardContent as s, CardDescription as c, CardHeader as l, CardTitle as u, GradientText as d } from "@burdenoff/fe-libs/ui";
|
|
5
5
|
//#region src/crewfoundry/pages/CommunicationsTeamsPagePage.tsx
|
|
6
|
-
function
|
|
7
|
-
let { teams:
|
|
6
|
+
function f() {
|
|
7
|
+
let { teams: f } = e();
|
|
8
8
|
return /* @__PURE__ */ i("div", {
|
|
9
9
|
className: "space-y-6 p-6",
|
|
10
10
|
children: [/* @__PURE__ */ i("div", { children: [/* @__PURE__ */ r("h1", {
|
|
11
11
|
className: "text-2xl font-semibold",
|
|
12
|
-
children: "Team Channels"
|
|
12
|
+
children: /* @__PURE__ */ r(d, { children: "Team Channels" })
|
|
13
13
|
}), /* @__PURE__ */ i("p", {
|
|
14
|
-
className: "text-sm text-
|
|
15
|
-
children: [
|
|
14
|
+
className: "text-sm text-text-secondary",
|
|
15
|
+
children: [f.length, " active team channels"]
|
|
16
16
|
})] }), /* @__PURE__ */ r("div", {
|
|
17
17
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
18
|
-
children:
|
|
18
|
+
children: f.map((e) => /* @__PURE__ */ i(o, {
|
|
19
19
|
className: "cursor-pointer hover:shadow-md transition-shadow",
|
|
20
20
|
children: [/* @__PURE__ */ i(l, { children: [/* @__PURE__ */ i("div", {
|
|
21
21
|
className: "flex items-center justify-between",
|
|
@@ -28,7 +28,7 @@ function d() {
|
|
|
28
28
|
children: e.status
|
|
29
29
|
})]
|
|
30
30
|
}), /* @__PURE__ */ r(c, { children: e.description })] }), /* @__PURE__ */ i(s, { children: [/* @__PURE__ */ i("div", {
|
|
31
|
-
className: "flex items-center justify-between text-sm text-
|
|
31
|
+
className: "flex items-center justify-between text-sm text-text-secondary",
|
|
32
32
|
children: [/* @__PURE__ */ i("span", {
|
|
33
33
|
className: "flex items-center gap-1",
|
|
34
34
|
children: [
|
|
@@ -45,7 +45,7 @@ function d() {
|
|
|
45
45
|
]
|
|
46
46
|
})]
|
|
47
47
|
}), /* @__PURE__ */ i("div", {
|
|
48
|
-
className: "mt-2 text-xs text-
|
|
48
|
+
className: "mt-2 text-xs text-text-secondary",
|
|
49
49
|
children: [
|
|
50
50
|
/* @__PURE__ */ i("span", { children: ["Lead: ", e.leadName] }),
|
|
51
51
|
" · ",
|
|
@@ -57,6 +57,6 @@ function d() {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
//#endregion
|
|
60
|
-
export {
|
|
60
|
+
export { f as CommunicationsTeamsPagePage };
|
|
61
61
|
|
|
62
62
|
//# sourceMappingURL=CommunicationsTeamsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommunicationsTeamsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsTeamsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\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\">Team Channels</h1>\n <p className=\"text-sm text-
|
|
1
|
+
{"version":3,"file":"CommunicationsTeamsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CommunicationsTeamsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GradientText,\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 <GradientText>Team Channels</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{teams.length} active team channels</p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {teams.map((team) => (\n <Card key={team.id} className=\"cursor-pointer hover:shadow-md transition-shadow\">\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 </Card>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAYA,SAAgB,IAA8B;CAC5C,IAAM,EAAE,aAAU,GAAqB;AAEvC,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;aACZ,kBAAC,GAAD,EAAA,UAAc,iBAA4B,CAAA;GACvC,CAAA,EACL,kBAAC,KAAD;GAAG,WAAU;aAAb,CAA4C,EAAM,QAAO,wBAAyB;KAC9E,EAAA,CAAA,EACN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAM,KAAK,MACV,kBAAC,GAAD;IAAoB,WAAU;cAA9B,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAW,WAAU;gBAAa,EAAK;MAAiB,CAAA,EACxD,kBAAC,GAAD;MACE,SAAS,EAAK,WAAW,WAAW,YAAY;MAChD,WAAU;gBAET,EAAK;MACA,CAAA,CACJ;QACN,kBAAC,GAAD,EAAA,UAAkB,EAAK,aAA8B,CAAA,CAC1C,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;OAC5B,EAAK;OAAY;OACb;SACP,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA;OACnC,EAAK;OAAa;OACd;QACH;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,QAAD,EAAA,UAAA,CAAM,UAAO,EAAK,SAAgB,EAAA,CAAA;;MAAG,kBAAC,QAAD,EAAA,UAAO,EAAK,YAAkB,CAAA;MAC/D;OACM,EAAA,CAAA,CACT;MA5BI,EAAK,GA4BT,CACP;GACE,CAAA,CACF"}
|
|
@@ -2,45 +2,45 @@ import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
|
2
2
|
import { useMemo as t } from "react";
|
|
3
3
|
import { Calendar as n, Clock as r, Monitor as i, Users as a, Video as o } from "lucide-react";
|
|
4
4
|
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
5
|
-
import { Badge as l, Button as u, Card as d, CardContent as f, CardHeader as p, CardTitle as m } from "@burdenoff/fe-libs/ui";
|
|
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 } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/crewfoundry/pages/CommunicationsVideoCallsPagePage.tsx
|
|
7
|
-
var
|
|
7
|
+
var _ = (e) => `${Math.max(e, 15)} min`, v = (e) => {
|
|
8
8
|
let t = Math.max(e, 1);
|
|
9
9
|
return `${String(t).padStart(2, "0")}:${String(t * 7 % 60).padStart(2, "0")}`;
|
|
10
|
-
},
|
|
10
|
+
}, y = (e) => {
|
|
11
11
|
let t = new Date(e);
|
|
12
12
|
return Number.isNaN(t.getTime()) ? "Upcoming" : t.toLocaleDateString();
|
|
13
13
|
};
|
|
14
|
-
function
|
|
15
|
-
let { teams:
|
|
16
|
-
let e =
|
|
14
|
+
function b() {
|
|
15
|
+
let { teams: b, interviews: x, announcements: S } = e(), C = t(() => {
|
|
16
|
+
let e = b.slice(0, 6).map((e, t) => ({
|
|
17
17
|
id: `team-${e.id}`,
|
|
18
18
|
title: `${e.name} Sync`,
|
|
19
19
|
host: e.leadName,
|
|
20
|
-
time:
|
|
21
|
-
duration:
|
|
20
|
+
time: y(e.createdAt),
|
|
21
|
+
duration: _(15 + t * 10),
|
|
22
22
|
participants: Math.max(e.memberCount, 2),
|
|
23
23
|
recurring: t % 2 == 0
|
|
24
|
-
})), t =
|
|
24
|
+
})), t = x.slice(0, 4).map((e) => ({
|
|
25
25
|
id: `interview-${e.id}`,
|
|
26
26
|
title: `Interview · ${e.candidateName}`,
|
|
27
27
|
host: e.interviewerName,
|
|
28
|
-
time:
|
|
29
|
-
duration:
|
|
28
|
+
time: y(e.date),
|
|
29
|
+
duration: _(Number.parseInt(e.time.split(":")[0] || "30", 10)),
|
|
30
30
|
participants: 3,
|
|
31
31
|
recurring: !1
|
|
32
32
|
}));
|
|
33
33
|
return [...e, ...t];
|
|
34
|
-
}, [
|
|
34
|
+
}, [x, b]), w = t(() => S.slice(0, 6).map((e) => {
|
|
35
35
|
let t = Math.max(12, Math.round(e.content.length / 40));
|
|
36
36
|
return {
|
|
37
37
|
id: `recording-${e.id}`,
|
|
38
38
|
title: `${e.title} recording`,
|
|
39
|
-
date:
|
|
40
|
-
duration:
|
|
39
|
+
date: y(e.createdAt),
|
|
40
|
+
duration: v(t),
|
|
41
41
|
size: `${(t / 10).toFixed(1)} GB`
|
|
42
42
|
};
|
|
43
|
-
}), [
|
|
43
|
+
}), [S]), T = C.length ? Math.round(C.map((e) => Number.parseInt(e.duration.split(" ")[0], 10)).reduce((e, t) => e + t, 0) / C.length) : 0;
|
|
44
44
|
return /* @__PURE__ */ c("div", {
|
|
45
45
|
className: "space-y-6 p-6",
|
|
46
46
|
children: [
|
|
@@ -48,9 +48,9 @@ function v() {
|
|
|
48
48
|
className: "flex items-center justify-between",
|
|
49
49
|
children: [/* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("h1", {
|
|
50
50
|
className: "text-2xl font-semibold",
|
|
51
|
-
children: "Video Calls"
|
|
51
|
+
children: /* @__PURE__ */ s(g, { children: "Video Calls" })
|
|
52
52
|
}), /* @__PURE__ */ s("p", {
|
|
53
|
-
className: "text-sm text-
|
|
53
|
+
className: "text-sm text-text-secondary",
|
|
54
54
|
children: "Video meetings and recordings"
|
|
55
55
|
})] }), /* @__PURE__ */ c("div", {
|
|
56
56
|
className: "flex gap-2",
|
|
@@ -67,59 +67,71 @@ function v() {
|
|
|
67
67
|
/* @__PURE__ */ c("div", {
|
|
68
68
|
className: "grid gap-4 md:grid-cols-3",
|
|
69
69
|
children: [
|
|
70
|
-
/* @__PURE__ */ c(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
70
|
+
/* @__PURE__ */ c(h, {
|
|
71
|
+
treatment: "metric",
|
|
72
|
+
className: "border-border-seam",
|
|
73
|
+
children: [/* @__PURE__ */ c(p, {
|
|
74
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
75
|
+
children: [/* @__PURE__ */ s(m, {
|
|
76
|
+
className: "text-sm font-medium",
|
|
77
|
+
children: "Upcoming"
|
|
78
|
+
}), /* @__PURE__ */ s(n, { className: "h-4 w-4 text-status-info-text" })]
|
|
79
|
+
}), /* @__PURE__ */ c(f, { children: [/* @__PURE__ */ s("div", {
|
|
80
|
+
className: "text-2xl font-bold tabular-nums",
|
|
81
|
+
children: C.length
|
|
82
|
+
}), /* @__PURE__ */ s("p", {
|
|
83
|
+
className: "text-xs text-text-secondary",
|
|
84
|
+
children: "meetings scheduled"
|
|
85
|
+
})] })]
|
|
86
|
+
}),
|
|
87
|
+
/* @__PURE__ */ c(h, {
|
|
88
|
+
treatment: "metric",
|
|
89
|
+
className: "border-border-seam",
|
|
90
|
+
children: [/* @__PURE__ */ c(p, {
|
|
91
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
92
|
+
children: [/* @__PURE__ */ s(m, {
|
|
93
|
+
className: "text-sm font-medium",
|
|
94
|
+
children: "Recordings"
|
|
95
|
+
}), /* @__PURE__ */ s(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
96
|
+
}), /* @__PURE__ */ c(f, { children: [/* @__PURE__ */ s("div", {
|
|
97
|
+
className: "text-2xl font-bold tabular-nums",
|
|
98
|
+
children: w.length
|
|
99
|
+
}), /* @__PURE__ */ s("p", {
|
|
100
|
+
className: "text-xs text-text-secondary",
|
|
101
|
+
children: "available"
|
|
102
|
+
})] })]
|
|
103
|
+
}),
|
|
104
|
+
/* @__PURE__ */ c(h, {
|
|
105
|
+
treatment: "metric",
|
|
106
|
+
className: "border-border-seam",
|
|
107
|
+
children: [/* @__PURE__ */ c(p, {
|
|
108
|
+
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
109
|
+
children: [/* @__PURE__ */ s(m, {
|
|
110
|
+
className: "text-sm font-medium",
|
|
111
|
+
children: "Avg Duration"
|
|
112
|
+
}), /* @__PURE__ */ s(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
113
|
+
}), /* @__PURE__ */ s(f, { children: /* @__PURE__ */ c("div", {
|
|
114
|
+
className: "text-2xl font-bold tabular-nums",
|
|
115
|
+
children: [T, " min"]
|
|
116
|
+
}) })]
|
|
117
|
+
})
|
|
106
118
|
]
|
|
107
119
|
}),
|
|
108
120
|
/* @__PURE__ */ c(d, { children: [/* @__PURE__ */ s(p, { children: /* @__PURE__ */ s(m, { children: "Upcoming Meetings" }) }), /* @__PURE__ */ s(f, {
|
|
109
121
|
className: "space-y-3",
|
|
110
|
-
children:
|
|
122
|
+
children: C.map((e) => /* @__PURE__ */ c("div", {
|
|
111
123
|
className: "flex items-center justify-between rounded border p-3",
|
|
112
124
|
children: [/* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
|
|
113
125
|
className: "text-sm font-medium",
|
|
114
126
|
children: e.title
|
|
115
127
|
}), /* @__PURE__ */ c("p", {
|
|
116
|
-
className: "text-xs text-
|
|
128
|
+
className: "text-xs text-text-secondary",
|
|
117
129
|
children: ["Hosted by ", e.host]
|
|
118
130
|
})] }), /* @__PURE__ */ c("div", {
|
|
119
131
|
className: "flex items-center gap-3",
|
|
120
132
|
children: [
|
|
121
133
|
/* @__PURE__ */ s("span", {
|
|
122
|
-
className: "text-xs text-
|
|
134
|
+
className: "text-xs text-text-secondary",
|
|
123
135
|
children: e.time
|
|
124
136
|
}),
|
|
125
137
|
/* @__PURE__ */ s(l, {
|
|
@@ -147,13 +159,13 @@ function v() {
|
|
|
147
159
|
})] }),
|
|
148
160
|
/* @__PURE__ */ c(d, { children: [/* @__PURE__ */ s(p, { children: /* @__PURE__ */ s(m, { children: "Recent Recordings" }) }), /* @__PURE__ */ s(f, {
|
|
149
161
|
className: "space-y-3",
|
|
150
|
-
children:
|
|
162
|
+
children: w.map((e) => /* @__PURE__ */ c("div", {
|
|
151
163
|
className: "flex items-center justify-between rounded border p-3",
|
|
152
164
|
children: [/* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
|
|
153
165
|
className: "text-sm font-medium",
|
|
154
166
|
children: e.title
|
|
155
167
|
}), /* @__PURE__ */ c("p", {
|
|
156
|
-
className: "text-xs text-
|
|
168
|
+
className: "text-xs text-text-secondary",
|
|
157
169
|
children: [
|
|
158
170
|
e.date,
|
|
159
171
|
" · ",
|
|
@@ -173,6 +185,6 @@ function v() {
|
|
|
173
185
|
});
|
|
174
186
|
}
|
|
175
187
|
//#endregion
|
|
176
|
-
export {
|
|
188
|
+
export { b as CommunicationsVideoCallsPagePage };
|
|
177
189
|
|
|
178
190
|
//# 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 { Badge, Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Calendar, Clock, Monitor, Users, Video } from 'lucide-react';\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 { teams, interviews, announcements } = useCrewFoundryStore();\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\">Video Calls</h1>\n <p className=\"text-sm text-muted-foreground\">Video meetings and recordings</p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Calendar className=\"mr-1 h-4 w-4\" />\n Schedule\n </Button>\n <Button size=\"sm\">\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 <Card>\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-blue-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{upcomingMeetings.length}</div>\n <p className=\"text-xs text-muted-foreground\">meetings scheduled</p>\n </CardContent>\n </Card>\n <Card>\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-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{recentRecordings.length}</div>\n <p className=\"text-xs text-muted-foreground\">available</p>\n </CardContent>\n </Card>\n <Card>\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-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{averageDurationMinutes} min</div>\n </CardContent>\n </Card>\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-muted-foreground\">Hosted by {meeting.host}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs text-muted-foreground\">{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 size=\"sm\" className=\"h-7 text-xs\">\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-muted-foreground\">\n {recording.date} · {recording.duration} · {recording.size}\n </p>\n </div>\n <Button variant=\"outline\" size=\"sm\" className=\"h-7 text-xs\">\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 { useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, Clock, Monitor, Users, Video } from 'lucide-react';\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 { teams, interviews, announcements } = useCrewFoundryStore();\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 </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Calendar className=\"mr-1 h-4 w-4\" />\n Schedule\n </Button>\n <Button size=\"sm\">\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=\"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\">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 size=\"sm\" className=\"h-7 text-xs\">\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 variant=\"outline\" size=\"sm\" className=\"h-7 text-xs\">\n Watch\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|