@burdenoff/microfe-crewfoundry 2026.626.1 → 2026.703.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/components/forms/ConfirmDialog.js +43 -0
- package/dist/crewfoundry/components/forms/ConfirmDialog.js.map +1 -0
- package/dist/crewfoundry/components/forms/FormModal.js +220 -0
- package/dist/crewfoundry/components/forms/FormModal.js.map +1 -0
- package/dist/crewfoundry/components/forms/formValues.js +20 -0
- package/dist/crewfoundry/components/forms/formValues.js.map +1 -0
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +255 -65
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +28 -17
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +57 -53
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +32 -23
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +44 -29
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +183 -57
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +214 -92
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +165 -131
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +163 -133
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +269 -54
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +225 -78
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +213 -59
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +287 -90
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +49 -47
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +166 -59
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +274 -83
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +198 -88
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +216 -88
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +216 -66
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +6 -7
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +83 -68
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +167 -46
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +75 -55
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +152 -79
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +75 -63
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +3 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +235 -87
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +199 -86
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +21 -40
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +117 -45
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +249 -90
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +47 -45
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +262 -133
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +144 -77
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +306 -51
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/package.json +1 -1
|
@@ -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 { 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 <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 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=\"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 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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"}
|
|
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,129 +1,218 @@
|
|
|
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 { Building2 as r, DollarSign as i, FolderKanban as a, Pencil as o, Plus as s, Trash2 as c } from "lucide-react";
|
|
4
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
5
|
+
import { AlertDialog as d, AlertDialogAction as f, AlertDialogCancel as p, AlertDialogContent as m, AlertDialogDescription as h, AlertDialogFooter as g, AlertDialogHeader as _, AlertDialogTitle as v, AlertDialogTrigger as y, Badge as b, Button as x, Card as S, CardContent as C, CardHeader as w, CardTitle as T, GlassCard as E, GradientText as D, PagePurpose as O } from "@burdenoff/fe-libs/ui";
|
|
5
6
|
//#region src/crewfoundry/pages/CompanyClientManagementPagePage.tsx
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
var k = [
|
|
8
|
+
{
|
|
9
|
+
name: "name",
|
|
10
|
+
label: "Client name",
|
|
11
|
+
type: "text",
|
|
12
|
+
required: !0
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: "industry",
|
|
16
|
+
label: "Industry",
|
|
17
|
+
type: "text"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "contactPerson",
|
|
21
|
+
label: "Contact person",
|
|
22
|
+
type: "text"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "email",
|
|
26
|
+
label: "Contact email",
|
|
27
|
+
type: "email"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "phone",
|
|
31
|
+
label: "Phone",
|
|
32
|
+
type: "text"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "status",
|
|
36
|
+
label: "Status",
|
|
37
|
+
type: "select",
|
|
38
|
+
options: [
|
|
39
|
+
{
|
|
40
|
+
label: "Active",
|
|
41
|
+
value: "active"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: "Prospect",
|
|
45
|
+
value: "prospect"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
label: "Churned",
|
|
49
|
+
value: "churned"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "revenue",
|
|
55
|
+
label: "Revenue (USD)",
|
|
56
|
+
type: "number"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "projects",
|
|
60
|
+
label: "Projects",
|
|
61
|
+
type: "number"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "since",
|
|
65
|
+
label: "Client since",
|
|
66
|
+
type: "date"
|
|
67
|
+
}
|
|
68
|
+
], A = (e) => ({
|
|
69
|
+
name: e.name,
|
|
70
|
+
industry: e.industry,
|
|
71
|
+
contactPerson: e.contactPerson,
|
|
72
|
+
email: e.email,
|
|
73
|
+
phone: e.phone,
|
|
74
|
+
status: e.status,
|
|
75
|
+
revenue: e.revenue,
|
|
76
|
+
projects: e.projects,
|
|
77
|
+
since: e.since ? e.since.slice(0, 10) : ""
|
|
78
|
+
}), j = (e, t) => ({
|
|
79
|
+
id: t?.id ?? crypto.randomUUID(),
|
|
80
|
+
name: String(e.name ?? ""),
|
|
81
|
+
industry: String(e.industry ?? ""),
|
|
82
|
+
contactPerson: String(e.contactPerson ?? ""),
|
|
83
|
+
email: String(e.email ?? ""),
|
|
84
|
+
phone: String(e.phone ?? ""),
|
|
85
|
+
status: e.status || "prospect",
|
|
86
|
+
revenue: typeof e.revenue == "number" ? e.revenue : Number(e.revenue) || 0,
|
|
87
|
+
projects: typeof e.projects == "number" ? e.projects : Number(e.projects) || 0,
|
|
88
|
+
since: String(e.since ?? "")
|
|
89
|
+
});
|
|
90
|
+
function M() {
|
|
91
|
+
let { clients: M, addClient: N, updateClient: P, removeClient: F } = e(), I = n(), L = M.reduce((e, t) => e + t.revenue, 0), R = M.filter((e) => e.status === "active");
|
|
92
|
+
return /* @__PURE__ */ u("div", {
|
|
9
93
|
className: "space-y-6 p-6",
|
|
10
94
|
children: [
|
|
11
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ u("div", {
|
|
12
96
|
className: "flex items-center justify-between",
|
|
13
|
-
children: [/* @__PURE__ */
|
|
14
|
-
/* @__PURE__ */
|
|
97
|
+
children: [/* @__PURE__ */ u("div", { children: [
|
|
98
|
+
/* @__PURE__ */ l("h1", {
|
|
15
99
|
className: "text-2xl font-semibold",
|
|
16
|
-
children: /* @__PURE__ */
|
|
100
|
+
children: /* @__PURE__ */ l(D, { children: "Client Management" })
|
|
17
101
|
}),
|
|
18
|
-
/* @__PURE__ */
|
|
102
|
+
/* @__PURE__ */ u("p", {
|
|
19
103
|
className: "text-sm text-text-secondary",
|
|
20
104
|
children: [
|
|
21
|
-
|
|
105
|
+
M.length,
|
|
22
106
|
" clients · $",
|
|
23
|
-
(
|
|
107
|
+
(L / 1e6).toFixed(1),
|
|
24
108
|
"M revenue"
|
|
25
109
|
]
|
|
26
110
|
}),
|
|
27
|
-
/* @__PURE__ */
|
|
111
|
+
/* @__PURE__ */ l(O, {
|
|
28
112
|
className: "mt-1",
|
|
29
113
|
children: "Keep track of the clients you work with — their contacts, status, and engagements — so account relationships never slip through the cracks."
|
|
30
114
|
})
|
|
31
|
-
] }), /* @__PURE__ */
|
|
115
|
+
] }), /* @__PURE__ */ u(x, {
|
|
32
116
|
size: "sm",
|
|
33
|
-
|
|
117
|
+
onClick: () => I.openModal(),
|
|
118
|
+
children: [/* @__PURE__ */ l(s, { className: "h-4 w-4 mr-1" }), "Add Client"]
|
|
34
119
|
})]
|
|
35
120
|
}),
|
|
36
|
-
/* @__PURE__ */
|
|
121
|
+
/* @__PURE__ */ u("div", {
|
|
37
122
|
className: "grid gap-4 md:grid-cols-3",
|
|
38
123
|
children: [
|
|
39
|
-
/* @__PURE__ */
|
|
124
|
+
/* @__PURE__ */ u(E, {
|
|
40
125
|
treatment: "glass",
|
|
41
126
|
glow: !0,
|
|
42
127
|
className: "border-border-seam",
|
|
43
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ u(w, {
|
|
44
129
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
45
|
-
children: [/* @__PURE__ */
|
|
130
|
+
children: [/* @__PURE__ */ l(T, {
|
|
46
131
|
className: "text-sm font-medium",
|
|
47
132
|
children: "Active Clients"
|
|
48
|
-
}), /* @__PURE__ */
|
|
49
|
-
}), /* @__PURE__ */
|
|
133
|
+
}), /* @__PURE__ */ l(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
134
|
+
}), /* @__PURE__ */ l(C, { children: /* @__PURE__ */ l("div", {
|
|
50
135
|
className: "text-2xl font-bold tabular-nums",
|
|
51
|
-
children:
|
|
136
|
+
children: R.length
|
|
52
137
|
}) })]
|
|
53
138
|
}),
|
|
54
|
-
/* @__PURE__ */
|
|
139
|
+
/* @__PURE__ */ u(E, {
|
|
55
140
|
treatment: "metric",
|
|
56
141
|
className: "border-border-seam",
|
|
57
|
-
children: [/* @__PURE__ */
|
|
142
|
+
children: [/* @__PURE__ */ u(w, {
|
|
58
143
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
59
|
-
children: [/* @__PURE__ */
|
|
144
|
+
children: [/* @__PURE__ */ l(T, {
|
|
60
145
|
className: "text-sm font-medium",
|
|
61
146
|
children: "Total Revenue"
|
|
62
|
-
}), /* @__PURE__ */
|
|
63
|
-
}), /* @__PURE__ */
|
|
147
|
+
}), /* @__PURE__ */ l(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
148
|
+
}), /* @__PURE__ */ l(C, { children: /* @__PURE__ */ u("div", {
|
|
64
149
|
className: "text-2xl font-bold tabular-nums",
|
|
65
150
|
children: [
|
|
66
151
|
"$",
|
|
67
|
-
(
|
|
152
|
+
(L / 1e6).toFixed(1),
|
|
68
153
|
"M"
|
|
69
154
|
]
|
|
70
155
|
}) })]
|
|
71
156
|
}),
|
|
72
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ u(E, {
|
|
73
158
|
treatment: "metric",
|
|
74
159
|
className: "border-border-seam",
|
|
75
|
-
children: [/* @__PURE__ */
|
|
160
|
+
children: [/* @__PURE__ */ u(w, {
|
|
76
161
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
77
|
-
children: [/* @__PURE__ */
|
|
162
|
+
children: [/* @__PURE__ */ l(T, {
|
|
78
163
|
className: "text-sm font-medium",
|
|
79
164
|
children: "Total Projects"
|
|
80
|
-
}), /* @__PURE__ */ a
|
|
81
|
-
}), /* @__PURE__ */
|
|
165
|
+
}), /* @__PURE__ */ l(a, { className: "h-4 w-4 text-text-secondary" })]
|
|
166
|
+
}), /* @__PURE__ */ l(C, { children: /* @__PURE__ */ l("div", {
|
|
82
167
|
className: "text-2xl font-bold tabular-nums",
|
|
83
|
-
children:
|
|
168
|
+
children: M.reduce((e, t) => e + t.projects, 0)
|
|
84
169
|
}) })]
|
|
85
170
|
})
|
|
86
171
|
]
|
|
87
172
|
}),
|
|
88
|
-
/* @__PURE__ */
|
|
89
|
-
className: "grid grid-cols-
|
|
173
|
+
/* @__PURE__ */ u(S, { children: [/* @__PURE__ */ l(w, { children: /* @__PURE__ */ l(T, { children: "Client Portfolio" }) }), /* @__PURE__ */ u(C, { children: [/* @__PURE__ */ u("div", {
|
|
174
|
+
className: "grid grid-cols-8 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2",
|
|
90
175
|
children: [
|
|
91
|
-
/* @__PURE__ */
|
|
92
|
-
/* @__PURE__ */
|
|
93
|
-
/* @__PURE__ */
|
|
94
|
-
/* @__PURE__ */
|
|
176
|
+
/* @__PURE__ */ l("span", { children: "Client" }),
|
|
177
|
+
/* @__PURE__ */ l("span", { children: "Industry" }),
|
|
178
|
+
/* @__PURE__ */ l("span", { children: "Contact" }),
|
|
179
|
+
/* @__PURE__ */ l("span", {
|
|
95
180
|
className: "text-right",
|
|
96
181
|
children: "Revenue"
|
|
97
182
|
}),
|
|
98
|
-
/* @__PURE__ */
|
|
183
|
+
/* @__PURE__ */ l("span", {
|
|
99
184
|
className: "text-right",
|
|
100
185
|
children: "Projects"
|
|
101
186
|
}),
|
|
102
|
-
/* @__PURE__ */
|
|
103
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ l("span", { children: "Since" }),
|
|
188
|
+
/* @__PURE__ */ l("span", {
|
|
104
189
|
className: "text-center",
|
|
105
190
|
children: "Status"
|
|
191
|
+
}),
|
|
192
|
+
/* @__PURE__ */ l("span", {
|
|
193
|
+
className: "text-right",
|
|
194
|
+
children: "Actions"
|
|
106
195
|
})
|
|
107
196
|
]
|
|
108
|
-
}),
|
|
109
|
-
className: "grid grid-cols-
|
|
197
|
+
}), M.map((e) => /* @__PURE__ */ u("div", {
|
|
198
|
+
className: "grid grid-cols-8 gap-2 py-2 border-b last:border-0 text-sm",
|
|
110
199
|
children: [
|
|
111
|
-
/* @__PURE__ */
|
|
200
|
+
/* @__PURE__ */ l("span", {
|
|
112
201
|
className: "font-medium",
|
|
113
202
|
children: e.name
|
|
114
203
|
}),
|
|
115
|
-
/* @__PURE__ */
|
|
204
|
+
/* @__PURE__ */ l("span", {
|
|
116
205
|
className: "text-text-secondary",
|
|
117
206
|
children: e.industry
|
|
118
207
|
}),
|
|
119
|
-
/* @__PURE__ */
|
|
208
|
+
/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
|
|
120
209
|
className: "text-xs",
|
|
121
210
|
children: e.contactPerson
|
|
122
|
-
}), /* @__PURE__ */
|
|
211
|
+
}), /* @__PURE__ */ l("p", {
|
|
123
212
|
className: "text-xs text-text-secondary",
|
|
124
213
|
children: e.email
|
|
125
214
|
})] }),
|
|
126
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ u("span", {
|
|
127
216
|
className: "text-right",
|
|
128
217
|
children: [
|
|
129
218
|
"$",
|
|
@@ -131,28 +220,65 @@ function g() {
|
|
|
131
220
|
"K"
|
|
132
221
|
]
|
|
133
222
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
223
|
+
/* @__PURE__ */ l("span", {
|
|
135
224
|
className: "text-right",
|
|
136
225
|
children: e.projects
|
|
137
226
|
}),
|
|
138
|
-
/* @__PURE__ */
|
|
227
|
+
/* @__PURE__ */ l("span", {
|
|
139
228
|
className: "text-text-secondary",
|
|
140
229
|
children: e.since
|
|
141
230
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
231
|
+
/* @__PURE__ */ l("div", {
|
|
143
232
|
className: "text-center",
|
|
144
|
-
children: /* @__PURE__ */
|
|
233
|
+
children: /* @__PURE__ */ l(b, {
|
|
145
234
|
variant: e.status === "active" ? "default" : e.status === "prospect" ? "secondary" : "destructive",
|
|
146
235
|
className: "text-[10px]",
|
|
147
236
|
children: e.status
|
|
148
237
|
})
|
|
238
|
+
}),
|
|
239
|
+
/* @__PURE__ */ u("div", {
|
|
240
|
+
className: "flex items-center justify-end gap-1",
|
|
241
|
+
children: [/* @__PURE__ */ l(x, {
|
|
242
|
+
variant: "ghost",
|
|
243
|
+
size: "icon",
|
|
244
|
+
"aria-label": `Edit ${e.name}`,
|
|
245
|
+
onClick: () => I.openModal(e),
|
|
246
|
+
children: /* @__PURE__ */ l(o, { className: "h-4 w-4" })
|
|
247
|
+
}), /* @__PURE__ */ u(d, { children: [/* @__PURE__ */ l(y, {
|
|
248
|
+
asChild: !0,
|
|
249
|
+
children: /* @__PURE__ */ l(x, {
|
|
250
|
+
variant: "ghost",
|
|
251
|
+
size: "icon",
|
|
252
|
+
"aria-label": `Delete ${e.name}`,
|
|
253
|
+
children: /* @__PURE__ */ l(c, { className: "h-4 w-4 text-status-error-text" })
|
|
254
|
+
})
|
|
255
|
+
}), /* @__PURE__ */ u(m, { children: [/* @__PURE__ */ u(_, { children: [/* @__PURE__ */ l(v, { children: "Delete client?" }), /* @__PURE__ */ u(h, { children: [
|
|
256
|
+
"This removes “",
|
|
257
|
+
e.name,
|
|
258
|
+
"” from your client portfolio. This action cannot be undone."
|
|
259
|
+
] })] }), /* @__PURE__ */ u(g, { children: [/* @__PURE__ */ l(p, { children: "Cancel" }), /* @__PURE__ */ l(f, {
|
|
260
|
+
onClick: () => void F(e.id),
|
|
261
|
+
children: "Delete"
|
|
262
|
+
})] })] })] })]
|
|
149
263
|
})
|
|
150
264
|
]
|
|
151
|
-
}, e.id))] })] })
|
|
265
|
+
}, e.id))] })] }),
|
|
266
|
+
/* @__PURE__ */ l(t, {
|
|
267
|
+
open: I.open,
|
|
268
|
+
onOpenChange: I.onOpenChange,
|
|
269
|
+
title: I.context ? "Edit client" : "Add client",
|
|
270
|
+
description: "Track the client relationship, contacts, and engagement value.",
|
|
271
|
+
fields: k,
|
|
272
|
+
initialValues: I.context ? A(I.context) : void 0,
|
|
273
|
+
submitLabel: I.context ? "Save changes" : "Add client",
|
|
274
|
+
onSubmit: async (e) => {
|
|
275
|
+
I.context ? await P(I.context.id, j(e, I.context)) : await N(j(e));
|
|
276
|
+
}
|
|
277
|
+
})
|
|
152
278
|
]
|
|
153
279
|
});
|
|
154
280
|
}
|
|
155
281
|
//#endregion
|
|
156
|
-
export {
|
|
282
|
+
export { M as CompanyClientManagementPagePage };
|
|
157
283
|
|
|
158
284
|
//# sourceMappingURL=CompanyClientManagementPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanyClientManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CompanyClientManagementPagePage.tsx"],"sourcesContent":["import {\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 { Building2, DollarSign, FolderKanban, Plus } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function CompanyClientManagementPagePage() {\n const { clients } = useCrewFoundryStore();\n const totalRevenue = clients.reduce((s, c) => s + c.revenue, 0);\n const activeClients = clients.filter((c) => c.status === 'active');\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>Client Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {clients.length} clients · ${(totalRevenue / 1000000).toFixed(1)}M revenue\n </p>\n <PagePurpose className=\"mt-1\">Keep track of the clients you work with — their contacts, status, and engagements — so account relationships never slip through the cracks.</PagePurpose>\n </div>\n <Button size=\"sm\">\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Client\n </Button>\n </div>\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\">Active Clients</CardTitle>\n <Building2 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activeClients.length}</div>\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\">Total Revenue</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalRevenue / 1000000).toFixed(1)}M\n </div>\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\">Total Projects</CardTitle>\n <FolderKanban className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {clients.reduce((s, c) => s + c.projects, 0)}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n <Card>\n <CardHeader>\n <CardTitle>Client Portfolio</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-7 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Client</span>\n <span>Industry</span>\n <span>Contact</span>\n <span className=\"text-right\">Revenue</span>\n <span className=\"text-right\">Projects</span>\n <span>Since</span>\n <span className=\"text-center\">Status</span>\n </div>\n {clients.map((c) => (\n <div key={c.id} className=\"grid grid-cols-7 gap-2 py-2 border-b last:border-0 text-sm\">\n <span className=\"font-medium\">{c.name}</span>\n <span className=\"text-text-secondary\">{c.industry}</span>\n <div>\n <p className=\"text-xs\">{c.contactPerson}</p>\n <p className=\"text-xs text-text-secondary\">{c.email}</p>\n </div>\n <span className=\"text-right\">${(c.revenue / 1000).toFixed(0)}K</span>\n <span className=\"text-right\">{c.projects}</span>\n <span className=\"text-text-secondary\">{c.since}</span>\n <div className=\"text-center\">\n <Badge\n variant={\n c.status === 'active'\n ? 'default'\n : c.status === 'prospect'\n ? 'secondary'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {c.status}\n </Badge>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CompanyClientManagementPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CompanyClientManagementPagePage.tsx"],"sourcesContent":["import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\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 { Building2, DollarSign, FolderKanban, Pencil, Plus, Trash2 } from 'lucide-react';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Client } from '../store/crewfoundryStore';\n\nconst CLIENT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Client name', type: 'text', required: true },\n { name: 'industry', label: 'Industry', type: 'text' },\n { name: 'contactPerson', label: 'Contact person', type: 'text' },\n { name: 'email', label: 'Contact email', type: 'email' },\n { name: 'phone', label: 'Phone', type: 'text' },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Active', value: 'active' },\n { label: 'Prospect', value: 'prospect' },\n { label: 'Churned', value: 'churned' },\n ],\n },\n { name: 'revenue', label: 'Revenue (USD)', type: 'number' },\n { name: 'projects', label: 'Projects', type: 'number' },\n { name: 'since', label: 'Client since', type: 'date' },\n];\n\nconst toInitialValues = (client: Client): FormValues => ({\n name: client.name,\n industry: client.industry,\n contactPerson: client.contactPerson,\n email: client.email,\n phone: client.phone,\n status: client.status,\n revenue: client.revenue,\n projects: client.projects,\n since: client.since ? client.since.slice(0, 10) : '',\n});\n\nconst valuesToClient = (values: FormValues, base?: Client): Client => ({\n id: base?.id ?? crypto.randomUUID(),\n name: String(values.name ?? ''),\n industry: String(values.industry ?? ''),\n contactPerson: String(values.contactPerson ?? ''),\n email: String(values.email ?? ''),\n phone: String(values.phone ?? ''),\n status: (values.status as Client['status']) || 'prospect',\n revenue: typeof values.revenue === 'number' ? values.revenue : Number(values.revenue) || 0,\n projects: typeof values.projects === 'number' ? values.projects : Number(values.projects) || 0,\n since: String(values.since ?? ''),\n});\n\nexport function CompanyClientManagementPagePage() {\n const { clients, addClient, updateClient, removeClient } = useCrewFoundryStore();\n const modal = useFormModal<Client>();\n const totalRevenue = clients.reduce((s, c) => s + c.revenue, 0);\n const activeClients = clients.filter((c) => c.status === 'active');\n\n const handleSubmit = async (values: FormValues) => {\n if (modal.context) {\n await updateClient(modal.context.id, valuesToClient(values, modal.context));\n } else {\n await addClient(valuesToClient(values));\n }\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>Client Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {clients.length} clients · ${(totalRevenue / 1000000).toFixed(1)}M revenue\n </p>\n <PagePurpose className=\"mt-1\">Keep track of the clients you work with — their contacts, status, and engagements — so account relationships never slip through the cracks.</PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Add Client\n </Button>\n </div>\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\">Active Clients</CardTitle>\n <Building2 className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activeClients.length}</div>\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\">Total Revenue</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalRevenue / 1000000).toFixed(1)}M\n </div>\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\">Total Projects</CardTitle>\n <FolderKanban className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {clients.reduce((s, c) => s + c.projects, 0)}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n <Card>\n <CardHeader>\n <CardTitle>Client Portfolio</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-8 gap-2 text-xs font-medium text-text-secondary border-b pb-2 mb-2\">\n <span>Client</span>\n <span>Industry</span>\n <span>Contact</span>\n <span className=\"text-right\">Revenue</span>\n <span className=\"text-right\">Projects</span>\n <span>Since</span>\n <span className=\"text-center\">Status</span>\n <span className=\"text-right\">Actions</span>\n </div>\n {clients.map((c) => (\n <div key={c.id} className=\"grid grid-cols-8 gap-2 py-2 border-b last:border-0 text-sm\">\n <span className=\"font-medium\">{c.name}</span>\n <span className=\"text-text-secondary\">{c.industry}</span>\n <div>\n <p className=\"text-xs\">{c.contactPerson}</p>\n <p className=\"text-xs text-text-secondary\">{c.email}</p>\n </div>\n <span className=\"text-right\">${(c.revenue / 1000).toFixed(0)}K</span>\n <span className=\"text-right\">{c.projects}</span>\n <span className=\"text-text-secondary\">{c.since}</span>\n <div className=\"text-center\">\n <Badge\n variant={\n c.status === 'active'\n ? 'default'\n : c.status === 'prospect'\n ? 'secondary'\n : 'destructive'\n }\n className=\"text-[10px]\"\n >\n {c.status}\n </Badge>\n </div>\n <div className=\"flex items-center justify-end gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Edit ${c.name}`}\n onClick={() => modal.openModal(c)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" aria-label={`Delete ${c.name}`}>\n <Trash2 className=\"h-4 w-4 text-status-error-text\" />\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete client?</AlertDialogTitle>\n <AlertDialogDescription>\n This removes “{c.name}” from your client portfolio. This action cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction onClick={() => void removeClient(c.id)}>\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title={modal.context ? 'Edit client' : 'Add client'}\n description=\"Track the client relationship, contacts, and engagement value.\"\n fields={CLIENT_FIELDS}\n initialValues={modal.context ? toInitialValues(modal.context) : undefined}\n submitLabel={modal.context ? 'Save changes' : 'Add client'}\n onSubmit={handleSubmit}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanyCompanyDashboardPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CompanyCompanyDashboardPagePage.tsx"],"sourcesContent":["import {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {
|
|
1
|
+
{"version":3,"file":"CompanyCompanyDashboardPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/CompanyCompanyDashboardPagePage.tsx"],"sourcesContent":["import {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { DollarSign, Globe, TrendingUp, Users } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function CompanyCompanyDashboardPagePage() {\n const { employees, departments, projects, clients } = useCrewFoundryStore();\n const totalRevenue = clients.reduce((s, c) => s + c.revenue, 0);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Company Dashboard</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Organization overview and key business metrics\n </p>\n <PagePurpose className=\"mt-1\">A bird's-eye view of your company's health — headcount, revenue, and key activity at a glance to guide your next move.</PagePurpose>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\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\">Total Employees</CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{employees.length}</div>\n <p className=\"text-xs text-text-secondary\">{departments.length} departments</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\">Active Projects</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {projects.filter((p) => p.status === 'active').length}\n </div>\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\">Client Revenue</CardTitle>\n <DollarSign className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalRevenue / 1000000).toFixed(1)}M\n </div>\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\">Active Clients</CardTitle>\n <Globe className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n {clients.filter((c) => c.status === 'active').length}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n <Card>\n <CardHeader>\n <CardTitle>Company Information</CardTitle>\n </CardHeader>\n <CardContent className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-3\">\n <div>\n <p className=\"text-xs text-text-secondary\">Company Name</p>\n <p className=\"text-sm font-medium\">CrewFoundry Inc.</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Industry</p>\n <p className=\"text-sm font-medium\">HR Technology / SaaS</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Founded</p>\n <p className=\"text-sm font-medium\">2020</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Headquarters</p>\n <p className=\"text-sm font-medium\">San Francisco, CA</p>\n </div>\n </div>\n <div className=\"space-y-3\">\n <div>\n <p className=\"text-xs text-text-secondary\">CEO</p>\n <p className=\"text-sm font-medium\">Alex Rivera</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Website</p>\n <p className=\"text-sm font-medium\">www.crewfoundry.com</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Offices</p>\n <p className=\"text-sm font-medium\">\n San Francisco, Austin, New York, Chicago, Remote\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Funding</p>\n <p className=\"text-sm font-medium\">Series B - $45M</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|