@burdenoff/microfe-crewfoundry 2026.703.2 → 2026.704.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crewfoundry/pages/AdminAdminPagePage.js +117 -164
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js +99 -82
- package/dist/crewfoundry/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js +160 -192
- package/dist/crewfoundry/pages/AnalyticsEmployeeAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +238 -231
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +196 -166
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js +45 -147
- package/dist/crewfoundry/pages/CommunicationsCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js +20 -11
- package/dist/crewfoundry/pages/CommunicationsDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js +45 -152
- package/dist/crewfoundry/pages/CommunicationsFilesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js +50 -138
- package/dist/crewfoundry/pages/CommunicationsMessagesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +149 -67
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js +50 -201
- package/dist/crewfoundry/pages/CommunicationsVideoCallsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +205 -136
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js +25 -31
- package/dist/crewfoundry/pages/CompanyCompanyDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +118 -104
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +117 -58
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +90 -94
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +210 -191
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +213 -180
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js +133 -264
- package/dist/crewfoundry/pages/DashboardExecutiveDashboardPage.js.map +1 -1
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js +279 -212
- package/dist/crewfoundry/pages/HelpApiDocumentationPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +131 -105
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +167 -148
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js +3 -3
- package/dist/crewfoundry/pages/HiringCreateJobPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +13 -5
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +151 -152
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +38 -21
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +3 -3
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js +134 -127
- package/dist/crewfoundry/pages/HrEmployeesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +163 -132
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +202 -160
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +104 -91
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js +29 -147
- package/dist/crewfoundry/pages/LearningAssessmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js +22 -106
- package/dist/crewfoundry/pages/LearningCertificatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +74 -74
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +101 -97
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +64 -47
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js +111 -121
- package/dist/crewfoundry/pages/LearningLearningAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +131 -110
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +65 -64
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +58 -43
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js +66 -82
- package/dist/crewfoundry/pages/LearningMyLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js +38 -88
- package/dist/crewfoundry/pages/MarketplaceBookingManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +59 -65
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +209 -323
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js +175 -220
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +74 -59
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +96 -80
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js +28 -100
- package/dist/crewfoundry/pages/MarketplaceMessagingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +27 -20
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +73 -73
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js +62 -56
- package/dist/crewfoundry/pages/MarketplaceServiceDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js +40 -138
- package/dist/crewfoundry/pages/PaymentsEscrowPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +126 -93
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +99 -77
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js +73 -74
- package/dist/crewfoundry/pages/PaymentsSecurityPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js +1 -1
- package/dist/crewfoundry/pages/ProjectsCreateProjectPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +122 -122
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +130 -113
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +68 -59
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +73 -62
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +82 -58
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +153 -153
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +63 -48
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
2
|
import { FormModal as t, useFormModal as n } from "../components/forms/FormModal.js";
|
|
3
|
-
import { CheckCircle2 as r,
|
|
4
|
-
import {
|
|
5
|
-
import { Badge as c, Button as l, CardContent as u, GlassCard as d, GradientText as f, IllustratedEmptyState as p, PagePurpose as m } from "@burdenoff/fe-libs/ui";
|
|
3
|
+
import { CheckCircle2 as r, Pencil as i, Plus as a } from "lucide-react";
|
|
4
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
5
|
+
import { Badge as c, Button as l, CardContent as u, GlassCard as d, GradientText as f, IllustratedEmptyState as p, PagePurpose as m, Pagination as h, ResponsiveTable as g } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { usePagination as _ } from "@burdenoff/fe-libs/shared/hooks";
|
|
6
7
|
//#region src/crewfoundry/pages/PaymentsInvoicesPagePage.tsx
|
|
7
|
-
var
|
|
8
|
+
var v = [
|
|
8
9
|
{
|
|
9
10
|
name: "number",
|
|
10
11
|
label: "Invoice number",
|
|
@@ -69,24 +70,32 @@ var h = [
|
|
|
69
70
|
colSpan: 2,
|
|
70
71
|
placeholder: "e.g. Consulting services"
|
|
71
72
|
}
|
|
72
|
-
],
|
|
73
|
-
|
|
73
|
+
], y = (e) => ({
|
|
74
|
+
number: e.number,
|
|
75
|
+
clientName: e.clientName,
|
|
76
|
+
amount: e.amount,
|
|
77
|
+
status: e.status,
|
|
78
|
+
issueDate: e.issueDate ? e.issueDate.slice(0, 10) : "",
|
|
79
|
+
dueDate: e.dueDate ? e.dueDate.slice(0, 10) : "",
|
|
80
|
+
lineItem: e.items[0]?.description ?? ""
|
|
81
|
+
}), b = (e, t) => {
|
|
82
|
+
let n = typeof e.amount == "number" ? e.amount : Number(e.amount) || 0, r = String(e.lineItem ?? "").trim() || "Services rendered";
|
|
74
83
|
return {
|
|
75
|
-
id: crypto.randomUUID(),
|
|
84
|
+
id: t?.id ?? crypto.randomUUID(),
|
|
76
85
|
number: String(e.number ?? ""),
|
|
77
86
|
clientName: String(e.clientName ?? ""),
|
|
78
|
-
amount:
|
|
87
|
+
amount: n,
|
|
79
88
|
status: e.status || "draft",
|
|
80
89
|
issueDate: String(e.issueDate ?? ""),
|
|
81
90
|
dueDate: String(e.dueDate ?? ""),
|
|
82
91
|
items: [{
|
|
83
|
-
description:
|
|
84
|
-
amount:
|
|
92
|
+
description: r,
|
|
93
|
+
amount: n
|
|
85
94
|
}]
|
|
86
95
|
};
|
|
87
|
-
};
|
|
88
|
-
function
|
|
89
|
-
let { invoices:
|
|
96
|
+
}, x = (e) => e === "paid" ? "default" : e === "overdue" ? "destructive" : e === "draft" ? "outline" : "secondary";
|
|
97
|
+
function S() {
|
|
98
|
+
let { invoices: S, addInvoice: C, updateInvoice: w } = e(), T = n(), { page: E, pageSize: D, offset: O, setPage: k } = _({ initialPageSize: 25 }), A = [...S].sort((e, t) => (t.issueDate ?? "").localeCompare(e.issueDate ?? "")), j = A.slice(O, O + D);
|
|
90
99
|
return /* @__PURE__ */ s("div", {
|
|
91
100
|
className: "space-y-6 p-6",
|
|
92
101
|
children: [
|
|
@@ -99,7 +108,7 @@ function _() {
|
|
|
99
108
|
}),
|
|
100
109
|
/* @__PURE__ */ s("p", {
|
|
101
110
|
className: "text-sm text-text-secondary",
|
|
102
|
-
children: [
|
|
111
|
+
children: [S.length, " invoices"]
|
|
103
112
|
}),
|
|
104
113
|
/* @__PURE__ */ o(m, {
|
|
105
114
|
className: "mt-1",
|
|
@@ -107,105 +116,129 @@ function _() {
|
|
|
107
116
|
})
|
|
108
117
|
] }), /* @__PURE__ */ s(l, {
|
|
109
118
|
size: "sm",
|
|
110
|
-
onClick: () =>
|
|
111
|
-
children: [/* @__PURE__ */ o(
|
|
119
|
+
onClick: () => T.openModal(),
|
|
120
|
+
children: [/* @__PURE__ */ o(a, { className: "h-4 w-4 mr-1" }), "Create Invoice"]
|
|
112
121
|
})]
|
|
113
122
|
}),
|
|
114
123
|
/* @__PURE__ */ o(d, {
|
|
115
124
|
treatment: "glass",
|
|
116
125
|
glow: !0,
|
|
117
126
|
className: "border-border-seam",
|
|
118
|
-
children: /* @__PURE__ */
|
|
119
|
-
className: "p-
|
|
120
|
-
children:
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
children: /* @__PURE__ */ s(u, {
|
|
128
|
+
className: "p-4",
|
|
129
|
+
children: [/* @__PURE__ */ o(g, {
|
|
130
|
+
data: j,
|
|
131
|
+
rowKey: (e) => e.id,
|
|
132
|
+
columns: [
|
|
133
|
+
{
|
|
134
|
+
key: "number",
|
|
135
|
+
header: "Invoice #",
|
|
136
|
+
priority: "primary",
|
|
137
|
+
cell: (e) => /* @__PURE__ */ o("span", {
|
|
138
|
+
className: "font-medium",
|
|
139
|
+
children: e.number
|
|
140
|
+
})
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
key: "client",
|
|
144
|
+
header: "Client",
|
|
145
|
+
priority: "secondary",
|
|
146
|
+
cell: (e) => /* @__PURE__ */ o("span", {
|
|
147
|
+
className: "text-text-secondary",
|
|
148
|
+
children: e.clientName
|
|
149
|
+
})
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
key: "items",
|
|
153
|
+
header: "Items",
|
|
154
|
+
priority: "hidden-on-mobile",
|
|
155
|
+
cell: (e) => /* @__PURE__ */ o("span", {
|
|
156
|
+
className: "text-xs text-text-secondary",
|
|
157
|
+
children: e.items.map((e) => e.description).join(", ")
|
|
158
|
+
})
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
key: "amount",
|
|
162
|
+
header: "Amount",
|
|
163
|
+
priority: "secondary",
|
|
164
|
+
headerClassName: "text-right",
|
|
165
|
+
cellClassName: "text-right",
|
|
166
|
+
cell: (e) => /* @__PURE__ */ s("span", {
|
|
167
|
+
className: "font-medium",
|
|
168
|
+
children: ["$", e.amount.toLocaleString()]
|
|
169
|
+
})
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
key: "dueDate",
|
|
173
|
+
header: "Due Date",
|
|
174
|
+
priority: "secondary",
|
|
175
|
+
cell: (e) => /* @__PURE__ */ o("span", {
|
|
176
|
+
className: "text-text-secondary",
|
|
177
|
+
children: e.dueDate
|
|
178
|
+
})
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
key: "status",
|
|
182
|
+
header: "Status",
|
|
183
|
+
priority: "secondary",
|
|
184
|
+
cell: (e) => /* @__PURE__ */ o(c, {
|
|
185
|
+
variant: x(e.status),
|
|
186
|
+
className: "text-[10px]",
|
|
187
|
+
children: e.status
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
emptyState: /* @__PURE__ */ o(p, {
|
|
123
192
|
illustration: "empty-data",
|
|
124
193
|
title: "No invoices yet",
|
|
125
194
|
description: "Create your first invoice to start getting paid."
|
|
195
|
+
}),
|
|
196
|
+
rowActions: (e) => /* @__PURE__ */ s("div", {
|
|
197
|
+
className: "flex items-center justify-end gap-1",
|
|
198
|
+
children: [/* @__PURE__ */ o(l, {
|
|
199
|
+
variant: "ghost",
|
|
200
|
+
size: "sm",
|
|
201
|
+
"aria-label": `Edit invoice ${e.number}`,
|
|
202
|
+
onClick: () => T.openModal(e),
|
|
203
|
+
children: /* @__PURE__ */ o(i, { className: "h-3.5 w-3.5" })
|
|
204
|
+
}), e.status === "paid" ? /* @__PURE__ */ s("span", {
|
|
205
|
+
className: "inline-flex items-center gap-1 text-xs text-status-success-text",
|
|
206
|
+
children: [/* @__PURE__ */ o(r, { className: "h-3.5 w-3.5" }), "Paid"]
|
|
207
|
+
}) : /* @__PURE__ */ s(l, {
|
|
208
|
+
variant: "outline",
|
|
209
|
+
size: "sm",
|
|
210
|
+
"aria-label": `Mark invoice ${e.number} as paid`,
|
|
211
|
+
onClick: () => void w(e.id, { status: "paid" }),
|
|
212
|
+
children: [/* @__PURE__ */ o(r, { className: "h-3.5 w-3.5 mr-1" }), "Mark Paid"]
|
|
213
|
+
})]
|
|
126
214
|
})
|
|
127
|
-
})
|
|
128
|
-
className: "
|
|
129
|
-
children:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}),
|
|
137
|
-
/* @__PURE__ */ o("span", { children: "Due Date" }),
|
|
138
|
-
/* @__PURE__ */ o("span", {
|
|
139
|
-
className: "text-center",
|
|
140
|
-
children: "Status"
|
|
141
|
-
}),
|
|
142
|
-
/* @__PURE__ */ o("span", {
|
|
143
|
-
className: "text-right",
|
|
144
|
-
children: "Actions"
|
|
145
|
-
})
|
|
146
|
-
]
|
|
147
|
-
}), _.map((e) => /* @__PURE__ */ s("div", {
|
|
148
|
-
className: "grid grid-cols-7 gap-2 py-3 px-4 border-b last:border-0 text-sm hover:bg-bg-sunken/50",
|
|
149
|
-
children: [
|
|
150
|
-
/* @__PURE__ */ o("span", {
|
|
151
|
-
className: "font-medium",
|
|
152
|
-
children: e.number
|
|
153
|
-
}),
|
|
154
|
-
/* @__PURE__ */ o("span", {
|
|
155
|
-
className: "text-text-secondary",
|
|
156
|
-
children: e.clientName
|
|
157
|
-
}),
|
|
158
|
-
/* @__PURE__ */ o("div", {
|
|
159
|
-
className: "text-xs text-text-secondary",
|
|
160
|
-
children: e.items.map((e) => e.description).join(", ")
|
|
161
|
-
}),
|
|
162
|
-
/* @__PURE__ */ s("span", {
|
|
163
|
-
className: "text-right font-medium",
|
|
164
|
-
children: ["$", e.amount.toLocaleString()]
|
|
165
|
-
}),
|
|
166
|
-
/* @__PURE__ */ o("span", {
|
|
167
|
-
className: "text-text-secondary",
|
|
168
|
-
children: e.dueDate
|
|
169
|
-
}),
|
|
170
|
-
/* @__PURE__ */ o("div", {
|
|
171
|
-
className: "text-center",
|
|
172
|
-
children: /* @__PURE__ */ o(c, {
|
|
173
|
-
variant: e.status === "paid" ? "default" : e.status === "overdue" ? "destructive" : e.status === "draft" ? "outline" : "secondary",
|
|
174
|
-
className: "text-[10px]",
|
|
175
|
-
children: e.status
|
|
176
|
-
})
|
|
177
|
-
}),
|
|
178
|
-
/* @__PURE__ */ o("div", {
|
|
179
|
-
className: "flex items-center justify-end",
|
|
180
|
-
children: e.status === "paid" ? /* @__PURE__ */ s("span", {
|
|
181
|
-
className: "inline-flex items-center gap-1 text-xs text-status-success-text",
|
|
182
|
-
children: [/* @__PURE__ */ o(r, { className: "h-3.5 w-3.5" }), "Paid"]
|
|
183
|
-
}) : /* @__PURE__ */ s(l, {
|
|
184
|
-
variant: "outline",
|
|
185
|
-
size: "sm",
|
|
186
|
-
onClick: () => void y(e.id, { status: "paid" }),
|
|
187
|
-
children: [/* @__PURE__ */ o(r, { className: "h-3.5 w-3.5 mr-1" }), "Mark Paid"]
|
|
188
|
-
})
|
|
189
|
-
})
|
|
190
|
-
]
|
|
191
|
-
}, e.id))] })
|
|
215
|
+
}), A.length > D && /* @__PURE__ */ o("div", {
|
|
216
|
+
className: "mt-4",
|
|
217
|
+
children: /* @__PURE__ */ o(h, {
|
|
218
|
+
page: E,
|
|
219
|
+
pageSize: D,
|
|
220
|
+
totalItems: A.length,
|
|
221
|
+
onPageChange: k
|
|
222
|
+
})
|
|
223
|
+
})]
|
|
192
224
|
})
|
|
193
225
|
}),
|
|
194
226
|
/* @__PURE__ */ o(t, {
|
|
195
|
-
open:
|
|
196
|
-
onOpenChange:
|
|
197
|
-
title: "Create invoice",
|
|
227
|
+
open: T.open,
|
|
228
|
+
onOpenChange: T.onOpenChange,
|
|
229
|
+
title: T.context ? "Edit invoice" : "Create invoice",
|
|
198
230
|
description: "Issue a new invoice to a client and track its payment status.",
|
|
199
|
-
fields:
|
|
200
|
-
|
|
231
|
+
fields: v,
|
|
232
|
+
initialValues: T.context ? y(T.context) : void 0,
|
|
233
|
+
submitLabel: T.context ? "Save changes" : "Create invoice",
|
|
201
234
|
onSubmit: async (e) => {
|
|
202
|
-
await
|
|
235
|
+
T.context ? await w(T.context.id, b(e, T.context)) : await C(b(e));
|
|
203
236
|
}
|
|
204
237
|
})
|
|
205
238
|
]
|
|
206
239
|
});
|
|
207
240
|
}
|
|
208
241
|
//#endregion
|
|
209
|
-
export {
|
|
242
|
+
export { S as PaymentsInvoicesPagePage };
|
|
210
243
|
|
|
211
244
|
//# sourceMappingURL=PaymentsInvoicesPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaymentsInvoicesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/PaymentsInvoicesPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n CardContent,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { CheckCircle2, Plus } from 'lucide-react';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Invoice } from '../store/crewfoundryStore';\n\nconst INVOICE_FIELDS: FieldConfig[] = [\n { name: 'number', label: 'Invoice number', type: 'text', required: true, placeholder: 'INV-0001' },\n { name: 'clientName', label: 'Client name', type: 'text', required: true },\n { name: 'amount', label: 'Amount (USD)', type: 'number', required: true },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Sent', value: 'sent' },\n { label: 'Paid', value: 'paid' },\n { label: 'Overdue', value: 'overdue' },\n { label: 'Cancelled', value: 'cancelled' },\n ],\n },\n { name: 'issueDate', label: 'Issue date', type: 'date', required: true },\n { name: 'dueDate', label: 'Due date', type: 'date' },\n {\n name: 'lineItem',\n label: 'Line item description',\n type: 'text',\n colSpan: 2,\n placeholder: 'e.g. Consulting services',\n },\n];\n\nconst valuesToInvoice = (values: FormValues): Invoice => {\n const amount = typeof values.amount === 'number' ? values.amount : Number(values.amount) || 0;\n const description = String(values.lineItem ?? '').trim() || 'Services rendered';\n return {\n id: crypto.randomUUID(),\n number: String(values.number ?? ''),\n clientName: String(values.clientName ?? ''),\n amount,\n status: (values.status as Invoice['status']) || 'draft',\n issueDate: String(values.issueDate ?? ''),\n dueDate: String(values.dueDate ?? ''),\n items: [{ description, amount }],\n };\n};\n\nexport function PaymentsInvoicesPagePage() {\n const { invoices, addInvoice, updateInvoice } = useCrewFoundryStore();\n const modal = useFormModal();\n\n const handleSubmit = async (values: FormValues) => {\n await addInvoice(valuesToInvoice(values));\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Invoices</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{invoices.length} invoices</p>\n <PagePurpose className=\"mt-1\">Create, send, and track invoices — see what's paid, pending, or overdue so you stay on top of getting paid.</PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Create Invoice\n </Button>\n </div>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"p-0\">\n {invoices.length === 0 ? (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No invoices yet\"\n description=\"Create your first invoice to start getting paid.\"\n />\n </div>\n ) : (\n <>\n <div className=\"grid grid-cols-7 gap-2 text-xs font-medium text-text-secondary p-4 border-b\">\n <span>Invoice #</span>\n <span>Client</span>\n <span>Items</span>\n <span className=\"text-right\">Amount</span>\n <span>Due Date</span>\n <span className=\"text-center\">Status</span>\n <span className=\"text-right\">Actions</span>\n </div>\n {invoices.map((inv) => (\n <div\n key={inv.id}\n className=\"grid grid-cols-7 gap-2 py-3 px-4 border-b last:border-0 text-sm hover:bg-bg-sunken/50\"\n >\n <span className=\"font-medium\">{inv.number}</span>\n <span className=\"text-text-secondary\">{inv.clientName}</span>\n <div className=\"text-xs text-text-secondary\">\n {inv.items.map((i) => i.description).join(', ')}\n </div>\n <span className=\"text-right font-medium\">${inv.amount.toLocaleString()}</span>\n <span className=\"text-text-secondary\">{inv.dueDate}</span>\n <div className=\"text-center\">\n <Badge\n variant={\n inv.status === 'paid'\n ? 'default'\n : inv.status === 'overdue'\n ? 'destructive'\n : inv.status === 'draft'\n ? 'outline'\n : 'secondary'\n }\n className=\"text-[10px]\"\n >\n {inv.status}\n </Badge>\n </div>\n <div className=\"flex items-center justify-end\">\n {inv.status === 'paid' ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-status-success-text\">\n <CheckCircle2 className=\"h-3.5 w-3.5\" />\n Paid\n </span>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void updateInvoice(inv.id, { status: 'paid' })}\n >\n <CheckCircle2 className=\"h-3.5 w-3.5 mr-1\" />\n Mark Paid\n </Button>\n )}\n </div>\n </div>\n ))}\n </>\n )}\n </CardContent>\n </GlassCard>\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title=\"Create invoice\"\n description=\"Issue a new invoice to a client and track its payment status.\"\n fields={INVOICE_FIELDS}\n submitLabel=\"Create invoice\"\n onSubmit={handleSubmit}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PaymentsInvoicesPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/PaymentsInvoicesPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n CardContent,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n Pagination,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { usePagination } from '@burdenoff/fe-libs/shared/hooks';\nimport { CheckCircle2, Pencil, Plus } from 'lucide-react';\nimport {\n FormModal,\n useFormModal,\n type FieldConfig,\n type FormValues,\n} from '../components/forms/FormModal';\nimport { useCrewFoundryStore, type Invoice } from '../store/crewfoundryStore';\n\nconst INVOICE_FIELDS: FieldConfig[] = [\n { name: 'number', label: 'Invoice number', type: 'text', required: true, placeholder: 'INV-0001' },\n { name: 'clientName', label: 'Client name', type: 'text', required: true },\n { name: 'amount', label: 'Amount (USD)', type: 'number', required: true },\n {\n name: 'status',\n label: 'Status',\n type: 'select',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Sent', value: 'sent' },\n { label: 'Paid', value: 'paid' },\n { label: 'Overdue', value: 'overdue' },\n { label: 'Cancelled', value: 'cancelled' },\n ],\n },\n { name: 'issueDate', label: 'Issue date', type: 'date', required: true },\n { name: 'dueDate', label: 'Due date', type: 'date' },\n {\n name: 'lineItem',\n label: 'Line item description',\n type: 'text',\n colSpan: 2,\n placeholder: 'e.g. Consulting services',\n },\n];\n\nconst toInitialValues = (invoice: Invoice): FormValues => ({\n number: invoice.number,\n clientName: invoice.clientName,\n amount: invoice.amount,\n status: invoice.status,\n issueDate: invoice.issueDate ? invoice.issueDate.slice(0, 10) : '',\n dueDate: invoice.dueDate ? invoice.dueDate.slice(0, 10) : '',\n lineItem: invoice.items[0]?.description ?? '',\n});\n\nconst valuesToInvoice = (values: FormValues, base?: Invoice): Invoice => {\n const amount = typeof values.amount === 'number' ? values.amount : Number(values.amount) || 0;\n const description = String(values.lineItem ?? '').trim() || 'Services rendered';\n return {\n id: base?.id ?? crypto.randomUUID(),\n number: String(values.number ?? ''),\n clientName: String(values.clientName ?? ''),\n amount,\n status: (values.status as Invoice['status']) || 'draft',\n issueDate: String(values.issueDate ?? ''),\n dueDate: String(values.dueDate ?? ''),\n items: [{ description, amount }],\n };\n};\n\nconst statusVariant = (status: Invoice['status']) =>\n status === 'paid'\n ? 'default'\n : status === 'overdue'\n ? 'destructive'\n : status === 'draft'\n ? 'outline'\n : 'secondary';\n\nexport function PaymentsInvoicesPagePage() {\n const { invoices, addInvoice, updateInvoice } = useCrewFoundryStore();\n const modal = useFormModal<Invoice>();\n const { page, pageSize, offset, setPage } = usePagination({ initialPageSize: 25 });\n\n const sorted = [...invoices].sort((a, b) => (b.issueDate ?? '').localeCompare(a.issueDate ?? ''));\n const paged = sorted.slice(offset, offset + pageSize);\n\n const handleSubmit = async (values: FormValues) => {\n if (modal.context) {\n await updateInvoice(modal.context.id, valuesToInvoice(values, modal.context));\n } else {\n await addInvoice(valuesToInvoice(values));\n }\n };\n\n const columns: ResponsiveTableColumn<Invoice>[] = [\n {\n key: 'number',\n header: 'Invoice #',\n priority: 'primary',\n cell: (inv) => <span className=\"font-medium\">{inv.number}</span>,\n },\n {\n key: 'client',\n header: 'Client',\n priority: 'secondary',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.clientName}</span>,\n },\n {\n key: 'items',\n header: 'Items',\n priority: 'hidden-on-mobile',\n cell: (inv) => (\n <span className=\"text-xs text-text-secondary\">\n {inv.items.map((i) => i.description).join(', ')}\n </span>\n ),\n },\n {\n key: 'amount',\n header: 'Amount',\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (inv) => <span className=\"font-medium\">${inv.amount.toLocaleString()}</span>,\n },\n {\n key: 'dueDate',\n header: 'Due Date',\n priority: 'secondary',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.dueDate}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'secondary',\n cell: (inv) => (\n <Badge variant={statusVariant(inv.status)} className=\"text-[10px]\">\n {inv.status}\n </Badge>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Invoices</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{invoices.length} invoices</p>\n <PagePurpose className=\"mt-1\">Create, send, and track invoices — see what's paid, pending, or overdue so you stay on top of getting paid.</PagePurpose>\n </div>\n <Button size=\"sm\" onClick={() => modal.openModal()}>\n <Plus className=\"h-4 w-4 mr-1\" />\n Create Invoice\n </Button>\n </div>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"p-4\">\n <ResponsiveTable\n data={paged}\n rowKey={(inv) => inv.id}\n columns={columns}\n emptyState={\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No invoices yet\"\n description=\"Create your first invoice to start getting paid.\"\n />\n }\n rowActions={(inv) => (\n <div className=\"flex items-center justify-end gap-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label={`Edit invoice ${inv.number}`}\n onClick={() => modal.openModal(inv)}\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </Button>\n {inv.status === 'paid' ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-status-success-text\">\n <CheckCircle2 className=\"h-3.5 w-3.5\" />\n Paid\n </span>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n aria-label={`Mark invoice ${inv.number} as paid`}\n onClick={() => void updateInvoice(inv.id, { status: 'paid' })}\n >\n <CheckCircle2 className=\"h-3.5 w-3.5 mr-1\" />\n Mark Paid\n </Button>\n )}\n </div>\n )}\n />\n {sorted.length > pageSize && (\n <div className=\"mt-4\">\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={sorted.length}\n onPageChange={setPage}\n />\n </div>\n )}\n </CardContent>\n </GlassCard>\n\n <FormModal\n open={modal.open}\n onOpenChange={modal.onOpenChange}\n title={modal.context ? 'Edit invoice' : 'Create invoice'}\n description=\"Issue a new invoice to a client and track its payment status.\"\n fields={INVOICE_FIELDS}\n initialValues={modal.context ? toInitialValues(modal.context) : undefined}\n submitLabel={modal.context ? 'Save changes' : 'Create invoice'}\n onSubmit={handleSubmit}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,137 +1,159 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
2
|
import { CreditCard as t, DollarSign as n, Receipt as r, TrendingUp as i } from "lucide-react";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { useNavigate as a } from "react-router-dom";
|
|
4
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
5
|
+
import { Badge as c, Button as l, Card as u, CardContent as d, CardHeader as f, CardTitle as p, GlassCard as m, GradientText as h, IllustratedEmptyState as g, PagePurpose as _, ResponsiveTable as v } from "@burdenoff/fe-libs/ui";
|
|
5
6
|
//#region src/crewfoundry/pages/PaymentsPaymentDashboardPagePage.tsx
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
var y = 5, b = (e) => e === "paid" ? "default" : e === "overdue" ? "destructive" : "secondary";
|
|
8
|
+
function x() {
|
|
9
|
+
let x = a(), { invoices: S, payrollRecords: C } = e(), w = S.reduce((e, t) => e + t.amount, 0), T = S.filter((e) => e.status === "paid").reduce((e, t) => e + t.amount, 0), E = C.reduce((e, t) => e + t.grossPay, 0), D = [...S].sort((e, t) => (t.issueDate ?? "").localeCompare(e.issueDate ?? "")).slice(0, y);
|
|
10
|
+
return /* @__PURE__ */ s("div", {
|
|
9
11
|
className: "space-y-6 p-6",
|
|
10
12
|
children: [
|
|
11
|
-
/* @__PURE__ */
|
|
12
|
-
/* @__PURE__ */
|
|
13
|
+
/* @__PURE__ */ s("div", { children: [
|
|
14
|
+
/* @__PURE__ */ o("h1", {
|
|
13
15
|
className: "text-2xl font-semibold",
|
|
14
|
-
children: /* @__PURE__ */
|
|
16
|
+
children: /* @__PURE__ */ o(h, { children: "Payment Dashboard" })
|
|
15
17
|
}),
|
|
16
|
-
/* @__PURE__ */
|
|
18
|
+
/* @__PURE__ */ o("p", {
|
|
17
19
|
className: "text-sm text-text-secondary",
|
|
18
20
|
children: "Financial transactions and payment overview"
|
|
19
21
|
}),
|
|
20
|
-
/* @__PURE__ */
|
|
22
|
+
/* @__PURE__ */ o(_, {
|
|
21
23
|
className: "mt-1",
|
|
22
24
|
children: "A snapshot of all money movement — incoming payments, payouts, and balances so you understand your financial position at a glance."
|
|
23
25
|
})
|
|
24
26
|
] }),
|
|
25
|
-
/* @__PURE__ */
|
|
27
|
+
/* @__PURE__ */ s("div", {
|
|
26
28
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
27
29
|
children: [
|
|
28
|
-
/* @__PURE__ */
|
|
30
|
+
/* @__PURE__ */ s(m, {
|
|
29
31
|
treatment: "glass",
|
|
30
32
|
glow: !0,
|
|
31
33
|
className: "border-border-seam",
|
|
32
|
-
children: [/* @__PURE__ */
|
|
34
|
+
children: [/* @__PURE__ */ s(f, {
|
|
33
35
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
34
|
-
children: [/* @__PURE__ */
|
|
36
|
+
children: [/* @__PURE__ */ o(p, {
|
|
35
37
|
className: "text-sm font-medium",
|
|
36
38
|
children: "Total Invoiced"
|
|
37
|
-
}), /* @__PURE__ */
|
|
38
|
-
}), /* @__PURE__ */
|
|
39
|
+
}), /* @__PURE__ */ o(r, { className: "h-4 w-4 text-text-secondary" })]
|
|
40
|
+
}), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ s("div", {
|
|
39
41
|
className: "text-2xl font-bold tabular-nums",
|
|
40
|
-
children: ["$",
|
|
42
|
+
children: ["$", w.toLocaleString()]
|
|
41
43
|
}) })]
|
|
42
44
|
}),
|
|
43
|
-
/* @__PURE__ */
|
|
45
|
+
/* @__PURE__ */ s(m, {
|
|
44
46
|
treatment: "metric",
|
|
45
47
|
className: "border-border-seam",
|
|
46
|
-
children: [/* @__PURE__ */
|
|
48
|
+
children: [/* @__PURE__ */ s(f, {
|
|
47
49
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
48
|
-
children: [/* @__PURE__ */
|
|
50
|
+
children: [/* @__PURE__ */ o(p, {
|
|
49
51
|
className: "text-sm font-medium",
|
|
50
52
|
children: "Collected"
|
|
51
|
-
}), /* @__PURE__ */
|
|
52
|
-
}), /* @__PURE__ */
|
|
53
|
+
}), /* @__PURE__ */ o(n, { className: "h-4 w-4 text-status-success-text" })]
|
|
54
|
+
}), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ s("div", {
|
|
53
55
|
className: "text-2xl font-bold tabular-nums",
|
|
54
|
-
children: ["$",
|
|
56
|
+
children: ["$", T.toLocaleString()]
|
|
55
57
|
}) })]
|
|
56
58
|
}),
|
|
57
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ s(m, {
|
|
58
60
|
treatment: "metric",
|
|
59
61
|
className: "border-border-seam",
|
|
60
|
-
children: [/* @__PURE__ */
|
|
62
|
+
children: [/* @__PURE__ */ s(f, {
|
|
61
63
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
62
|
-
children: [/* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ o(p, {
|
|
63
65
|
className: "text-sm font-medium",
|
|
64
66
|
children: "Payroll Processed"
|
|
65
|
-
}), /* @__PURE__ */
|
|
66
|
-
}), /* @__PURE__ */
|
|
67
|
+
}), /* @__PURE__ */ o(t, { className: "h-4 w-4 text-text-secondary" })]
|
|
68
|
+
}), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ s("div", {
|
|
67
69
|
className: "text-2xl font-bold tabular-nums",
|
|
68
|
-
children: ["$",
|
|
70
|
+
children: ["$", E.toLocaleString()]
|
|
69
71
|
}) })]
|
|
70
72
|
}),
|
|
71
|
-
/* @__PURE__ */
|
|
73
|
+
/* @__PURE__ */ s(m, {
|
|
72
74
|
treatment: "metric",
|
|
73
75
|
className: "border-border-seam",
|
|
74
|
-
children: [/* @__PURE__ */
|
|
76
|
+
children: [/* @__PURE__ */ s(f, {
|
|
75
77
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
76
|
-
children: [/* @__PURE__ */
|
|
78
|
+
children: [/* @__PURE__ */ o(p, {
|
|
77
79
|
className: "text-sm font-medium",
|
|
78
80
|
children: "Outstanding"
|
|
79
|
-
}), /* @__PURE__ */
|
|
80
|
-
}), /* @__PURE__ */
|
|
81
|
+
}), /* @__PURE__ */ o(i, { className: "h-4 w-4 text-status-warning-text" })]
|
|
82
|
+
}), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ s("div", {
|
|
81
83
|
className: "text-2xl font-bold tabular-nums",
|
|
82
|
-
children: ["$", (
|
|
84
|
+
children: ["$", (w - T).toLocaleString()]
|
|
83
85
|
}) })]
|
|
84
86
|
})
|
|
85
87
|
]
|
|
86
88
|
}),
|
|
87
|
-
/* @__PURE__ */
|
|
88
|
-
className: "
|
|
89
|
-
children: [
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
89
|
+
/* @__PURE__ */ s(u, { children: [/* @__PURE__ */ s(f, {
|
|
90
|
+
className: "flex flex-row items-center justify-between space-y-0",
|
|
91
|
+
children: [/* @__PURE__ */ o(p, { children: "Recent Invoices" }), S.length > y && /* @__PURE__ */ o(l, {
|
|
92
|
+
variant: "ghost",
|
|
93
|
+
size: "sm",
|
|
94
|
+
onClick: () => x("../invoices-page"),
|
|
95
|
+
children: "View all"
|
|
96
|
+
})]
|
|
97
|
+
}), /* @__PURE__ */ o(d, { children: /* @__PURE__ */ o(v, {
|
|
98
|
+
data: D,
|
|
99
|
+
rowKey: (e) => e.id,
|
|
100
|
+
columns: [
|
|
101
|
+
{
|
|
102
|
+
key: "number",
|
|
103
|
+
header: "Invoice",
|
|
104
|
+
priority: "primary",
|
|
105
|
+
cell: (e) => /* @__PURE__ */ o("span", {
|
|
106
|
+
className: "font-medium",
|
|
107
|
+
children: e.number
|
|
108
|
+
})
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
key: "client",
|
|
112
|
+
header: "Client",
|
|
113
|
+
priority: "secondary",
|
|
114
|
+
cell: (e) => /* @__PURE__ */ o("span", {
|
|
115
|
+
className: "text-text-secondary",
|
|
116
|
+
children: e.clientName
|
|
117
|
+
})
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
key: "amount",
|
|
121
|
+
header: "Amount",
|
|
122
|
+
priority: "secondary",
|
|
123
|
+
headerClassName: "text-right",
|
|
124
|
+
cellClassName: "text-right",
|
|
125
|
+
cell: (e) => /* @__PURE__ */ s("span", { children: ["$", e.amount.toLocaleString()] })
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
key: "dueDate",
|
|
129
|
+
header: "Due Date",
|
|
130
|
+
priority: "hidden-on-mobile",
|
|
131
|
+
cell: (e) => /* @__PURE__ */ o("span", {
|
|
132
|
+
className: "text-text-secondary",
|
|
133
|
+
children: e.dueDate
|
|
134
|
+
})
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
key: "status",
|
|
138
|
+
header: "Status",
|
|
139
|
+
priority: "secondary",
|
|
140
|
+
cell: (e) => /* @__PURE__ */ o(c, {
|
|
141
|
+
variant: b(e.status),
|
|
125
142
|
className: "text-[10px]",
|
|
126
143
|
children: e.status
|
|
127
144
|
})
|
|
128
|
-
}
|
|
129
|
-
]
|
|
130
|
-
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
emptyState: /* @__PURE__ */ o(g, {
|
|
148
|
+
illustration: "empty-data",
|
|
149
|
+
title: "No invoices yet",
|
|
150
|
+
description: "Invoices you create will show up here."
|
|
151
|
+
})
|
|
152
|
+
}) })] })
|
|
131
153
|
]
|
|
132
154
|
});
|
|
133
155
|
}
|
|
134
156
|
//#endregion
|
|
135
|
-
export {
|
|
157
|
+
export { x as PaymentsPaymentDashboardPagePage };
|
|
136
158
|
|
|
137
159
|
//# sourceMappingURL=PaymentsPaymentDashboardPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaymentsPaymentDashboardPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/PaymentsPaymentDashboardPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { CreditCard, DollarSign, Receipt, TrendingUp } from 'lucide-react';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function PaymentsPaymentDashboardPagePage() {\n const { invoices, payrollRecords } = useCrewFoundryStore();\n const totalInvoiced = invoices.reduce((s, i) => s + i.amount, 0);\n const totalPaid = invoices.filter((i) => i.status === 'paid').reduce((s, i) => s + i.amount, 0);\n const totalPayroll = payrollRecords.reduce((s, r) => s + r.grossPay, 0);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Payment Dashboard</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Financial transactions and payment overview</p>\n <PagePurpose className=\"mt-1\">A snapshot of all money movement — incoming payments, payouts, and balances so you understand your financial position at a glance.</PagePurpose>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Invoiced</CardTitle>\n <Receipt className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalInvoiced.toLocaleString()}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Collected</CardTitle>\n <DollarSign className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalPaid.toLocaleString()}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Payroll Processed</CardTitle>\n <CreditCard className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalPayroll.toLocaleString()}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Outstanding</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalInvoiced - totalPaid).toLocaleString()}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n <Card>\n <CardHeader
|
|
1
|
+
{"version":3,"file":"PaymentsPaymentDashboardPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/PaymentsPaymentDashboardPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport { CreditCard, DollarSign, Receipt, TrendingUp } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore, type Invoice } from '../store/crewfoundryStore';\n\nconst RECENT_LIMIT = 5;\n\nconst statusVariant = (status: Invoice['status']) =>\n status === 'paid' ? 'default' : status === 'overdue' ? 'destructive' : 'secondary';\n\nexport function PaymentsPaymentDashboardPagePage() {\n const navigate = useNavigate();\n const { invoices, payrollRecords } = useCrewFoundryStore();\n const totalInvoiced = invoices.reduce((s, i) => s + i.amount, 0);\n const totalPaid = invoices.filter((i) => i.status === 'paid').reduce((s, i) => s + i.amount, 0);\n const totalPayroll = payrollRecords.reduce((s, r) => s + r.grossPay, 0);\n\n const recentInvoices = [...invoices]\n .sort((a, b) => (b.issueDate ?? '').localeCompare(a.issueDate ?? ''))\n .slice(0, RECENT_LIMIT);\n\n const columns: ResponsiveTableColumn<Invoice>[] = [\n {\n key: 'number',\n header: 'Invoice',\n priority: 'primary',\n cell: (inv) => <span className=\"font-medium\">{inv.number}</span>,\n },\n {\n key: 'client',\n header: 'Client',\n priority: 'secondary',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.clientName}</span>,\n },\n {\n key: 'amount',\n header: 'Amount',\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (inv) => <span>${inv.amount.toLocaleString()}</span>,\n },\n {\n key: 'dueDate',\n header: 'Due Date',\n priority: 'hidden-on-mobile',\n cell: (inv) => <span className=\"text-text-secondary\">{inv.dueDate}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n priority: 'secondary',\n cell: (inv) => (\n <Badge variant={statusVariant(inv.status)} className=\"text-[10px]\">\n {inv.status}\n </Badge>\n ),\n },\n ];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>Payment Dashboard</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Financial transactions and payment overview</p>\n <PagePurpose className=\"mt-1\">A snapshot of all money movement — incoming payments, payouts, and balances so you understand your financial position at a glance.</PagePurpose>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Total Invoiced</CardTitle>\n <Receipt className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalInvoiced.toLocaleString()}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Collected</CardTitle>\n <DollarSign className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalPaid.toLocaleString()}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Payroll Processed</CardTitle>\n <CreditCard className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">${totalPayroll.toLocaleString()}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Outstanding</CardTitle>\n <TrendingUp className=\"h-4 w-4 text-status-warning-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">\n ${(totalInvoiced - totalPaid).toLocaleString()}\n </div>\n </CardContent>\n </GlassCard>\n </div>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Recent Invoices</CardTitle>\n {invoices.length > RECENT_LIMIT && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigate('../invoices-page')}>\n View all\n </Button>\n )}\n </CardHeader>\n <CardContent>\n <ResponsiveTable\n data={recentInvoices}\n rowKey={(inv) => inv.id}\n columns={columns}\n emptyState={\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No invoices yet\"\n description=\"Invoices you create will show up here.\"\n />\n }\n />\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|