@burdenoff/microfe-crewfoundry 2026.625.2 → 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.
Files changed (82) hide show
  1. package/dist/crewfoundry/components/forms/ConfirmDialog.js +43 -0
  2. package/dist/crewfoundry/components/forms/ConfirmDialog.js.map +1 -0
  3. package/dist/crewfoundry/components/forms/FormModal.js +220 -0
  4. package/dist/crewfoundry/components/forms/FormModal.js.map +1 -0
  5. package/dist/crewfoundry/components/forms/formValues.js +20 -0
  6. package/dist/crewfoundry/components/forms/formValues.js.map +1 -0
  7. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +255 -65
  8. package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
  9. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +28 -17
  10. package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
  11. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +57 -53
  12. package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
  13. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +32 -23
  14. package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
  15. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +44 -29
  16. package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
  17. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +183 -57
  18. package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
  19. package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
  20. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +214 -92
  21. package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
  22. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +165 -131
  23. package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
  24. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +163 -133
  25. package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
  26. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +269 -54
  27. package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
  28. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +225 -78
  29. package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
  30. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +213 -59
  31. package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
  32. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +287 -90
  33. package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
  34. package/dist/crewfoundry/pages/HiringJobsPagePage.js +49 -47
  35. package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
  36. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +166 -59
  37. package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
  38. package/dist/crewfoundry/pages/HrEmployeesPagePage.js +274 -83
  39. package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
  40. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +198 -88
  41. package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
  42. package/dist/crewfoundry/pages/HrPayrollPagePage.js +216 -88
  43. package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
  44. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +216 -66
  45. package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
  46. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +6 -7
  47. package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
  48. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +83 -68
  49. package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
  50. package/dist/crewfoundry/pages/LearningCoursesPagePage.js +167 -46
  51. package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
  52. package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
  53. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +75 -55
  54. package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
  55. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +152 -79
  56. package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
  57. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +75 -63
  58. package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
  59. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +3 -1
  60. package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
  61. package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
  62. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +235 -87
  63. package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
  64. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +199 -86
  65. package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
  66. package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
  67. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +21 -40
  68. package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
  69. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +117 -45
  70. package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
  71. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +249 -90
  72. package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
  73. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +47 -45
  74. package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
  75. package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
  76. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +262 -133
  77. package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
  78. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +144 -77
  79. package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
  80. package/dist/crewfoundry/store/crewfoundryStore.js +306 -51
  81. package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
  82. package/package.json +1 -1
@@ -1,118 +1,231 @@
1
1
  import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
