@burdenoff/microfe-crewfoundry 2026.704.5 → 2026.704.7
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/CrewFoundryRoutes.js +51 -43
- package/dist/crewfoundry/CrewFoundryRoutes.js.map +1 -1
- package/dist/crewfoundry/components/forms/formValues.js +5 -2
- package/dist/crewfoundry/components/forms/formValues.js.map +1 -1
- package/dist/crewfoundry/components/viz/AllocationBar.js +68 -0
- package/dist/crewfoundry/components/viz/AllocationBar.js.map +1 -0
- package/dist/crewfoundry/components/viz/AreaChart.js +102 -0
- package/dist/crewfoundry/components/viz/AreaChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/AvatarStack.js +36 -0
- package/dist/crewfoundry/components/viz/AvatarStack.js.map +1 -0
- package/dist/crewfoundry/components/viz/BarChart.js +83 -0
- package/dist/crewfoundry/components/viz/BarChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/CertificateCard.js +118 -0
- package/dist/crewfoundry/components/viz/CertificateCard.js.map +1 -0
- package/dist/crewfoundry/components/viz/DonutChart.js +109 -0
- package/dist/crewfoundry/components/viz/DonutChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/HBarFunnel.js +54 -0
- package/dist/crewfoundry/components/viz/HBarFunnel.js.map +1 -0
- package/dist/crewfoundry/components/viz/Heatmap.js +91 -0
- package/dist/crewfoundry/components/viz/Heatmap.js.map +1 -0
- package/dist/crewfoundry/components/viz/KanbanBoard.js +50 -0
- package/dist/crewfoundry/components/viz/KanbanBoard.js.map +1 -0
- package/dist/crewfoundry/components/viz/LineChart.js +123 -0
- package/dist/crewfoundry/components/viz/LineChart.js.map +1 -0
- package/dist/crewfoundry/components/viz/OrgTree.js +83 -0
- package/dist/crewfoundry/components/viz/OrgTree.js.map +1 -0
- package/dist/crewfoundry/components/viz/PathSteps.js +68 -0
- package/dist/crewfoundry/components/viz/PathSteps.js.map +1 -0
- package/dist/crewfoundry/components/viz/ProgressRing.js +68 -0
- package/dist/crewfoundry/components/viz/ProgressRing.js.map +1 -0
- package/dist/crewfoundry/components/viz/RatingStars.js +51 -0
- package/dist/crewfoundry/components/viz/RatingStars.js.map +1 -0
- package/dist/crewfoundry/components/viz/SegmentedTabs.js +69 -0
- package/dist/crewfoundry/components/viz/SegmentedTabs.js.map +1 -0
- package/dist/crewfoundry/components/viz/SkillBar.js +3 -0
- package/dist/crewfoundry/components/viz/Sparkline.js +74 -0
- package/dist/crewfoundry/components/viz/Sparkline.js.map +1 -0
- package/dist/crewfoundry/components/viz/StatCard.js +60 -0
- package/dist/crewfoundry/components/viz/StatCard.js.map +1 -0
- package/dist/crewfoundry/components/viz/StepProgress.js +3 -0
- package/dist/crewfoundry/components/viz/Timeline.js +66 -0
- package/dist/crewfoundry/components/viz/Timeline.js.map +1 -0
- package/dist/crewfoundry/components/viz/index.js +23 -0
- package/dist/crewfoundry/components/viz/lib/Avatar.js +30 -0
- package/dist/crewfoundry/components/viz/lib/Avatar.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/CartesianFrame.js +119 -0
- package/dist/crewfoundry/components/viz/lib/CartesianFrame.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/ResponsiveSvg.js +35 -0
- package/dist/crewfoundry/components/viz/lib/ResponsiveSvg.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/format.js +21 -0
- package/dist/crewfoundry/components/viz/lib/format.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/geometry.js +69 -0
- package/dist/crewfoundry/components/viz/lib/geometry.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/hooks.js +39 -0
- package/dist/crewfoundry/components/viz/lib/hooks.js.map +1 -0
- package/dist/crewfoundry/components/viz/lib/palette.js +27 -0
- package/dist/crewfoundry/components/viz/lib/palette.js.map +1 -0
- package/dist/crewfoundry/lib/analytics.js +323 -0
- package/dist/crewfoundry/lib/analytics.js.map +1 -0
- package/dist/crewfoundry/lib/companyFinance.js +16 -0
- package/dist/crewfoundry/lib/companyFinance.js.map +1 -0
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +226 -283
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +107 -120
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +122 -162
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +121 -158
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +316 -211
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +75 -27
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +167 -165
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +168 -109
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +401 -290
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +84 -75
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +368 -174
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +236 -201
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +369 -196
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +252 -249
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +210 -110
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +216 -178
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js +385 -0
- package/dist/crewfoundry/pages/HrEmployeeProfilePagePage.js.map +1 -0
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +189 -130
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +397 -241
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +262 -147
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +345 -167
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +98 -24
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +35 -31
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +289 -108
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +221 -114
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +136 -133
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +148 -97
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +264 -157
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +85 -93
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +211 -122
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +94 -54
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +28 -25
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +290 -138
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +169 -79
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +65 -61
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +296 -125
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js +187 -0
- package/dist/crewfoundry/pages/ProjectsResourcingPagePage.js.map +1 -0
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +142 -76
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +93 -43
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +250 -98
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/crewfoundry/utils/cn.js +10 -0
- package/dist/crewfoundry/utils/cn.js.map +1 -0
- package/dist/crewfoundry/utils/courseProgress.js +46 -0
- package/dist/crewfoundry/utils/courseProgress.js.map +1 -0
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/package.json +1 -1
|
@@ -5,10 +5,10 @@ import { useState as i } from "react";
|
|
|
5
5
|
import { Calendar as a, DollarSign as o, FolderKanban as s, Pencil as c, Target as l, Trash2 as u, Users as d } from "lucide-react";
|
|
6
6
|
import { useNavigate as f, useSearchParams as p } from "react-router-dom";
|
|
7
7
|
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
8
|
-
import { Badge as g, Button as _, Card as v, CardContent as y, CardHeader as b, CardTitle as x, EmphasisPanel as S, GradientText as C, IllustratedEmptyState as w, NextSteps as T, PagePurpose as E, ResponsiveDialog as D, ResponsiveDialogContent as O, ResponsiveDialogDescription as k, ResponsiveDialogFooter as A, ResponsiveDialogHeader as j, ResponsiveDialogTitle as M } from "@burdenoff/fe-libs/ui";
|
|
9
|
-
import { useGlobalUi as
|
|
8
|
+
import { Badge as g, Button as _, Card as v, CardContent as y, CardHeader as b, CardTitle as x, EmphasisPanel as S, GradientText as C, IllustratedEmptyState as w, NextSteps as T, PagePurpose as E, ResponsiveDialog as D, ResponsiveDialogContent as O, ResponsiveDialogDescription as k, ResponsiveDialogFooter as A, ResponsiveDialogHeader as j, ResponsiveDialogTitle as M, Spinner as N } from "@burdenoff/fe-libs/ui";
|
|
9
|
+
import { useGlobalUi as P } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
10
10
|
//#region src/crewfoundry/pages/ProjectsProjectDetailsPagePage.tsx
|
|
11
|
-
var
|
|
11
|
+
var F = [
|
|
12
12
|
{
|
|
13
13
|
name: "name",
|
|
14
14
|
label: "Project Name",
|
|
@@ -83,9 +83,13 @@ var P = [
|
|
|
83
83
|
type: "number"
|
|
84
84
|
}
|
|
85
85
|
];
|
|
86
|
-
function
|
|
87
|
-
let
|
|
88
|
-
if (!
|
|
86
|
+
function I() {
|
|
87
|
+
let I = f(), [L] = p(), { showToast: R } = P(), z = e((e) => e.projects), B = e((e) => e.updateProject), V = e((e) => e.removeProject), H = e((e) => e.initialized), U = r(), [W, G] = i(!1), [K, q] = i(!1), J = L.get("id"), Y = z.find((e) => e.id === J) ?? z[0];
|
|
88
|
+
if (!H && !Y) return /* @__PURE__ */ m("div", {
|
|
89
|
+
className: "flex min-h-[60vh] items-center justify-center p-6",
|
|
90
|
+
children: /* @__PURE__ */ m(N, { size: "lg" })
|
|
91
|
+
});
|
|
92
|
+
if (!Y) return /* @__PURE__ */ m("div", {
|
|
89
93
|
className: "p-6",
|
|
90
94
|
children: /* @__PURE__ */ m(w, {
|
|
91
95
|
illustration: "empty-search",
|
|
@@ -93,13 +97,13 @@ function F() {
|
|
|
93
97
|
description: "This project is no longer available."
|
|
94
98
|
})
|
|
95
99
|
});
|
|
96
|
-
let
|
|
97
|
-
name:
|
|
98
|
-
description:
|
|
99
|
-
status:
|
|
100
|
-
priority:
|
|
101
|
-
budget:
|
|
102
|
-
progress:
|
|
100
|
+
let X = Y.budget > 0 ? Math.round(Y.spent / Y.budget * 100) : 0, Z = Y.budget > 0 && Y.spent / Y.budget > .9, Q = {
|
|
101
|
+
name: Y.name,
|
|
102
|
+
description: Y.description,
|
|
103
|
+
status: Y.status,
|
|
104
|
+
priority: Y.priority,
|
|
105
|
+
budget: Y.budget,
|
|
106
|
+
progress: Y.progress
|
|
103
107
|
};
|
|
104
108
|
return /* @__PURE__ */ h("div", {
|
|
105
109
|
className: "space-y-6 p-6 max-w-4xl",
|
|
@@ -108,27 +112,27 @@ function F() {
|
|
|
108
112
|
className: "flex items-center justify-between gap-4",
|
|
109
113
|
children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h1", {
|
|
110
114
|
className: "text-2xl font-semibold",
|
|
111
|
-
children: /* @__PURE__ */ m(C, { children:
|
|
115
|
+
children: /* @__PURE__ */ m(C, { children: Y.name })
|
|
112
116
|
}), /* @__PURE__ */ m("p", {
|
|
113
117
|
className: "text-sm text-text-secondary",
|
|
114
|
-
children:
|
|
118
|
+
children: Y.description
|
|
115
119
|
})] }), /* @__PURE__ */ h("div", {
|
|
116
120
|
className: "flex items-center gap-2",
|
|
117
121
|
children: [
|
|
118
122
|
/* @__PURE__ */ h("div", {
|
|
119
123
|
className: "hidden gap-1 sm:flex",
|
|
120
124
|
children: [/* @__PURE__ */ m(g, {
|
|
121
|
-
variant:
|
|
122
|
-
children: t(
|
|
125
|
+
variant: Y.priority === "critical" ? "destructive" : "default",
|
|
126
|
+
children: t(Y.priority)
|
|
123
127
|
}), /* @__PURE__ */ m(g, {
|
|
124
|
-
variant:
|
|
125
|
-
children: t(
|
|
128
|
+
variant: Y.status === "active" ? "default" : "secondary",
|
|
129
|
+
children: t(Y.status)
|
|
126
130
|
})]
|
|
127
131
|
}),
|
|
128
132
|
/* @__PURE__ */ h(_, {
|
|
129
133
|
variant: "outline",
|
|
130
134
|
size: "sm",
|
|
131
|
-
onClick: () =>
|
|
135
|
+
onClick: () => U.openModal(),
|
|
132
136
|
children: [/* @__PURE__ */ m(c, { className: "h-4 w-4 mr-1" }), "Edit"]
|
|
133
137
|
}),
|
|
134
138
|
/* @__PURE__ */ m(_, {
|
|
@@ -136,7 +140,7 @@ function F() {
|
|
|
136
140
|
size: "sm",
|
|
137
141
|
"aria-label": "Delete project",
|
|
138
142
|
className: "h-9 w-9 p-0 text-text-secondary hover:text-status-error-text",
|
|
139
|
-
onClick: () =>
|
|
143
|
+
onClick: () => G(!0),
|
|
140
144
|
children: /* @__PURE__ */ m(u, { className: "h-4 w-4" })
|
|
141
145
|
})
|
|
142
146
|
]
|
|
@@ -151,21 +155,21 @@ function F() {
|
|
|
151
155
|
label: "View all projects",
|
|
152
156
|
description: "See how this project compares across your portfolio.",
|
|
153
157
|
icon: /* @__PURE__ */ m(s, { className: "h-4 w-4" }),
|
|
154
|
-
onClick: () =>
|
|
158
|
+
onClick: () => I("../projects/projects-page")
|
|
155
159
|
},
|
|
156
160
|
{
|
|
157
161
|
id: "team",
|
|
158
162
|
label: "Check the team",
|
|
159
163
|
description: "Review who is working on this and their workload.",
|
|
160
164
|
icon: /* @__PURE__ */ m(d, { className: "h-4 w-4" }),
|
|
161
|
-
onClick: () =>
|
|
165
|
+
onClick: () => I("../teams/teams-page")
|
|
162
166
|
},
|
|
163
167
|
{
|
|
164
168
|
id: "new-project",
|
|
165
169
|
label: "Start a new project",
|
|
166
170
|
description: "Kick off the next piece of work.",
|
|
167
171
|
icon: /* @__PURE__ */ m(l, { className: "h-4 w-4" }),
|
|
168
|
-
onClick: () =>
|
|
172
|
+
onClick: () => I("../projects/create-project-page")
|
|
169
173
|
}
|
|
170
174
|
]
|
|
171
175
|
}),
|
|
@@ -178,7 +182,7 @@ function F() {
|
|
|
178
182
|
/* @__PURE__ */ m(l, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
179
183
|
/* @__PURE__ */ h("p", {
|
|
180
184
|
className: "text-lg font-bold",
|
|
181
|
-
children: [
|
|
185
|
+
children: [Y.progress, "%"]
|
|
182
186
|
}),
|
|
183
187
|
/* @__PURE__ */ m("p", {
|
|
184
188
|
className: "text-xs text-text-secondary",
|
|
@@ -194,7 +198,7 @@ function F() {
|
|
|
194
198
|
className: "text-lg font-bold",
|
|
195
199
|
children: [
|
|
196
200
|
"$",
|
|
197
|
-
(
|
|
201
|
+
(Y.budget / 1e3).toFixed(0),
|
|
198
202
|
"K"
|
|
199
203
|
]
|
|
200
204
|
}),
|
|
@@ -210,7 +214,7 @@ function F() {
|
|
|
210
214
|
/* @__PURE__ */ m(d, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
211
215
|
/* @__PURE__ */ m("p", {
|
|
212
216
|
className: "text-lg font-bold",
|
|
213
|
-
children:
|
|
217
|
+
children: Y.teamName
|
|
214
218
|
}),
|
|
215
219
|
/* @__PURE__ */ m("p", {
|
|
216
220
|
className: "text-xs text-text-secondary",
|
|
@@ -224,7 +228,7 @@ function F() {
|
|
|
224
228
|
/* @__PURE__ */ m(a, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
|
|
225
229
|
/* @__PURE__ */ m("p", {
|
|
226
230
|
className: "text-lg font-bold",
|
|
227
|
-
children:
|
|
231
|
+
children: Y.endDate
|
|
228
232
|
}),
|
|
229
233
|
/* @__PURE__ */ m("p", {
|
|
230
234
|
className: "text-xs text-text-secondary",
|
|
@@ -242,19 +246,19 @@ function F() {
|
|
|
242
246
|
children: [/* @__PURE__ */ h("div", {
|
|
243
247
|
className: "flex justify-between text-sm",
|
|
244
248
|
children: [/* @__PURE__ */ h("span", { children: [
|
|
245
|
-
|
|
249
|
+
Y.completedTasks,
|
|
246
250
|
" of ",
|
|
247
|
-
|
|
251
|
+
Y.tasks,
|
|
248
252
|
" tasks completed"
|
|
249
253
|
] }), /* @__PURE__ */ h("span", {
|
|
250
254
|
className: "font-medium",
|
|
251
|
-
children: [
|
|
255
|
+
children: [Y.progress, "%"]
|
|
252
256
|
})]
|
|
253
257
|
}), /* @__PURE__ */ m("div", {
|
|
254
258
|
className: "h-3 bg-bg-sunken rounded overflow-hidden",
|
|
255
259
|
children: /* @__PURE__ */ m("div", {
|
|
256
260
|
className: "h-3 bg-action-primary-bg rounded",
|
|
257
|
-
style: { width: `${
|
|
261
|
+
style: { width: `${Y.progress}%` }
|
|
258
262
|
})
|
|
259
263
|
})]
|
|
260
264
|
})] }),
|
|
@@ -264,19 +268,19 @@ function F() {
|
|
|
264
268
|
className: "flex justify-between text-sm",
|
|
265
269
|
children: [/* @__PURE__ */ h("span", { children: [
|
|
266
270
|
"Spent $",
|
|
267
|
-
(
|
|
271
|
+
(Y.spent / 1e3).toFixed(0),
|
|
268
272
|
"K of $",
|
|
269
|
-
(
|
|
273
|
+
(Y.budget / 1e3).toFixed(0),
|
|
270
274
|
"K"
|
|
271
275
|
] }), /* @__PURE__ */ h("span", {
|
|
272
276
|
className: "font-medium",
|
|
273
|
-
children: [
|
|
277
|
+
children: [X, "%"]
|
|
274
278
|
})]
|
|
275
279
|
}), /* @__PURE__ */ m("div", {
|
|
276
280
|
className: "h-3 bg-bg-sunken rounded overflow-hidden",
|
|
277
281
|
children: /* @__PURE__ */ m("div", {
|
|
278
|
-
className: `h-3 rounded ${
|
|
279
|
-
style: { width: `${
|
|
282
|
+
className: `h-3 rounded ${Z ? "bg-status-error-text" : "bg-status-success-text"}`,
|
|
283
|
+
style: { width: `${X}%` }
|
|
280
284
|
})
|
|
281
285
|
})]
|
|
282
286
|
}), /* @__PURE__ */ h("div", {
|
|
@@ -286,66 +290,66 @@ function F() {
|
|
|
286
290
|
children: "Manager"
|
|
287
291
|
}), /* @__PURE__ */ m("p", {
|
|
288
292
|
className: "font-medium",
|
|
289
|
-
children:
|
|
293
|
+
children: Y.managerName
|
|
290
294
|
})] }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
|
|
291
295
|
className: "text-xs text-text-secondary",
|
|
292
296
|
children: "Timeline"
|
|
293
297
|
}), /* @__PURE__ */ h("p", { children: [
|
|
294
|
-
|
|
298
|
+
Y.startDate,
|
|
295
299
|
" — ",
|
|
296
|
-
|
|
300
|
+
Y.endDate
|
|
297
301
|
] })] })]
|
|
298
302
|
})] })] }),
|
|
299
303
|
/* @__PURE__ */ m(n, {
|
|
300
|
-
open:
|
|
301
|
-
onOpenChange:
|
|
304
|
+
open: U.open,
|
|
305
|
+
onOpenChange: U.onOpenChange,
|
|
302
306
|
title: "Edit Project",
|
|
303
|
-
description: `Update the details for ${
|
|
304
|
-
fields:
|
|
305
|
-
initialValues:
|
|
307
|
+
description: `Update the details for ${Y.name}.`,
|
|
308
|
+
fields: F,
|
|
309
|
+
initialValues: Q,
|
|
306
310
|
submitLabel: "Save Changes",
|
|
307
311
|
onSubmit: async (e) => {
|
|
308
312
|
let t = {
|
|
309
313
|
name: String(e.name ?? "").trim(),
|
|
310
314
|
description: String(e.description ?? "").trim(),
|
|
311
|
-
status: String(e.status ??
|
|
312
|
-
priority: String(e.priority ??
|
|
315
|
+
status: String(e.status ?? Y.status),
|
|
316
|
+
priority: String(e.priority ?? Y.priority)
|
|
313
317
|
};
|
|
314
|
-
typeof e.budget == "number" && !Number.isNaN(e.budget) && (t.budget = e.budget), typeof e.progress == "number" && !Number.isNaN(e.progress) && (t.progress = e.progress), await
|
|
318
|
+
typeof e.budget == "number" && !Number.isNaN(e.budget) && (t.budget = e.budget), typeof e.progress == "number" && !Number.isNaN(e.progress) && (t.progress = e.progress), await B(Y.id, t), R("Project updated", "success");
|
|
315
319
|
}
|
|
316
320
|
}),
|
|
317
321
|
/* @__PURE__ */ m(D, {
|
|
318
|
-
open:
|
|
319
|
-
onOpenChange:
|
|
322
|
+
open: W,
|
|
323
|
+
onOpenChange: G,
|
|
320
324
|
children: /* @__PURE__ */ h(O, {
|
|
321
325
|
className: "sm:max-w-[440px]",
|
|
322
326
|
children: [/* @__PURE__ */ h(j, { children: [/* @__PURE__ */ h(M, { children: [
|
|
323
327
|
"Delete ",
|
|
324
|
-
|
|
328
|
+
Y.name,
|
|
325
329
|
"?"
|
|
326
330
|
] }), /* @__PURE__ */ m(k, { children: "This permanently removes the project and its tracking data. This cannot be undone." })] }), /* @__PURE__ */ h(A, { children: [/* @__PURE__ */ m(_, {
|
|
327
331
|
type: "button",
|
|
328
332
|
variant: "outline",
|
|
329
|
-
onClick: () =>
|
|
330
|
-
disabled:
|
|
333
|
+
onClick: () => G(!1),
|
|
334
|
+
disabled: K,
|
|
331
335
|
children: "Cancel"
|
|
332
336
|
}), /* @__PURE__ */ m(_, {
|
|
333
337
|
type: "button",
|
|
334
338
|
variant: "destructive",
|
|
335
339
|
onClick: async () => {
|
|
336
|
-
if (!
|
|
337
|
-
|
|
340
|
+
if (!K) {
|
|
341
|
+
q(!0);
|
|
338
342
|
try {
|
|
339
|
-
await
|
|
343
|
+
await V(Y.id), R("Project deleted", "success"), G(!1), I("../projects/projects-page");
|
|
340
344
|
} catch (e) {
|
|
341
|
-
|
|
345
|
+
R(e instanceof Error ? e.message : "Unable to delete project", "error");
|
|
342
346
|
} finally {
|
|
343
|
-
|
|
347
|
+
q(!1);
|
|
344
348
|
}
|
|
345
349
|
}
|
|
346
350
|
},
|
|
347
|
-
disabled:
|
|
348
|
-
children:
|
|
351
|
+
disabled: K,
|
|
352
|
+
children: K ? "Deleting…" : "Delete Project"
|
|
349
353
|
})] })]
|
|
350
354
|
})
|
|
351
355
|
})
|
|
@@ -353,6 +357,6 @@ function F() {
|
|
|
353
357
|
});
|
|
354
358
|
}
|
|
355
359
|
//#endregion
|
|
356
|
-
export {
|
|
360
|
+
export { I as ProjectsProjectDetailsPagePage };
|
|
357
361
|
|
|
358
362
|
//# sourceMappingURL=ProjectsProjectDetailsPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectsProjectDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/ProjectsProjectDetailsPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { Calendar, DollarSign, FolderKanban, Pencil, Target, Trash2, Users } from 'lucide-react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Project } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst PROJECT_EDIT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Project Name', type: 'text', required: true, colSpan: 2 },\n { name: 'description', label: 'Description', type: 'textarea', colSpan: 2 },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Planning', value: 'planning' },\n { label: 'Active', value: 'active' },\n { label: 'On Hold', value: 'on_hold' },\n { label: 'Completed', value: 'completed' },\n { label: 'Cancelled', value: 'cancelled' },\n ],\n },\n {\n name: 'priority',\n label: 'Priority',\n type: 'select',\n options: [\n { label: 'Low', value: 'low' },\n { label: 'Medium', value: 'medium' },\n { label: 'High', value: 'high' },\n { label: 'Critical', value: 'critical' },\n ],\n },\n { name: 'budget', label: 'Budget ($)', type: 'number' },\n { name: 'progress', label: 'Progress (%)', type: 'number' },\n];\n\nexport function ProjectsProjectDetailsPagePage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { showToast } = useGlobalUi();\n const projects = useCrewFoundryStore((state) => state.projects);\n const updateProject = useCrewFoundryStore((state) => state.updateProject);\n const removeProject = useCrewFoundryStore((state) => state.removeProject);\n const editModal = useFormModal();\n const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);\n const [deleting, setDeleting] = useState(false);\n const projectId = searchParams.get('id');\n const project = projects.find((p) => p.id === projectId) ?? projects[0];\n if (!project)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Project not found\"\n description=\"This project is no longer available.\"\n />\n </div>\n );\n\n const budgetPct = project.budget > 0 ? Math.round((project.spent / project.budget) * 100) : 0;\n const budgetOverrun = project.budget > 0 && project.spent / project.budget > 0.9;\n\n const editInitialValues: FormValues = {\n name: project.name,\n description: project.description,\n status: project.status,\n priority: project.priority,\n budget: project.budget,\n progress: project.progress,\n };\n\n const handleEdit = async (values: FormValues) => {\n const updates: Partial<Project> = {\n name: String(values.name ?? '').trim(),\n description: String(values.description ?? '').trim(),\n status: String(values.status ?? project.status) as Project['status'],\n priority: String(values.priority ?? project.priority) as Project['priority'],\n };\n if (typeof values.budget === 'number' && !Number.isNaN(values.budget)) {\n updates.budget = values.budget;\n }\n if (typeof values.progress === 'number' && !Number.isNaN(values.progress)) {\n updates.progress = values.progress;\n }\n await updateProject(project.id, updates);\n showToast('Project updated', 'success');\n };\n\n const handleDelete = async () => {\n if (deleting) return;\n setDeleting(true);\n try {\n await removeProject(project.id);\n showToast('Project deleted', 'success');\n setConfirmDeleteOpen(false);\n navigate('../projects/projects-page');\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to delete project', 'error');\n } finally {\n setDeleting(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{project.name}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{project.description}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"hidden gap-1 sm:flex\">\n <Badge variant={project.priority === 'critical' ? 'destructive' : 'default'}>\n {formatEnumLabel(project.priority)}\n </Badge>\n <Badge variant={project.status === 'active' ? 'default' : 'secondary'}>\n {formatEnumLabel(project.status)}\n </Badge>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => editModal.openModal()}>\n <Pencil className=\"h-4 w-4 mr-1\" />\n Edit\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Delete project\"\n className=\"h-9 w-9 p-0 text-text-secondary hover:text-status-error-text\"\n onClick={() => setConfirmDeleteOpen(true)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n <PagePurpose>\n Track a single project end-to-end — progress, budget, team, and timeline in one place — so\n you can spot risks early and keep delivery on schedule and on budget.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"crewfoundry-project-details\"\n steps={[\n {\n id: 'all-projects',\n label: 'View all projects',\n description: 'See how this project compares across your portfolio.',\n icon: <FolderKanban className=\"h-4 w-4\" />,\n onClick: () => navigate('../projects/projects-page'),\n },\n {\n id: 'team',\n label: 'Check the team',\n description: 'Review who is working on this and their workload.',\n icon: <Users className=\"h-4 w-4\" />,\n onClick: () => navigate('../teams/teams-page'),\n },\n {\n id: 'new-project',\n label: 'Start a new project',\n description: 'Kick off the next piece of work.',\n icon: <Target className=\"h-4 w-4\" />,\n onClick: () => navigate('../projects/create-project-page'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Target className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.progress}%</p>\n <p className=\"text-xs text-text-secondary\">Progress</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <DollarSign className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">${(project.budget / 1000).toFixed(0)}K</p>\n <p className=\"text-xs text-text-secondary\">Budget</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.teamName}</p>\n <p className=\"text-xs text-text-secondary\">Team</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Calendar className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.endDate}</p>\n <p className=\"text-xs text-text-secondary\">Deadline</p>\n </CardContent>\n </Card>\n </div>\n <EmphasisPanel>\n <div className=\"mb-2 text-lg font-semibold\">Task Progress</div>\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span>\n {project.completedTasks} of {project.tasks} tasks completed\n </span>\n <span className=\"font-medium\">{project.progress}%</span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-3 bg-action-primary-bg rounded\"\n style={{ width: `${project.progress}%` }}\n />\n </div>\n </div>\n </EmphasisPanel>\n <Card>\n <CardHeader>\n <CardTitle>Budget Tracking</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span>\n Spent ${(project.spent / 1000).toFixed(0)}K of ${(project.budget / 1000).toFixed(0)}\n K\n </span>\n <span className=\"font-medium\">{budgetPct}%</span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-3 rounded ${budgetOverrun ? 'bg-status-error-text' : 'bg-status-success-text'}`}\n style={{ width: `${budgetPct}%` }}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4 mt-4 text-sm\">\n <div>\n <p className=\"text-xs text-text-secondary\">Manager</p>\n <p className=\"font-medium\">{project.managerName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Timeline</p>\n <p>\n {project.startDate} — {project.endDate}\n </p>\n </div>\n </div>\n </CardContent>\n </Card>\n\n <FormModal\n open={editModal.open}\n onOpenChange={editModal.onOpenChange}\n title=\"Edit Project\"\n description={`Update the details for ${project.name}.`}\n fields={PROJECT_EDIT_FIELDS}\n initialValues={editInitialValues}\n submitLabel=\"Save Changes\"\n onSubmit={handleEdit}\n />\n\n <ResponsiveDialog open={confirmDeleteOpen} onOpenChange={setConfirmDeleteOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-[440px]\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Delete {project.name}?</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n This permanently removes the project and its tracking data. This cannot be undone.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <ResponsiveDialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setConfirmDeleteOpen(false)}\n disabled={deleting}\n >\n Cancel\n </Button>\n <Button type=\"button\" variant=\"destructive\" onClick={handleDelete} disabled={deleting}>\n {deleting ? 'Deleting…' : 'Delete Project'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProjectsProjectDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/ProjectsProjectDetailsPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n Spinner,\n} from '@burdenoff/fe-libs/ui';\nimport { useGlobalUi } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { Calendar, DollarSign, FolderKanban, Pencil, Target, Trash2, Users } from 'lucide-react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Project } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst PROJECT_EDIT_FIELDS: FieldConfig[] = [\n { name: 'name', label: 'Project Name', type: 'text', required: true, colSpan: 2 },\n { name: 'description', label: 'Description', type: 'textarea', colSpan: 2 },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Planning', value: 'planning' },\n { label: 'Active', value: 'active' },\n { label: 'On Hold', value: 'on_hold' },\n { label: 'Completed', value: 'completed' },\n { label: 'Cancelled', value: 'cancelled' },\n ],\n },\n {\n name: 'priority',\n label: 'Priority',\n type: 'select',\n options: [\n { label: 'Low', value: 'low' },\n { label: 'Medium', value: 'medium' },\n { label: 'High', value: 'high' },\n { label: 'Critical', value: 'critical' },\n ],\n },\n { name: 'budget', label: 'Budget ($)', type: 'number' },\n { name: 'progress', label: 'Progress (%)', type: 'number' },\n];\n\nexport function ProjectsProjectDetailsPagePage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { showToast } = useGlobalUi();\n const projects = useCrewFoundryStore((state) => state.projects);\n const updateProject = useCrewFoundryStore((state) => state.updateProject);\n const removeProject = useCrewFoundryStore((state) => state.removeProject);\n const initialized = useCrewFoundryStore((state) => state.initialized);\n const editModal = useFormModal();\n const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);\n const [deleting, setDeleting] = useState(false);\n const projectId = searchParams.get('id');\n const project = projects.find((p) => p.id === projectId) ?? projects[0];\n if (!initialized && !project) {\n return (\n <div className=\"flex min-h-[60vh] items-center justify-center p-6\">\n <Spinner size=\"lg\" />\n </div>\n );\n }\n\n if (!project)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Project not found\"\n description=\"This project is no longer available.\"\n />\n </div>\n );\n\n const budgetPct = project.budget > 0 ? Math.round((project.spent / project.budget) * 100) : 0;\n const budgetOverrun = project.budget > 0 && project.spent / project.budget > 0.9;\n\n const editInitialValues: FormValues = {\n name: project.name,\n description: project.description,\n status: project.status,\n priority: project.priority,\n budget: project.budget,\n progress: project.progress,\n };\n\n const handleEdit = async (values: FormValues) => {\n const updates: Partial<Project> = {\n name: String(values.name ?? '').trim(),\n description: String(values.description ?? '').trim(),\n status: String(values.status ?? project.status) as Project['status'],\n priority: String(values.priority ?? project.priority) as Project['priority'],\n };\n if (typeof values.budget === 'number' && !Number.isNaN(values.budget)) {\n updates.budget = values.budget;\n }\n if (typeof values.progress === 'number' && !Number.isNaN(values.progress)) {\n updates.progress = values.progress;\n }\n await updateProject(project.id, updates);\n showToast('Project updated', 'success');\n };\n\n const handleDelete = async () => {\n if (deleting) return;\n setDeleting(true);\n try {\n await removeProject(project.id);\n showToast('Project deleted', 'success');\n setConfirmDeleteOpen(false);\n navigate('../projects/projects-page');\n } catch (error) {\n showToast(error instanceof Error ? error.message : 'Unable to delete project', 'error');\n } finally {\n setDeleting(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{project.name}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{project.description}</p>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"hidden gap-1 sm:flex\">\n <Badge variant={project.priority === 'critical' ? 'destructive' : 'default'}>\n {formatEnumLabel(project.priority)}\n </Badge>\n <Badge variant={project.status === 'active' ? 'default' : 'secondary'}>\n {formatEnumLabel(project.status)}\n </Badge>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => editModal.openModal()}>\n <Pencil className=\"h-4 w-4 mr-1\" />\n Edit\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Delete project\"\n className=\"h-9 w-9 p-0 text-text-secondary hover:text-status-error-text\"\n onClick={() => setConfirmDeleteOpen(true)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n <PagePurpose>\n Track a single project end-to-end — progress, budget, team, and timeline in one place — so\n you can spot risks early and keep delivery on schedule and on budget.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"crewfoundry-project-details\"\n steps={[\n {\n id: 'all-projects',\n label: 'View all projects',\n description: 'See how this project compares across your portfolio.',\n icon: <FolderKanban className=\"h-4 w-4\" />,\n onClick: () => navigate('../projects/projects-page'),\n },\n {\n id: 'team',\n label: 'Check the team',\n description: 'Review who is working on this and their workload.',\n icon: <Users className=\"h-4 w-4\" />,\n onClick: () => navigate('../teams/teams-page'),\n },\n {\n id: 'new-project',\n label: 'Start a new project',\n description: 'Kick off the next piece of work.',\n icon: <Target className=\"h-4 w-4\" />,\n onClick: () => navigate('../projects/create-project-page'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Target className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.progress}%</p>\n <p className=\"text-xs text-text-secondary\">Progress</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <DollarSign className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">${(project.budget / 1000).toFixed(0)}K</p>\n <p className=\"text-xs text-text-secondary\">Budget</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Users className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.teamName}</p>\n <p className=\"text-xs text-text-secondary\">Team</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"p-4 text-center\">\n <Calendar className=\"h-5 w-5 mx-auto text-text-secondary mb-1\" />\n <p className=\"text-lg font-bold\">{project.endDate}</p>\n <p className=\"text-xs text-text-secondary\">Deadline</p>\n </CardContent>\n </Card>\n </div>\n <EmphasisPanel>\n <div className=\"mb-2 text-lg font-semibold\">Task Progress</div>\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span>\n {project.completedTasks} of {project.tasks} tasks completed\n </span>\n <span className=\"font-medium\">{project.progress}%</span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className=\"h-3 bg-action-primary-bg rounded\"\n style={{ width: `${project.progress}%` }}\n />\n </div>\n </div>\n </EmphasisPanel>\n <Card>\n <CardHeader>\n <CardTitle>Budget Tracking</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span>\n Spent ${(project.spent / 1000).toFixed(0)}K of ${(project.budget / 1000).toFixed(0)}\n K\n </span>\n <span className=\"font-medium\">{budgetPct}%</span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-3 rounded ${budgetOverrun ? 'bg-status-error-text' : 'bg-status-success-text'}`}\n style={{ width: `${budgetPct}%` }}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4 mt-4 text-sm\">\n <div>\n <p className=\"text-xs text-text-secondary\">Manager</p>\n <p className=\"font-medium\">{project.managerName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Timeline</p>\n <p>\n {project.startDate} — {project.endDate}\n </p>\n </div>\n </div>\n </CardContent>\n </Card>\n\n <FormModal\n open={editModal.open}\n onOpenChange={editModal.onOpenChange}\n title=\"Edit Project\"\n description={`Update the details for ${project.name}.`}\n fields={PROJECT_EDIT_FIELDS}\n initialValues={editInitialValues}\n submitLabel=\"Save Changes\"\n onSubmit={handleEdit}\n />\n\n <ResponsiveDialog open={confirmDeleteOpen} onOpenChange={setConfirmDeleteOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-[440px]\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Delete {project.name}?</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n This permanently removes the project and its tracking data. This cannot be undone.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <ResponsiveDialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setConfirmDeleteOpen(false)}\n disabled={deleting}\n >\n Cancel\n </Button>\n <Button type=\"button\" variant=\"destructive\" onClick={handleDelete} disabled={deleting}>\n {deleting ? 'Deleting…' : 'Delete Project'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </div>\n );\n}\n"],"mappings":"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"}
|