@burdenoff/microfe-crewfoundry 2026.1029.2 → 2026.1030.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/lib/useFocusedRecordParam.d.ts +51 -0
- package/dist/crewfoundry/lib/useFocusedRecordParam.d.ts.map +1 -0
- package/dist/crewfoundry/lib/useFocusedRecordParam.js +38 -0
- package/dist/crewfoundry/lib/useFocusedRecordParam.js.map +1 -0
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +119 -112
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +78 -71
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +88 -81
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +133 -126
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +150 -143
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +110 -103
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +173 -162
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +169 -158
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.d.ts.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +179 -163
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/utils/pageContext.d.ts +43 -4
- package/dist/utils/pageContext.d.ts.map +1 -1
- package/dist/utils/pageContext.js +10 -3
- package/dist/utils/pageContext.js.map +1 -1
- package/package.json +3 -2
|
@@ -6,14 +6,15 @@ import { AvatarStack as i } from "../components/viz/AvatarStack.js";
|
|
|
6
6
|
import "../components/viz/index.js";
|
|
7
7
|
import { billableSplit as ee } from "../lib/analytics.js";
|
|
8
8
|
import { FormModal as a, useFormModal as o } from "../components/forms/FormModal.js";
|
|
9
|
-
import {
|
|
9
|
+
import { pageContaining as te, useFocusedRecordParam as ne } from "../lib/useFocusedRecordParam.js";
|
|
10
|
+
import { getBool as re, getNumber as s, getText as c, newClientId as ie } from "../components/forms/formValues.js";
|
|
10
11
|
import { useMemo as l, useState as u } from "react";
|
|
11
|
-
import { CheckCircle as
|
|
12
|
-
import { jsx as
|
|
13
|
-
import { Badge as
|
|
14
|
-
import { usePagination as
|
|
12
|
+
import { CheckCircle as ae, ChevronLeft as oe, ChevronRight as se, Clock as d, LogIn as ce, LogOut as f, Timer as p } from "lucide-react";
|
|
13
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
14
|
+
import { Badge as g, Button as _, Card as v, CardContent as y, CardDescription as b, CardHeader as x, CardTitle as S, GradientText as C, PagePurpose as le, Pagination as ue } from "@burdenoff/fe-libs/ui";
|
|
15
|
+
import { usePagination as de } from "@burdenoff/fe-libs/shared/hooks";
|
|
15
16
|
//#region src/crewfoundry/pages/HrTimeTrackingPagePage.tsx
|
|
16
|
-
var
|
|
17
|
+
var w = [
|
|
17
18
|
{
|
|
18
19
|
label: "Pending",
|
|
19
20
|
value: "pending"
|
|
@@ -26,7 +27,7 @@ var T = [
|
|
|
26
27
|
label: "Rejected",
|
|
27
28
|
value: "rejected"
|
|
28
29
|
}
|
|
29
|
-
],
|
|
30
|
+
], fe = [
|
|
30
31
|
{
|
|
31
32
|
name: "clockOut",
|
|
32
33
|
label: "Clock-out time",
|
|
@@ -49,9 +50,9 @@ var T = [
|
|
|
49
50
|
name: "status",
|
|
50
51
|
label: "Status",
|
|
51
52
|
type: "select",
|
|
52
|
-
options:
|
|
53
|
+
options: w
|
|
53
54
|
}
|
|
54
|
-
],
|
|
55
|
+
], T = [
|
|
55
56
|
"Jan",
|
|
56
57
|
"Feb",
|
|
57
58
|
"Mar",
|
|
@@ -64,7 +65,7 @@ var T = [
|
|
|
64
65
|
"Oct",
|
|
65
66
|
"Nov",
|
|
66
67
|
"Dec"
|
|
67
|
-
],
|
|
68
|
+
], pe = [
|
|
68
69
|
"Mon",
|
|
69
70
|
"Tue",
|
|
70
71
|
"Wed",
|
|
@@ -72,24 +73,24 @@ var T = [
|
|
|
72
73
|
"Fri",
|
|
73
74
|
"Sat",
|
|
74
75
|
"Sun"
|
|
75
|
-
],
|
|
76
|
+
], me = (e) => `${e.getFullYear()}-${String(e.getMonth() + 1).padStart(2, "0")}-${String(e.getDate()).padStart(2, "0")}`, he = (e) => {
|
|
76
77
|
let t = new Date(e.getFullYear(), e.getMonth(), e.getDate()), n = (t.getDay() + 6) % 7;
|
|
77
78
|
return t.setDate(t.getDate() - n), t;
|
|
78
|
-
},
|
|
79
|
+
}, E = (e) => {
|
|
79
80
|
let [t, n, r] = e.slice(0, 10).split("-").map(Number);
|
|
80
81
|
return new Date(t, (n || 1) - 1, r || 1);
|
|
81
82
|
};
|
|
82
|
-
function
|
|
83
|
-
let { timeEntries:
|
|
83
|
+
function D() {
|
|
84
|
+
let { timeEntries: D, employees: O, addTimeEntry: ge, updateTimeEntry: _e } = e(), k = o(), A = o(), [j, ve] = u(null), M = l(() => new Map(O.map((e) => [e.id, e])), [O]), N = l(() => O.map((e) => ({
|
|
84
85
|
label: `${e.firstName} ${e.lastName}`,
|
|
85
86
|
value: e.id
|
|
86
|
-
})), [
|
|
87
|
+
})), [O]), ye = l(() => [
|
|
87
88
|
{
|
|
88
89
|
name: "employeeId",
|
|
89
90
|
label: "Employee",
|
|
90
91
|
type: "select",
|
|
91
92
|
required: !0,
|
|
92
|
-
options:
|
|
93
|
+
options: N,
|
|
93
94
|
colSpan: 2
|
|
94
95
|
},
|
|
95
96
|
{
|
|
@@ -131,7 +132,7 @@ function k() {
|
|
|
131
132
|
name: "status",
|
|
132
133
|
label: "Status",
|
|
133
134
|
type: "select",
|
|
134
|
-
options:
|
|
135
|
+
options: w
|
|
135
136
|
},
|
|
136
137
|
{
|
|
137
138
|
name: "billable",
|
|
@@ -139,25 +140,25 @@ function k() {
|
|
|
139
140
|
type: "switch",
|
|
140
141
|
colSpan: 2
|
|
141
142
|
}
|
|
142
|
-
], [
|
|
143
|
-
let e =
|
|
144
|
-
return
|
|
145
|
-
}, [
|
|
146
|
-
let e = new Date(
|
|
147
|
-
return e.setDate(e.getDate() +
|
|
148
|
-
}, [
|
|
149
|
-
let n = new Date(
|
|
150
|
-
return n.setDate(
|
|
151
|
-
iso:
|
|
152
|
-
label: `${
|
|
143
|
+
], [N]), [P, F] = u(0), I = l(() => {
|
|
144
|
+
let e = D.map((e) => e.date.slice(0, 10)).filter(Boolean).sort().slice(-1)[0];
|
|
145
|
+
return he(e ? E(e) : /* @__PURE__ */ new Date());
|
|
146
|
+
}, [D]), L = l(() => {
|
|
147
|
+
let e = new Date(I);
|
|
148
|
+
return e.setDate(e.getDate() + P * 7), e;
|
|
149
|
+
}, [I, P]), R = l(() => Array.from({ length: 7 }, (e, t) => {
|
|
150
|
+
let n = new Date(L);
|
|
151
|
+
return n.setDate(L.getDate() + t), {
|
|
152
|
+
iso: me(n),
|
|
153
|
+
label: `${pe[t]} ${n.getDate()}`
|
|
153
154
|
};
|
|
154
|
-
}), [
|
|
155
|
+
}), [L]), z = l(() => new Set(R.map((e) => e.iso)), [R]), B = R[6], V = `${T[L.getMonth()]} ${L.getDate()} – ${T[E(B.iso).getMonth()]} ${E(B.iso).getDate()}`, H = l(() => D.filter((e) => z.has(e.date.slice(0, 10))), [D, z]), be = H.reduce((e, t) => e + t.totalHours, 0), xe = H.reduce((e, t) => e + t.overtime, 0), Se = H.filter((e) => e.status === "approved").length, Ce = H.filter((e) => e.status === "pending").length, U = l(() => {
|
|
155
156
|
let e = /* @__PURE__ */ new Map();
|
|
156
|
-
for (let t of
|
|
157
|
+
for (let t of H) {
|
|
157
158
|
let n = e.get(t.employeeId);
|
|
158
159
|
n || (n = {
|
|
159
|
-
name: t.employeeName ||
|
|
160
|
-
avatar:
|
|
160
|
+
name: t.employeeName || M.get(t.employeeId)?.firstName || "Unknown",
|
|
161
|
+
avatar: M.get(t.employeeId)?.avatar,
|
|
161
162
|
perDay: /* @__PURE__ */ new Map(),
|
|
162
163
|
total: 0,
|
|
163
164
|
statuses: /* @__PURE__ */ new Set()
|
|
@@ -173,8 +174,8 @@ function k() {
|
|
|
173
174
|
total: t.total,
|
|
174
175
|
status: t.statuses.has("pending") ? "pending" : t.statuses.has("rejected") ? "rejected" : "approved"
|
|
175
176
|
})).sort((e, t) => t.total - e.total);
|
|
176
|
-
}, [
|
|
177
|
-
let e = ee(
|
|
177
|
+
}, [H, M]), W = l(() => {
|
|
178
|
+
let e = ee(H);
|
|
178
179
|
if (!e) return null;
|
|
179
180
|
let t = e.reduce((e, t) => e + t.value, 0), n = e.find((e) => e.label === "Billable")?.value ?? 0;
|
|
180
181
|
return {
|
|
@@ -182,12 +183,20 @@ function k() {
|
|
|
182
183
|
centerValue: `${t > 0 ? Math.round(n / t * 100) : 0}%`,
|
|
183
184
|
caption: "Billable"
|
|
184
185
|
};
|
|
185
|
-
}, [
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
id
|
|
186
|
+
}, [H]), G = H.reduce((e, t) => (e[t.project] = (e[t.project] || 0) + t.totalHours, e), {}), we = Math.max(...Object.values(G), 1), K = l(() => [...D].sort((e, t) => t.date.localeCompare(e.date)), [D]), { page: Te, pageSize: q, offset: J, setPage: Y } = de({ initialPageSize: 8 }), Ee = K.slice(J, J + q), [X, Z] = u(null), Q = A.open ? A.context?.id ?? null : X && D.some((e) => e.id === X) ? X : null;
|
|
187
|
+
ne({
|
|
188
|
+
records: D,
|
|
189
|
+
activeId: Q,
|
|
190
|
+
onRestore: (e) => {
|
|
191
|
+
Z(e.id), Y(te(K, e.id, q));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
let $ = (e) => {
|
|
195
|
+
ve(e ?? null), k.openModal();
|
|
196
|
+
}, De = async (e) => {
|
|
197
|
+
let t = c(e, "employeeId"), n = O.find((e) => e.id === t);
|
|
198
|
+
await ge({
|
|
199
|
+
id: ie(),
|
|
191
200
|
employeeId: t,
|
|
192
201
|
employeeName: n ? `${n.firstName} ${n.lastName}` : "",
|
|
193
202
|
date: c(e, "date"),
|
|
@@ -197,154 +206,154 @@ function k() {
|
|
|
197
206
|
overtime: s(e, "overtime"),
|
|
198
207
|
project: c(e, "project"),
|
|
199
208
|
status: c(e, "status") || "pending",
|
|
200
|
-
billable:
|
|
209
|
+
billable: re(e, "billable")
|
|
201
210
|
});
|
|
202
|
-
},
|
|
203
|
-
let t =
|
|
204
|
-
t && await
|
|
211
|
+
}, Oe = async (e) => {
|
|
212
|
+
let t = A.context;
|
|
213
|
+
t && await _e(t.id, {
|
|
205
214
|
clockOut: c(e, "clockOut"),
|
|
206
215
|
totalHours: s(e, "totalHours"),
|
|
207
216
|
overtime: s(e, "overtime"),
|
|
208
217
|
status: c(e, "status") || t.status
|
|
209
218
|
});
|
|
210
|
-
},
|
|
219
|
+
}, ke = {
|
|
211
220
|
billable: !0,
|
|
212
|
-
...
|
|
213
|
-
employeeId:
|
|
214
|
-
date:
|
|
221
|
+
...j ? {
|
|
222
|
+
employeeId: j.employeeId,
|
|
223
|
+
date: j.date
|
|
215
224
|
} : {}
|
|
216
|
-
},
|
|
217
|
-
clockOut:
|
|
218
|
-
totalHours:
|
|
219
|
-
overtime:
|
|
220
|
-
status:
|
|
225
|
+
}, Ae = A.context ? {
|
|
226
|
+
clockOut: A.context.clockOut,
|
|
227
|
+
totalHours: A.context.totalHours,
|
|
228
|
+
overtime: A.context.overtime,
|
|
229
|
+
status: A.context.status
|
|
221
230
|
} : void 0;
|
|
222
|
-
return /* @__PURE__ */
|
|
231
|
+
return /* @__PURE__ */ h("div", {
|
|
223
232
|
className: "space-y-6 p-6",
|
|
224
233
|
children: [
|
|
225
|
-
/* @__PURE__ */
|
|
234
|
+
/* @__PURE__ */ h("div", {
|
|
226
235
|
className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between",
|
|
227
|
-
children: [/* @__PURE__ */
|
|
228
|
-
/* @__PURE__ */
|
|
236
|
+
children: [/* @__PURE__ */ h("div", { children: [
|
|
237
|
+
/* @__PURE__ */ m("h1", {
|
|
229
238
|
className: "text-2xl font-semibold",
|
|
230
|
-
children: /* @__PURE__ */
|
|
239
|
+
children: /* @__PURE__ */ m(C, { children: "Time Tracking" })
|
|
231
240
|
}),
|
|
232
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ m("p", {
|
|
233
242
|
className: "text-sm text-text-secondary",
|
|
234
243
|
children: "Monitor employee work hours and overtime"
|
|
235
244
|
}),
|
|
236
|
-
/* @__PURE__ */
|
|
245
|
+
/* @__PURE__ */ m(le, {
|
|
237
246
|
className: "mt-1",
|
|
238
247
|
children: "Track hours and attendance across your team — use it to monitor logged time, overtime, and timesheet approvals."
|
|
239
248
|
})
|
|
240
|
-
] }), /* @__PURE__ */
|
|
249
|
+
] }), /* @__PURE__ */ h("div", {
|
|
241
250
|
className: "flex items-center gap-2",
|
|
242
|
-
children: [/* @__PURE__ */
|
|
251
|
+
children: [/* @__PURE__ */ h("div", {
|
|
243
252
|
className: "flex items-center gap-1 rounded-lg border border-border-subtle p-1",
|
|
244
253
|
children: [
|
|
245
|
-
/* @__PURE__ */
|
|
254
|
+
/* @__PURE__ */ m(_, {
|
|
246
255
|
variant: "ghost",
|
|
247
256
|
size: "sm",
|
|
248
257
|
className: "h-8 w-8 p-0",
|
|
249
258
|
"aria-label": "Previous week",
|
|
250
|
-
onClick: () =>
|
|
251
|
-
children: /* @__PURE__ */
|
|
259
|
+
onClick: () => F((e) => e - 1),
|
|
260
|
+
children: /* @__PURE__ */ m(oe, { className: "h-4 w-4" })
|
|
252
261
|
}),
|
|
253
|
-
/* @__PURE__ */
|
|
262
|
+
/* @__PURE__ */ m("span", {
|
|
254
263
|
className: "min-w-[8.5rem] text-center text-sm font-medium tabular-nums",
|
|
255
|
-
children:
|
|
264
|
+
children: V
|
|
256
265
|
}),
|
|
257
|
-
/* @__PURE__ */
|
|
266
|
+
/* @__PURE__ */ m(_, {
|
|
258
267
|
variant: "ghost",
|
|
259
268
|
size: "sm",
|
|
260
269
|
className: "h-8 w-8 p-0",
|
|
261
270
|
"aria-label": "Next week",
|
|
262
|
-
onClick: () =>
|
|
263
|
-
children: /* @__PURE__ */
|
|
271
|
+
onClick: () => F((e) => e + 1),
|
|
272
|
+
children: /* @__PURE__ */ m(se, { className: "h-4 w-4" })
|
|
264
273
|
})
|
|
265
274
|
]
|
|
266
|
-
}), /* @__PURE__ */
|
|
275
|
+
}), /* @__PURE__ */ h(_, {
|
|
267
276
|
size: "sm",
|
|
268
277
|
onClick: () => $(),
|
|
269
|
-
children: [/* @__PURE__ */
|
|
278
|
+
children: [/* @__PURE__ */ m(p, { className: "h-4 w-4 mr-1" }), "Log Time"]
|
|
270
279
|
})]
|
|
271
280
|
})]
|
|
272
281
|
}),
|
|
273
|
-
/* @__PURE__ */
|
|
282
|
+
/* @__PURE__ */ h("div", {
|
|
274
283
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
275
284
|
children: [
|
|
276
|
-
/* @__PURE__ */
|
|
285
|
+
/* @__PURE__ */ m(r, {
|
|
277
286
|
label: "Total Hours",
|
|
278
|
-
value:
|
|
279
|
-
icon: /* @__PURE__ */
|
|
287
|
+
value: be.toFixed(1),
|
|
288
|
+
icon: /* @__PURE__ */ m(d, { className: "h-4 w-4" })
|
|
280
289
|
}),
|
|
281
|
-
/* @__PURE__ */
|
|
290
|
+
/* @__PURE__ */ m(r, {
|
|
282
291
|
label: "Overtime",
|
|
283
|
-
value: `${
|
|
284
|
-
icon: /* @__PURE__ */
|
|
292
|
+
value: `${xe.toFixed(1)}h`,
|
|
293
|
+
icon: /* @__PURE__ */ m(p, { className: "h-4 w-4" })
|
|
285
294
|
}),
|
|
286
|
-
/* @__PURE__ */
|
|
295
|
+
/* @__PURE__ */ m(r, {
|
|
287
296
|
label: "Approved",
|
|
288
|
-
value:
|
|
289
|
-
icon: /* @__PURE__ */
|
|
297
|
+
value: Se,
|
|
298
|
+
icon: /* @__PURE__ */ m(ae, { className: "h-4 w-4" })
|
|
290
299
|
}),
|
|
291
|
-
/* @__PURE__ */
|
|
300
|
+
/* @__PURE__ */ m(r, {
|
|
292
301
|
label: "Pending",
|
|
293
|
-
value:
|
|
294
|
-
icon: /* @__PURE__ */
|
|
302
|
+
value: Ce,
|
|
303
|
+
icon: /* @__PURE__ */ m(d, { className: "h-4 w-4" })
|
|
295
304
|
})
|
|
296
305
|
]
|
|
297
306
|
}),
|
|
298
|
-
/* @__PURE__ */
|
|
307
|
+
/* @__PURE__ */ h("div", {
|
|
299
308
|
className: "grid gap-4 xl:grid-cols-[minmax(0,2.2fr)_minmax(0,1fr)]",
|
|
300
|
-
children: [/* @__PURE__ */
|
|
309
|
+
children: [/* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(x, { children: [/* @__PURE__ */ m(S, { children: "Timesheet" }), /* @__PURE__ */ h(b, { children: [V, " · tap a day cell to log time for that person"] })] }), /* @__PURE__ */ h(y, { children: [/* @__PURE__ */ m("div", {
|
|
301
310
|
className: "overflow-x-auto",
|
|
302
|
-
children: /* @__PURE__ */
|
|
311
|
+
children: /* @__PURE__ */ h("table", {
|
|
303
312
|
className: "w-full min-w-[46rem] border-collapse text-sm",
|
|
304
|
-
children: [/* @__PURE__ */
|
|
313
|
+
children: [/* @__PURE__ */ m("thead", { children: /* @__PURE__ */ h("tr", {
|
|
305
314
|
className: "border-b border-border-subtle text-xs text-text-secondary",
|
|
306
315
|
children: [
|
|
307
|
-
/* @__PURE__ */
|
|
316
|
+
/* @__PURE__ */ m("th", {
|
|
308
317
|
className: "px-2 py-2 text-left font-medium",
|
|
309
318
|
children: "Employee"
|
|
310
319
|
}),
|
|
311
|
-
|
|
320
|
+
R.map((e) => /* @__PURE__ */ m("th", {
|
|
312
321
|
className: "px-1 py-2 text-center font-medium",
|
|
313
322
|
children: e.label
|
|
314
323
|
}, e.iso)),
|
|
315
|
-
/* @__PURE__ */
|
|
324
|
+
/* @__PURE__ */ m("th", {
|
|
316
325
|
className: "px-2 py-2 text-right font-medium",
|
|
317
326
|
children: "Total"
|
|
318
327
|
}),
|
|
319
|
-
/* @__PURE__ */
|
|
328
|
+
/* @__PURE__ */ m("th", {
|
|
320
329
|
className: "px-2 py-2 text-center font-medium",
|
|
321
330
|
children: "Status"
|
|
322
331
|
})
|
|
323
332
|
]
|
|
324
|
-
}) }), /* @__PURE__ */
|
|
333
|
+
}) }), /* @__PURE__ */ m("tbody", { children: U.map((e) => /* @__PURE__ */ h("tr", {
|
|
325
334
|
className: "border-b border-border-subtle/60",
|
|
326
335
|
children: [
|
|
327
|
-
/* @__PURE__ */
|
|
336
|
+
/* @__PURE__ */ m("td", {
|
|
328
337
|
className: "px-2 py-2",
|
|
329
|
-
children: /* @__PURE__ */
|
|
338
|
+
children: /* @__PURE__ */ h("div", {
|
|
330
339
|
className: "flex items-center gap-2",
|
|
331
|
-
children: [/* @__PURE__ */
|
|
340
|
+
children: [/* @__PURE__ */ m(i, {
|
|
332
341
|
people: [{
|
|
333
342
|
name: e.name,
|
|
334
343
|
avatarUrl: e.avatar
|
|
335
344
|
}],
|
|
336
345
|
size: 28
|
|
337
|
-
}), /* @__PURE__ */
|
|
346
|
+
}), /* @__PURE__ */ m("span", {
|
|
338
347
|
className: "truncate font-medium",
|
|
339
348
|
children: e.name
|
|
340
349
|
})]
|
|
341
350
|
})
|
|
342
351
|
}),
|
|
343
|
-
|
|
352
|
+
R.map((t) => {
|
|
344
353
|
let n = e.perDay.get(t.iso) ?? 0;
|
|
345
|
-
return /* @__PURE__ */
|
|
354
|
+
return /* @__PURE__ */ m("td", {
|
|
346
355
|
className: "px-1 py-2 text-center",
|
|
347
|
-
children: /* @__PURE__ */
|
|
356
|
+
children: /* @__PURE__ */ m("button", {
|
|
348
357
|
type: "button",
|
|
349
358
|
onClick: () => $({
|
|
350
359
|
employeeId: e.employeeId,
|
|
@@ -356,13 +365,13 @@ function k() {
|
|
|
356
365
|
})
|
|
357
366
|
}, t.iso);
|
|
358
367
|
}),
|
|
359
|
-
/* @__PURE__ */
|
|
368
|
+
/* @__PURE__ */ m("td", {
|
|
360
369
|
className: "px-2 py-2 text-right font-semibold tabular-nums",
|
|
361
370
|
children: e.total.toFixed(1)
|
|
362
371
|
}),
|
|
363
|
-
/* @__PURE__ */
|
|
372
|
+
/* @__PURE__ */ m("td", {
|
|
364
373
|
className: "px-2 py-2 text-center",
|
|
365
|
-
children: /* @__PURE__ */
|
|
374
|
+
children: /* @__PURE__ */ m(g, {
|
|
366
375
|
variant: e.status === "approved" ? "default" : e.status === "pending" ? "secondary" : "destructive",
|
|
367
376
|
className: "text-[10px]",
|
|
368
377
|
children: t(e.status)
|
|
@@ -371,93 +380,98 @@ function k() {
|
|
|
371
380
|
]
|
|
372
381
|
}, e.employeeId)) })]
|
|
373
382
|
})
|
|
374
|
-
}),
|
|
383
|
+
}), U.length === 0 && /* @__PURE__ */ h("p", {
|
|
375
384
|
className: "py-8 text-center text-sm text-text-secondary",
|
|
376
385
|
children: [
|
|
377
386
|
"No time logged for ",
|
|
378
|
-
|
|
387
|
+
V,
|
|
379
388
|
"."
|
|
380
389
|
]
|
|
381
|
-
})] })] }), /* @__PURE__ */
|
|
390
|
+
})] })] }), /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(x, { children: [/* @__PURE__ */ m(S, { children: "Billable split" }), /* @__PURE__ */ h(b, { children: ["Billable vs non-billable hours for ", V] })] }), /* @__PURE__ */ m(y, {
|
|
382
391
|
className: "flex flex-col items-center",
|
|
383
|
-
children:
|
|
384
|
-
segments:
|
|
385
|
-
centerLabel:
|
|
386
|
-
centerCaption:
|
|
392
|
+
children: W ? /* @__PURE__ */ m(n, {
|
|
393
|
+
segments: W.segments,
|
|
394
|
+
centerLabel: W.centerValue,
|
|
395
|
+
centerCaption: W.caption,
|
|
387
396
|
valueFormatter: (e) => `${e.toFixed(1)}h`,
|
|
388
397
|
title: "Billable vs non-billable hours"
|
|
389
|
-
}) : /* @__PURE__ */
|
|
398
|
+
}) : /* @__PURE__ */ m("p", {
|
|
390
399
|
className: "py-10 text-center text-sm text-text-secondary",
|
|
391
400
|
children: "No hours logged this week."
|
|
392
401
|
})
|
|
393
402
|
})] })]
|
|
394
403
|
}),
|
|
395
|
-
/* @__PURE__ */
|
|
404
|
+
/* @__PURE__ */ h("div", {
|
|
396
405
|
className: "grid gap-4 md:grid-cols-2",
|
|
397
|
-
children: [/* @__PURE__ */
|
|
406
|
+
children: [/* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(x, { children: [/* @__PURE__ */ m(S, { children: "Hours by Project" }), /* @__PURE__ */ h(b, { children: ["Time allocation for ", V] })] }), /* @__PURE__ */ h(y, {
|
|
398
407
|
className: "space-y-3",
|
|
399
|
-
children: [Object.entries(
|
|
408
|
+
children: [Object.entries(G).sort(([, e], [, t]) => t - e).map(([e, t]) => /* @__PURE__ */ h("div", {
|
|
400
409
|
className: "flex items-center gap-3",
|
|
401
410
|
children: [
|
|
402
|
-
/* @__PURE__ */
|
|
411
|
+
/* @__PURE__ */ m("span", {
|
|
403
412
|
className: "w-40 truncate text-sm",
|
|
404
413
|
children: e
|
|
405
414
|
}),
|
|
406
|
-
/* @__PURE__ */
|
|
415
|
+
/* @__PURE__ */ m("div", {
|
|
407
416
|
className: "h-4 flex-1 overflow-hidden rounded bg-bg-sunken",
|
|
408
|
-
children: /* @__PURE__ */
|
|
417
|
+
children: /* @__PURE__ */ m("div", {
|
|
409
418
|
className: "h-4 rounded bg-action-primary-bg",
|
|
410
|
-
style: { width: `${Math.round(t /
|
|
419
|
+
style: { width: `${Math.round(t / we * 100)}%` }
|
|
411
420
|
})
|
|
412
421
|
}),
|
|
413
|
-
/* @__PURE__ */
|
|
422
|
+
/* @__PURE__ */ h("span", {
|
|
414
423
|
className: "w-14 text-right text-sm font-medium tabular-nums",
|
|
415
424
|
children: [t.toFixed(1), "h"]
|
|
416
425
|
})
|
|
417
426
|
]
|
|
418
|
-
}, e)), Object.keys(
|
|
427
|
+
}, e)), Object.keys(G).length === 0 && /* @__PURE__ */ m("p", {
|
|
419
428
|
className: "py-6 text-center text-sm text-text-secondary",
|
|
420
429
|
children: "No project hours this week."
|
|
421
430
|
})]
|
|
422
|
-
})] }), /* @__PURE__ */
|
|
431
|
+
})] }), /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(x, { children: [/* @__PURE__ */ m(S, { children: "Recent Activity" }), /* @__PURE__ */ m(b, { children: "Latest employee clock-in/out entries" })] }), /* @__PURE__ */ h(y, {
|
|
423
432
|
className: "space-y-3",
|
|
424
433
|
children: [
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
434
|
+
Ee.map((e) => /* @__PURE__ */ h("div", {
|
|
435
|
+
"aria-current": e.id === Q ? "true" : void 0,
|
|
436
|
+
className: `flex items-center justify-between rounded border p-3 transition-colors ${e.id === Q ? "border-action-primary-bg bg-action-primary-bg/10" : ""}`,
|
|
437
|
+
children: [/* @__PURE__ */ h("button", {
|
|
438
|
+
type: "button",
|
|
439
|
+
"aria-pressed": e.id === Q,
|
|
440
|
+
"aria-label": `Select time entry for ${e.employeeName}`,
|
|
441
|
+
onClick: () => Z(e.id),
|
|
442
|
+
className: "flex min-w-0 items-center gap-2.5 text-left",
|
|
443
|
+
children: [/* @__PURE__ */ m(i, {
|
|
430
444
|
people: [{
|
|
431
445
|
name: e.employeeName,
|
|
432
|
-
avatarUrl:
|
|
446
|
+
avatarUrl: M.get(e.employeeId)?.avatar
|
|
433
447
|
}],
|
|
434
448
|
size: 30
|
|
435
|
-
}), /* @__PURE__ */
|
|
449
|
+
}), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
|
|
436
450
|
className: "text-sm font-medium",
|
|
437
451
|
children: e.employeeName
|
|
438
|
-
}), /* @__PURE__ */
|
|
452
|
+
}), /* @__PURE__ */ m("p", {
|
|
439
453
|
className: "text-xs text-text-secondary",
|
|
440
454
|
children: e.project
|
|
441
455
|
})] })]
|
|
442
|
-
}), /* @__PURE__ */
|
|
456
|
+
}), /* @__PURE__ */ h("div", {
|
|
443
457
|
className: "flex items-center gap-3",
|
|
444
458
|
children: [
|
|
445
|
-
/* @__PURE__ */
|
|
459
|
+
/* @__PURE__ */ h("div", {
|
|
446
460
|
className: "text-right text-xs",
|
|
447
|
-
children: [/* @__PURE__ */
|
|
461
|
+
children: [/* @__PURE__ */ h("div", {
|
|
448
462
|
className: "flex items-center gap-1",
|
|
449
|
-
children: [/* @__PURE__ */
|
|
450
|
-
}), /* @__PURE__ */
|
|
463
|
+
children: [/* @__PURE__ */ m(ce, { className: "h-3 w-3 text-status-success-text" }), e.clockIn]
|
|
464
|
+
}), /* @__PURE__ */ h("div", {
|
|
451
465
|
className: "flex items-center gap-1",
|
|
452
|
-
children: [/* @__PURE__ */
|
|
466
|
+
children: [/* @__PURE__ */ m(f, { className: "h-3 w-3 text-status-error-text" }), e.clockOut]
|
|
453
467
|
})]
|
|
454
468
|
}),
|
|
455
|
-
/* @__PURE__ */
|
|
469
|
+
/* @__PURE__ */ h("div", {
|
|
456
470
|
className: "text-right",
|
|
457
|
-
children: [/* @__PURE__ */
|
|
471
|
+
children: [/* @__PURE__ */ h("p", {
|
|
458
472
|
className: "text-sm font-medium",
|
|
459
473
|
children: [e.totalHours, "h"]
|
|
460
|
-
}), e.overtime > 0 && /* @__PURE__ */
|
|
474
|
+
}), e.overtime > 0 && /* @__PURE__ */ h("p", {
|
|
461
475
|
className: "text-xs text-status-warning-text",
|
|
462
476
|
children: [
|
|
463
477
|
"+",
|
|
@@ -466,59 +480,61 @@ function k() {
|
|
|
466
480
|
]
|
|
467
481
|
})]
|
|
468
482
|
}),
|
|
469
|
-
/* @__PURE__ */
|
|
483
|
+
/* @__PURE__ */ m(g, {
|
|
470
484
|
variant: e.status === "approved" ? "default" : "secondary",
|
|
471
485
|
className: "text-[10px]",
|
|
472
486
|
children: t(e.status)
|
|
473
487
|
}),
|
|
474
|
-
/* @__PURE__ */
|
|
488
|
+
/* @__PURE__ */ m(_, {
|
|
475
489
|
variant: "ghost",
|
|
476
490
|
size: "sm",
|
|
477
491
|
className: "h-8 w-8 p-0",
|
|
478
492
|
"aria-label": `Clock out ${e.employeeName}`,
|
|
479
|
-
onClick: () =>
|
|
480
|
-
|
|
493
|
+
onClick: () => {
|
|
494
|
+
Z(e.id), A.openModal(e);
|
|
495
|
+
},
|
|
496
|
+
children: /* @__PURE__ */ m(f, { className: "h-4 w-4" })
|
|
481
497
|
})
|
|
482
498
|
]
|
|
483
499
|
})]
|
|
484
500
|
}, e.id)),
|
|
485
|
-
|
|
501
|
+
K.length === 0 && /* @__PURE__ */ m("p", {
|
|
486
502
|
className: "py-6 text-center text-sm text-text-secondary",
|
|
487
503
|
children: "No time entries logged yet."
|
|
488
504
|
}),
|
|
489
|
-
|
|
490
|
-
page:
|
|
491
|
-
pageSize:
|
|
492
|
-
totalItems:
|
|
493
|
-
onPageChange:
|
|
505
|
+
K.length > q && /* @__PURE__ */ m(ue, {
|
|
506
|
+
page: Te,
|
|
507
|
+
pageSize: q,
|
|
508
|
+
totalItems: K.length,
|
|
509
|
+
onPageChange: Y
|
|
494
510
|
})
|
|
495
511
|
]
|
|
496
512
|
})] })]
|
|
497
513
|
}),
|
|
498
|
-
/* @__PURE__ */
|
|
499
|
-
open:
|
|
500
|
-
onOpenChange:
|
|
514
|
+
/* @__PURE__ */ m(a, {
|
|
515
|
+
open: k.open,
|
|
516
|
+
onOpenChange: k.onOpenChange,
|
|
501
517
|
title: "Log time",
|
|
502
518
|
description: "Log a work session for a team member.",
|
|
503
|
-
fields:
|
|
504
|
-
initialValues:
|
|
519
|
+
fields: ye,
|
|
520
|
+
initialValues: ke,
|
|
505
521
|
submitLabel: "Add entry",
|
|
506
|
-
onSubmit:
|
|
522
|
+
onSubmit: De
|
|
507
523
|
}),
|
|
508
|
-
/* @__PURE__ */
|
|
509
|
-
open:
|
|
510
|
-
onOpenChange:
|
|
524
|
+
/* @__PURE__ */ m(a, {
|
|
525
|
+
open: A.open,
|
|
526
|
+
onOpenChange: A.onOpenChange,
|
|
511
527
|
title: "Clock out",
|
|
512
|
-
description:
|
|
513
|
-
fields:
|
|
514
|
-
initialValues:
|
|
528
|
+
description: A.context ? `Record clock-out for ${A.context.employeeName}.` : void 0,
|
|
529
|
+
fields: fe,
|
|
530
|
+
initialValues: Ae,
|
|
515
531
|
submitLabel: "Save",
|
|
516
|
-
onSubmit:
|
|
532
|
+
onSubmit: Oe
|
|
517
533
|
})
|
|
518
534
|
]
|
|
519
535
|
});
|
|
520
536
|
}
|
|
521
537
|
//#endregion
|
|
522
|
-
export {
|
|
538
|
+
export { D as HrTimeTrackingPagePage };
|
|
523
539
|
|
|
524
540
|
//# sourceMappingURL=HrTimeTrackingPagePage.js.map
|