2
- import { Calendar as t, DollarSign as n, FolderKanban as r, Target as i, Users as a } from "lucide-react";
3
- import { useNavigate as o } from "react-router-dom";
4
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
5
- import { Badge as l, Card as u, CardContent as d, CardHeader as f, CardTitle as p, EmphasisPanel as m, GradientText as h, IllustratedEmptyState as g, NextSteps as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
2
+ import { FormModal as t, useFormModal as n } from "../components/forms/FormModal.js";
3
+ import { useState as r } from "react";
4
+ import { Calendar as i, DollarSign as a, FolderKanban as o, Pencil as s, Target as c, Trash2 as l, Users as u } from "lucide-react";
5
+ import { useNavigate as d } from "react-router-dom";
6
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
7
+ import { Badge as m, Button as h, Card as g, CardContent as _, CardHeader as v, CardTitle as y, EmphasisPanel as b, GradientText as x, IllustratedEmptyState as S, NextSteps as C, PagePurpose as w, ResponsiveDialog as T, ResponsiveDialogContent as E, ResponsiveDialogDescription as D, ResponsiveDialogFooter as O, ResponsiveDialogHeader as k, ResponsiveDialogTitle as A } from "@burdenoff/fe-libs/ui";
8
+ import { useGlobalUi as j } from "@burdenoff/fe-libs/shared/providers/shell";
6
9
  //#region src/crewfoundry/pages/ProjectsProjectDetailsPagePage.tsx
7
- function y() {
8
- let y = o(), { projects: b } = e(), x = b[1];
9
- return x ? /* @__PURE__ */ c("div", {
10
+ var M = [
11
+ {
12
+ name: "name",
13
+ label: "Project Name",
14
+ type: "text",
15
+ required: !0,
16
+ colSpan: 2
17
+ },
18
+ {
19
+ name: "description",
20
+ label: "Description",
21
+ type: "textarea",
22
+ colSpan: 2
23
+ },
24
+ {
25
+ name: "status",
26
+ label: "Status",
27
+ type: "select",
28
+ options: [
29
+ {
30
+ label: "Planning",
31
+ value: "planning"
32
+ },
33
+ {
34
+ label: "Active",
35
+ value: "active"
36
+ },
37
+ {
38
+ label: "On Hold",
39
+ value: "on_hold"
40
+ },
41
+ {
42
+ label: "Completed",
43
+ value: "completed"
44
+ },
45
+ {
46
+ label: "Cancelled",
47
+ value: "cancelled"
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ name: "priority",
53
+ label: "Priority",
54
+ type: "select",
55
+ options: [
56
+ {
57
+ label: "Low",
58
+ value: "low"
59
+ },
60
+ {
61
+ label: "Medium",
62
+ value: "medium"
63
+ },
64
+ {
65
+ label: "High",
66
+ value: "high"
67
+ },
68
+ {
69
+ label: "Critical",
70
+ value: "critical"
71
+ }
72
+ ]
73
+ },
74
+ {
75
+ name: "budget",
76
+ label: "Budget ($)",
77
+ type: "number"
78
+ },
79
+ {
80
+ name: "progress",
81
+ label: "Progress (%)",
82
+ type: "number"
83
+ }
84
+ ];
85
+ function N() {
86
+ let N = d(), { showToast: P } = j(), F = e((e) => e.projects), I = e((e) => e.updateProject), L = e((e) => e.removeProject), R = n(), [z, B] = r(!1), [V, H] = r(!1), U = F[1];
87
+ if (!U) return /* @__PURE__ */ f("div", {
88
+ className: "p-6",
89
+ children: /* @__PURE__ */ f(S, {
90
+ illustration: "empty-search",
91
+ title: "Project not found",
92
+ description: "This project is no longer available."
93
+ })
94
+ });
95
+ let W = {
96
+ name: U.name,
97
+ description: U.description,
98
+ status: U.status,
99
+ priority: U.priority,
100
+ budget: U.budget,
101
+ progress: U.progress
102
+ };
103
+ return /* @__PURE__ */ p("div", {
10
104
  className: "space-y-6 p-6 max-w-4xl",
11
105
  children: [
12
- /* @__PURE__ */ c("div", {
13
- className: "flex items-center justify-between",
14
- children: [/* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("h1", {
106
+ /* @__PURE__ */ p("div", {
107
+ className: "flex items-center justify-between gap-4",
108
+ children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
15
109
  className: "text-2xl font-semibold",
16
- children: /* @__PURE__ */ s(h, { children: x.name })
17
- }), /* @__PURE__ */ s("p", {
110
+ children: /* @__PURE__ */ f(x, { children: U.name })
111
+ }), /* @__PURE__ */ f("p", {
18
112
  className: "text-sm text-text-secondary",
19
- children: x.description
20
- })] }), /* @__PURE__ */ c("div", {
21
- className: "flex gap-1",
22
- children: [/* @__PURE__ */ s(l, {
23
- variant: x.priority === "critical" ? "destructive" : "default",
24
- children: x.priority
25
- }), /* @__PURE__ */ s(l, {
26
- variant: x.status === "active" ? "default" : "secondary",
27
- children: x.status
28
- })]
113
+ children: U.description
114
+ })] }), /* @__PURE__ */ p("div", {
115
+ className: "flex items-center gap-2",
116
+ children: [
117
+ /* @__PURE__ */ p("div", {
118
+ className: "hidden gap-1 sm:flex",
119
+ children: [/* @__PURE__ */ f(m, {
120
+ variant: U.priority === "critical" ? "destructive" : "default",
121
+ children: U.priority
122
+ }), /* @__PURE__ */ f(m, {
123
+ variant: U.status === "active" ? "default" : "secondary",
124
+ children: U.status
125
+ })]
126
+ }),
127
+ /* @__PURE__ */ p(h, {
128
+ variant: "outline",
129
+ size: "sm",
130
+ onClick: () => R.openModal(),
131
+ children: [/* @__PURE__ */ f(s, { className: "h-4 w-4 mr-1" }), "Edit"]
132
+ }),
133
+ /* @__PURE__ */ f(h, {
134
+ variant: "ghost",
135
+ size: "sm",
136
+ "aria-label": "Delete project",
137
+ className: "h-9 w-9 p-0 text-text-secondary hover:text-status-error-text",
138
+ onClick: () => B(!0),
139
+ children: /* @__PURE__ */ f(l, { className: "h-4 w-4" })
140
+ })
141
+ ]
29
142
  })]
30
143
  }),
31
- /* @__PURE__ */ s(v, { children: "Track a single project end-to-end — progress, budget, team, and timeline in one place — so you can spot risks early and keep delivery on schedule and on budget." }),
32
- /* @__PURE__ */ s(_, {
144
+ /* @__PURE__ */ f(w, { children: "Track a single project end-to-end — progress, budget, team, and timeline in one place — so you can spot risks early and keep delivery on schedule and on budget." }),
145
+ /* @__PURE__ */ f(C, {
33
146
  storageKey: "crewfoundry-project-details",
34
147
  steps: [
35
148
  {
36
149
  id: "all-projects",
37
150
  label: "View all projects",
38
151
  description: "See how this project compares across your portfolio.",
39
- icon: /* @__PURE__ */ s(r, { className: "h-4 w-4" }),
40
- onClick: () => y("../../projects/projects-page")
152
+ icon: /* @__PURE__ */ f(o, { className: "h-4 w-4" }),
153
+ onClick: () => N("../../projects/projects-page")
41
154
  },
42
155
  {
43
156
  id: "team",
44
157
  label: "Check the team",
45
158
  description: "Review who is working on this and their workload.",
46
- icon: /* @__PURE__ */ s(a, { className: "h-4 w-4" }),
47
- onClick: () => y("../../teams/teams-page")
159
+ icon: /* @__PURE__ */ f(u, { className: "h-4 w-4" }),
160
+ onClick: () => N("../../teams/teams-page")
48
161
  },
49
162
  {
50
163
  id: "new-project",
51
164
  label: "Start a new project",
52
165
  description: "Kick off the next piece of work.",
53
- icon: /* @__PURE__ */ s(i, { className: "h-4 w-4" }),
54
- onClick: () => y("../../projects/create-project-page")
166
+ icon: /* @__PURE__ */ f(c, { className: "h-4 w-4" }),
167
+ onClick: () => N("../../projects/create-project-page")
55
168
  }
56
169
  ]
57
170
  }),
58
- /* @__PURE__ */ c("div", {
171
+ /* @__PURE__ */ p("div", {
59
172
  className: "grid gap-4 md:grid-cols-4",
60
173
  children: [
61
- /* @__PURE__ */ s(u, { children: /* @__PURE__ */ c(d, {
174
+ /* @__PURE__ */ f(g, { children: /* @__PURE__ */ p(_, {
62
175
  className: "p-4 text-center",
63
176
  children: [
64
- /* @__PURE__ */ s(i, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
65
- /* @__PURE__ */ c("p", {
177
+ /* @__PURE__ */ f(c, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
178
+ /* @__PURE__ */ p("p", {
66
179
  className: "text-lg font-bold",
67
- children: [x.progress, "%"]
180
+ children: [U.progress, "%"]
68
181
  }),
69
- /* @__PURE__ */ s("p", {
182
+ /* @__PURE__ */ f("p", {
70
183
  className: "text-xs text-text-secondary",
71
184
  children: "Progress"
72
185
  })
73
186
  ]
74
187
  }) }),
75
- /* @__PURE__ */ s(u, { children: /* @__PURE__ */ c(d, {
188
+ /* @__PURE__ */ f(g, { children: /* @__PURE__ */ p(_, {
76
189
  className: "p-4 text-center",
77
190
  children: [
78
- /* @__PURE__ */ s(n, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
79
- /* @__PURE__ */ c("p", {
191
+ /* @__PURE__ */ f(a, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
192
+ /* @__PURE__ */ p("p", {
80
193
  className: "text-lg font-bold",
81
194
  children: [
82
195
  "$",
83
- (x.budget / 1e3).toFixed(0),
196
+ (U.budget / 1e3).toFixed(0),
84
197
  "K"
85
198
  ]
86
199
  }),
87
- /* @__PURE__ */ s("p", {
200
+ /* @__PURE__ */ f("p", {
88
201
  className: "text-xs text-text-secondary",
89
202
  children: "Budget"
90
203
  })
91
204
  ]
92
205
  }) }),
93
- /* @__PURE__ */ s(u, { children: /* @__PURE__ */ c(d, {
206
+ /* @__PURE__ */ f(g, { children: /* @__PURE__ */ p(_, {
94
207
  className: "p-4 text-center",
95
208
  children: [
96
- /* @__PURE__ */ s(a, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
97
- /* @__PURE__ */ s("p", {
209
+ /* @__PURE__ */ f(u, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
210
+ /* @__PURE__ */ f("p", {
98
211
  className: "text-lg font-bold",
99
- children: x.teamName
212
+ children: U.teamName
100
213
  }),
101
- /* @__PURE__ */ s("p", {
214
+ /* @__PURE__ */ f("p", {
102
215
  className: "text-xs text-text-secondary",
103
216
  children: "Team"
104
217
  })
105
218
  ]
106
219
  }) }),
107
- /* @__PURE__ */ s(u, { children: /* @__PURE__ */ c(d, {
220
+ /* @__PURE__ */ f(g, { children: /* @__PURE__ */ p(_, {
108
221
  className: "p-4 text-center",
109
222
  children: [
110
- /* @__PURE__ */ s(t, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
111
- /* @__PURE__ */ s("p", {
223
+ /* @__PURE__ */ f(i, { className: "h-5 w-5 mx-auto text-text-secondary mb-1" }),
224
+ /* @__PURE__ */ f("p", {
112
225
  className: "text-lg font-bold",
113
- children: x.endDate
226
+ children: U.endDate
114
227
  }),
115
- /* @__PURE__ */ s("p", {
228
+ /* @__PURE__ */ f("p", {
116
229
  className: "text-xs text-text-secondary",
117
230
  children: "Deadline"
118
231
  })
@@ -120,79 +233,125 @@ function y() {
120
233
  }) })
121
234
  ]
122
235
  }),
123
- /* @__PURE__ */ c(m, { children: [/* @__PURE__ */ s("div", {
236
+ /* @__PURE__ */ p(b, { children: [/* @__PURE__ */ f("div", {
124
237
  className: "mb-2 text-lg font-semibold",
125
238
  children: "Task Progress"
126
- }), /* @__PURE__ */ c("div", {
239
+ }), /* @__PURE__ */ p("div", {
127
240
  className: "space-y-2",
128
- children: [/* @__PURE__ */ c("div", {
241
+ children: [/* @__PURE__ */ p("div", {
129
242
  className: "flex justify-between text-sm",
130
- children: [/* @__PURE__ */ c("span", { children: [
131
- x.completedTasks,
243
+ children: [/* @__PURE__ */ p("span", { children: [
244
+ U.completedTasks,
132
245
  " of ",
133
- x.tasks,
246
+ U.tasks,
134
247
  " tasks completed"
135
- ] }), /* @__PURE__ */ c("span", {
248
+ ] }), /* @__PURE__ */ p("span", {
136
249
  className: "font-medium",
137
- children: [x.progress, "%"]
250
+ children: [U.progress, "%"]
138
251
  })]
139
- }), /* @__PURE__ */ s("div", {
252
+ }), /* @__PURE__ */ f("div", {
140
253
  className: "h-3 bg-bg-sunken rounded overflow-hidden",
141
- children: /* @__PURE__ */ s("div", {
254
+ children: /* @__PURE__ */ f("div", {
142
255
  className: "h-3 bg-action-primary-bg rounded",
143
- style: { width: `${x.progress}%` }
256
+ style: { width: `${U.progress}%` }
144
257
  })
145
258
  })]
146
259
  })] }),
147
- /* @__PURE__ */ c(u, { children: [/* @__PURE__ */ s(f, { children: /* @__PURE__ */ s(p, { children: "Budget Tracking" }) }), /* @__PURE__ */ c(d, { children: [/* @__PURE__ */ c("div", {
260
+ /* @__PURE__ */ p(g, { children: [/* @__PURE__ */ f(v, { children: /* @__PURE__ */ f(y, { children: "Budget Tracking" }) }), /* @__PURE__ */ p(_, { children: [/* @__PURE__ */ p("div", {
148
261
  className: "space-y-2",
149
- children: [/* @__PURE__ */ c("div", {
262
+ children: [/* @__PURE__ */ p("div", {
150
263
  className: "flex justify-between text-sm",
151
- children: [/* @__PURE__ */ c("span", { children: [
264
+ children: [/* @__PURE__ */ p("span", { children: [
152
265
  "Spent $",
153
- (x.spent / 1e3).toFixed(0),
266
+ (U.spent / 1e3).toFixed(0),
154
267
  "K of $",
155
- (x.budget / 1e3).toFixed(0),
268
+ (U.budget / 1e3).toFixed(0),
156
269
  "K"
157
- ] }), /* @__PURE__ */ c("span", {
270
+ ] }), /* @__PURE__ */ p("span", {
158
271
  className: "font-medium",
159
- children: [Math.round(x.spent / x.budget * 100), "%"]
272
+ children: [Math.round(U.spent / U.budget * 100), "%"]
160
273
  })]
161
- }), /* @__PURE__ */ s("div", {
274
+ }), /* @__PURE__ */ f("div", {
162
275
  className: "h-3 bg-bg-sunken rounded overflow-hidden",
163
- children: /* @__PURE__ */ s("div", {
164
- className: `h-3 rounded ${x.spent / x.budget > .9 ? "bg-status-error-text" : "bg-status-success-text"}`,
165
- style: { width: `${Math.round(x.spent / x.budget * 100)}%` }
276
+ children: /* @__PURE__ */ f("div", {
277
+ className: `h-3 rounded ${U.spent / U.budget > .9 ? "bg-status-error-text" : "bg-status-success-text"}`,
278
+ style: { width: `${Math.round(U.spent / U.budget * 100)}%` }
166
279
  })
167
280
  })]
168
- }), /* @__PURE__ */ c("div", {
281
+ }), /* @__PURE__ */ p("div", {
169
282
  className: "grid grid-cols-2 gap-4 mt-4 text-sm",
170
- children: [/* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
283
+ children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("p", {
171
284
  className: "text-xs text-text-secondary",
172
285
  children: "Manager"
173
- }), /* @__PURE__ */ s("p", {
286
+ }), /* @__PURE__ */ f("p", {
174
287
  className: "font-medium",
175
- children: x.managerName
176
- })] }), /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
288
+ children: U.managerName
289
+ })] }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("p", {
177
290
  className: "text-xs text-text-secondary",
178
291
  children: "Timeline"
179
- }), /* @__PURE__ */ c("p", { children: [
180
- x.startDate,
292
+ }), /* @__PURE__ */ p("p", { children: [
293
+ U.startDate,
181
294
  " — ",
182
- x.endDate
295
+ U.endDate
183
296
  ] })] })]
184
- })] })] })
297
+ })] })] }),
298
+ /* @__PURE__ */ f(t, {
299
+ open: R.open,
300
+ onOpenChange: R.onOpenChange,
301
+ title: "Edit Project",
302
+ description: `Update the details for ${U.name}.`,
303
+ fields: M,
304
+ initialValues: W,
305
+ submitLabel: "Save Changes",
306
+ onSubmit: async (e) => {
307
+ let t = {
308
+ name: String(e.name ?? "").trim(),
309
+ description: String(e.description ?? "").trim(),
310
+ status: String(e.status ?? U.status),
311
+ priority: String(e.priority ?? U.priority)
312
+ };
313
+ 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 I(U.id, t), P("Project updated", "success");
314
+ }
315
+ }),
316
+ /* @__PURE__ */ f(T, {
317
+ open: z,
318
+ onOpenChange: B,
319
+ children: /* @__PURE__ */ p(E, {
320
+ className: "sm:max-w-[440px]",
321
+ children: [/* @__PURE__ */ p(k, { children: [/* @__PURE__ */ p(A, { children: [
322
+ "Delete ",
323
+ U.name,
324
+ "?"
325
+ ] }), /* @__PURE__ */ f(D, { children: "This permanently removes the project and its tracking data. This cannot be undone." })] }), /* @__PURE__ */ p(O, { children: [/* @__PURE__ */ f(h, {
326
+ type: "button",
327
+ variant: "outline",
328
+ onClick: () => B(!1),
329
+ disabled: V,
330
+ children: "Cancel"
331
+ }), /* @__PURE__ */ f(h, {
332
+ type: "button",
333
+ variant: "destructive",
334
+ onClick: async () => {
335
+ if (!V) {
336
+ H(!0);
337
+ try {
338
+ await L(U.id), P("Project deleted", "success"), B(!1), N("../../projects/projects-page");
339
+ } catch (e) {
340
+ P(e instanceof Error ? e.message : "Unable to delete project", "error");
341
+ } finally {
342
+ H(!1);
343
+ }
344
+ }
345
+ },
346
+ disabled: V,
347
+ children: V ? "Deleting…" : "Delete Project"
348
+ })] })]
349
+ })
350
+ })
185
351
  ]
186
- }) : /* @__PURE__ */ s("div", {
187
- className: "p-6",
188
- children: /* @__PURE__ */ s(g, {
189
- illustration: "empty-search",
190
- title: "Project not found",
191
- description: "This project is no longer available."
192
- })
193
352
  });
194
353
  }
195
354
  //#endregion
196
- export { y as ProjectsProjectDetailsPagePage };
355
+ export { N as ProjectsProjectDetailsPagePage };
197
356
 
198
357
  //# sourceMappingURL=ProjectsProjectDetailsPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsProjectDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/ProjectsProjectDetailsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, DollarSign, FolderKanban, Target, Users } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function ProjectsProjectDetailsPagePage() {\n const navigate = useNavigate();\n const { projects } = useCrewFoundryStore();\n const project = projects[1]; // Show second project for variety\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 return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\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 gap-1\">\n <Badge variant={project.priority === 'critical' ? 'destructive' : 'default'}>\n {project.priority}\n </Badge>\n <Badge variant={project.status === 'active' ? 'default' : 'secondary'}>\n {project.status}\n </Badge>\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\">\n {Math.round((project.spent / project.budget) * 100)}%\n </span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-3 rounded ${project.spent / project.budget > 0.9 ? 'bg-status-error-text' : 'bg-status-success-text'}`}\n style={{ width: `${Math.round((project.spent / project.budget) * 100)}%` }}\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 </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} 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 } 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';\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 { 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 project = projects[1]; // Show second project for variety\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 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 {project.priority}\n </Badge>\n <Badge variant={project.status === 'active' ? 'default' : 'secondary'}>\n {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\">\n {Math.round((project.spent / project.budget) * 100)}%\n </span>\n </div>\n <div className=\"h-3 bg-bg-sunken rounded overflow-hidden\">\n <div\n className={`h-3 rounded ${project.spent / project.budget > 0.9 ? 'bg-status-error-text' : 'bg-status-success-text'}`}\n style={{ width: `${Math.round((project.spent / project.budget) * 100)}%` }}\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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"}