@burdenoff/microfe-crewfoundry 2026.704.3 → 2026.704.4
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 +76 -75
- package/dist/crewfoundry/pages/AdminAdminPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js +118 -117
- package/dist/crewfoundry/pages/AnalyticsFinancialAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js +115 -114
- package/dist/crewfoundry/pages/AnalyticsHiringAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js +105 -104
- package/dist/crewfoundry/pages/CommunicationsAnnouncementsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js +52 -51
- package/dist/crewfoundry/pages/CommunicationsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js +94 -93
- package/dist/crewfoundry/pages/CompanyClientManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js +97 -96
- package/dist/crewfoundry/pages/CompanyCompanyProfilePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js +68 -67
- package/dist/crewfoundry/pages/CompanyVendorManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js +96 -95
- package/dist/crewfoundry/pages/DashboardAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js +153 -152
- package/dist/crewfoundry/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js +107 -106
- package/dist/crewfoundry/pages/DashboardEnhancedDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js +77 -76
- package/dist/crewfoundry/pages/HiringApplicationsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +80 -79
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js +102 -101
- package/dist/crewfoundry/pages/HiringInterviewsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js +126 -125
- package/dist/crewfoundry/pages/HiringJobDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HiringJobsPagePage.js +64 -63
- package/dist/crewfoundry/pages/HiringJobsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js +96 -95
- package/dist/crewfoundry/pages/HrDepartmentsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +127 -126
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +118 -117
- package/dist/crewfoundry/pages/HrPayrollPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js +123 -122
- package/dist/crewfoundry/pages/HrTimeTrackingPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js +77 -76
- package/dist/crewfoundry/pages/LearningCourseDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js +49 -48
- package/dist/crewfoundry/pages/LearningCourseLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +62 -61
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPagePage.js +72 -71
- package/dist/crewfoundry/pages/LearningLearningPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js +70 -69
- package/dist/crewfoundry/pages/LearningLearningPathDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js +57 -56
- package/dist/crewfoundry/pages/LearningLearningPathsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js +58 -57
- package/dist/crewfoundry/pages/MarketplaceEarningsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js +122 -121
- package/dist/crewfoundry/pages/MarketplaceFreelancerProfilePageEnhancedPage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js +70 -69
- package/dist/crewfoundry/pages/MarketplaceMarketplacePagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js +41 -40
- package/dist/crewfoundry/pages/MarketplaceMarketplaceServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js +65 -64
- package/dist/crewfoundry/pages/MarketplaceMyServicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js +75 -74
- package/dist/crewfoundry/pages/MarketplaceProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js +60 -59
- package/dist/crewfoundry/pages/PaymentsInvoicesPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js +53 -52
- package/dist/crewfoundry/pages/PaymentsPaymentDashboardPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js +37 -36
- package/dist/crewfoundry/pages/PaymentsPaymentMethodsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js +126 -125
- package/dist/crewfoundry/pages/ProjectsProjectDetailsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js +62 -61
- package/dist/crewfoundry/pages/ProjectsProjectsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js +50 -49
- package/dist/crewfoundry/pages/TeamsTeamAnalyticsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js +72 -71
- package/dist/crewfoundry/pages/TeamsTeamDetailPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js +40 -39
- package/dist/crewfoundry/pages/TeamsTeamDirectoryPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js +130 -129
- package/dist/crewfoundry/pages/TeamsTeamSettingsPagePage.js.map +1 -1
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js +60 -59
- package/dist/crewfoundry/pages/TeamsTeamsPagePage.js.map +1 -1
- package/dist/crewfoundry/store/crewfoundryStore.js +177 -146
- package/dist/crewfoundry/store/crewfoundryStore.js.map +1 -1
- package/dist/crewfoundry/utils/formatEnumLabel.js +8 -0
- package/dist/crewfoundry/utils/formatEnumLabel.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceProjectDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceProjectDetailsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, DollarSign, MessageSquare, Users } from 'lucide-react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\n\nexport function MarketplaceProjectDetailsPagePage() {\n const navigate = useNavigate();\n const location = useLocation();\n const { projects } = useCrewFoundryStore();\n const selectedId = new URLSearchParams(location.search).get('id');\n const project = projects.find((p) => p.id === selectedId) ?? projects[0];\n if (!project)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Project not found\"\n description=\"This project is no longer available.\"\n />\n </div>\n );\n\n 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 <PagePurpose className=\"mt-2\">\n The full picture of a marketplace project — scope, budget, timeline, and progress — so\n you can track delivery and stay aligned with the team doing the work.\n </PagePurpose>\n </div>\n <Badge variant={project.status === 'active' ? 'default' : 'secondary'}>\n {project.status}\n </Badge>\n </div>\n\n <NextSteps\n storageKey=\"crewfoundry-marketplace-project-details\"\n steps={[\n {\n id: 'message',\n label: 'Message the team',\n description: 'Coordinate on scope, blockers, and next milestones.',\n icon: <MessageSquare className=\"h-4 w-4\" />,\n onClick: () => navigate('../../marketplace/messaging-page'),\n },\n {\n id: 'bookings',\n label: 'Review bookings',\n description: 'Check the engagements tied to this project.',\n icon: <Calendar className=\"h-4 w-4\" />,\n onClick: () => navigate('../../marketplace/booking-management-page'),\n },\n {\n id: 'earnings',\n label: 'Track earnings',\n description: 'See payouts and balances connected to your work.',\n icon: <DollarSign className=\"h-4 w-4\" />,\n onClick: () => navigate('../../marketplace/earnings-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 <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 <DollarSign className=\"h-5 w-5 mx-auto text-status-success-text mb-1\" />\n <p className=\"text-lg font-bold\">${(project.spent / 1000).toFixed(0)}K</p>\n <p className=\"text-xs text-text-secondary\">Spent</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\">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\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 <div className=\"grid grid-cols-2 gap-4 mt-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Manager</p>\n <p className=\"text-sm font-medium\">{project.managerName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Priority</p>\n <Badge\n variant={\n project.priority === 'critical'\n ? 'destructive'\n : project.priority === 'high'\n ? 'default'\n : 'secondary'\n }\n >\n {project.priority}\n </Badge>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Start Date</p>\n <p className=\"text-sm\">{project.startDate}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">End Date</p>\n <p className=\"text-sm\">{project.endDate}</p>\n </div>\n </div>\n </EmphasisPanel>\n </div>\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"MarketplaceProjectDetailsPagePage.js","names":[],"sources":["../../../src/crewfoundry/pages/MarketplaceProjectDetailsPagePage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n EmphasisPanel,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, DollarSign, MessageSquare, Users } from 'lucide-react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { useCrewFoundryStore } from '../store/crewfoundryStore';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nexport function MarketplaceProjectDetailsPagePage() {\n const navigate = useNavigate();\n const location = useLocation();\n const { projects } = useCrewFoundryStore();\n const selectedId = new URLSearchParams(location.search).get('id');\n const project = projects.find((p) => p.id === selectedId) ?? projects[0];\n if (!project)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Project not found\"\n description=\"This project is no longer available.\"\n />\n </div>\n );\n\n 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 <PagePurpose className=\"mt-2\">\n The full picture of a marketplace project — scope, budget, timeline, and progress — so\n you can track delivery and stay aligned with the team doing the work.\n </PagePurpose>\n </div>\n <Badge variant={project.status === 'active' ? 'default' : 'secondary'}>\n {formatEnumLabel(project.status)}\n </Badge>\n </div>\n\n <NextSteps\n storageKey=\"crewfoundry-marketplace-project-details\"\n steps={[\n {\n id: 'message',\n label: 'Message the team',\n description: 'Coordinate on scope, blockers, and next milestones.',\n icon: <MessageSquare className=\"h-4 w-4\" />,\n onClick: () => navigate('../../marketplace/messaging-page'),\n },\n {\n id: 'bookings',\n label: 'Review bookings',\n description: 'Check the engagements tied to this project.',\n icon: <Calendar className=\"h-4 w-4\" />,\n onClick: () => navigate('../../marketplace/booking-management-page'),\n },\n {\n id: 'earnings',\n label: 'Track earnings',\n description: 'See payouts and balances connected to your work.',\n icon: <DollarSign className=\"h-4 w-4\" />,\n onClick: () => navigate('../../marketplace/earnings-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 <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 <DollarSign className=\"h-5 w-5 mx-auto text-status-success-text mb-1\" />\n <p className=\"text-lg font-bold\">${(project.spent / 1000).toFixed(0)}K</p>\n <p className=\"text-xs text-text-secondary\">Spent</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\">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\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 <div className=\"grid grid-cols-2 gap-4 mt-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Manager</p>\n <p className=\"text-sm font-medium\">{project.managerName}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Priority</p>\n <Badge\n variant={\n project.priority === 'critical'\n ? 'destructive'\n : project.priority === 'high'\n ? 'default'\n : 'secondary'\n }\n >\n {formatEnumLabel(project.priority)}\n </Badge>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Start Date</p>\n <p className=\"text-sm\">{project.startDate}</p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">End Date</p>\n <p className=\"text-sm\">{project.endDate}</p>\n </div>\n </div>\n </EmphasisPanel>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
+
import { FormModal as n, useFormModal as r } from "../components/forms/FormModal.js";
|
|
4
|
+
import { CheckCircle2 as i, Pencil as a, Plus as o } from "lucide-react";
|
|
5
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
6
|
+
import { Badge as l, Button as u, CardContent as d, GlassCard as f, GradientText as p, IllustratedEmptyState as m, PagePurpose as h, Pagination as g, ResponsiveTable as _ } from "@burdenoff/fe-libs/ui";
|
|
7
|
+
import { usePagination as v } from "@burdenoff/fe-libs/shared/hooks";
|
|
7
8
|
//#region src/crewfoundry/pages/PaymentsInvoicesPagePage.tsx
|
|
8
|
-
var
|
|
9
|
+
var y = [
|
|
9
10
|
{
|
|
10
11
|
name: "number",
|
|
11
12
|
label: "Invoice number",
|
|
@@ -70,7 +71,7 @@ var v = [
|
|
|
70
71
|
colSpan: 2,
|
|
71
72
|
placeholder: "e.g. Consulting services"
|
|
72
73
|
}
|
|
73
|
-
],
|
|
74
|
+
], b = (e) => ({
|
|
74
75
|
number: e.number,
|
|
75
76
|
clientName: e.clientName,
|
|
76
77
|
amount: e.amount,
|
|
@@ -78,7 +79,7 @@ var v = [
|
|
|
78
79
|
issueDate: e.issueDate ? e.issueDate.slice(0, 10) : "",
|
|
79
80
|
dueDate: e.dueDate ? e.dueDate.slice(0, 10) : "",
|
|
80
81
|
lineItem: e.items[0]?.description ?? ""
|
|
81
|
-
}),
|
|
82
|
+
}), x = (e, t) => {
|
|
82
83
|
let n = typeof e.amount == "number" ? e.amount : Number(e.amount) || 0, r = String(e.lineItem ?? "").trim() || "Services rendered";
|
|
83
84
|
return {
|
|
84
85
|
id: t?.id ?? crypto.randomUUID(),
|
|
@@ -93,48 +94,48 @@ var v = [
|
|
|
93
94
|
amount: n
|
|
94
95
|
}]
|
|
95
96
|
};
|
|
96
|
-
},
|
|
97
|
-
function
|
|
98
|
-
let { invoices:
|
|
99
|
-
return /* @__PURE__ */
|
|
97
|
+
}, S = (e) => e === "paid" ? "default" : e === "overdue" ? "destructive" : e === "draft" ? "outline" : "secondary";
|
|
98
|
+
function C() {
|
|
99
|
+
let { invoices: C, addInvoice: w, updateInvoice: T } = e(), E = r(), { page: D, pageSize: O, offset: k, setPage: A } = v({ initialPageSize: 25 }), j = [...C].sort((e, t) => (t.issueDate ?? "").localeCompare(e.issueDate ?? "")), M = j.slice(k, k + O);
|
|
100
|
+
return /* @__PURE__ */ c("div", {
|
|
100
101
|
className: "space-y-6 p-6",
|
|
101
102
|
children: [
|
|
102
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ c("div", {
|
|
103
104
|
className: "flex items-center justify-between",
|
|
104
|
-
children: [/* @__PURE__ */
|
|
105
|
-
/* @__PURE__ */
|
|
105
|
+
children: [/* @__PURE__ */ c("div", { children: [
|
|
106
|
+
/* @__PURE__ */ s("h1", {
|
|
106
107
|
className: "text-2xl font-semibold",
|
|
107
|
-
children: /* @__PURE__ */
|
|
108
|
+
children: /* @__PURE__ */ s(p, { children: "Invoices" })
|
|
108
109
|
}),
|
|
109
|
-
/* @__PURE__ */
|
|
110
|
+
/* @__PURE__ */ c("p", {
|
|
110
111
|
className: "text-sm text-text-secondary",
|
|
111
|
-
children: [
|
|
112
|
+
children: [C.length, " invoices"]
|
|
112
113
|
}),
|
|
113
|
-
/* @__PURE__ */
|
|
114
|
+
/* @__PURE__ */ s(h, {
|
|
114
115
|
className: "mt-1",
|
|
115
116
|
children: "Create, send, and track invoices — see what's paid, pending, or overdue so you stay on top of getting paid."
|
|
116
117
|
})
|
|
117
|
-
] }), /* @__PURE__ */
|
|
118
|
+
] }), /* @__PURE__ */ c(u, {
|
|
118
119
|
size: "sm",
|
|
119
|
-
onClick: () =>
|
|
120
|
-
children: [/* @__PURE__ */ o
|
|
120
|
+
onClick: () => E.openModal(),
|
|
121
|
+
children: [/* @__PURE__ */ s(o, { className: "h-4 w-4 mr-1" }), "Create Invoice"]
|
|
121
122
|
})]
|
|
122
123
|
}),
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
+
/* @__PURE__ */ s(f, {
|
|
124
125
|
treatment: "glass",
|
|
125
126
|
glow: !0,
|
|
126
127
|
className: "border-border-seam",
|
|
127
|
-
children: /* @__PURE__ */
|
|
128
|
+
children: /* @__PURE__ */ c(d, {
|
|
128
129
|
className: "p-4",
|
|
129
|
-
children: [/* @__PURE__ */
|
|
130
|
-
data:
|
|
130
|
+
children: [/* @__PURE__ */ s(_, {
|
|
131
|
+
data: M,
|
|
131
132
|
rowKey: (e) => e.id,
|
|
132
133
|
columns: [
|
|
133
134
|
{
|
|
134
135
|
key: "number",
|
|
135
136
|
header: "Invoice #",
|
|
136
137
|
priority: "primary",
|
|
137
|
-
cell: (e) => /* @__PURE__ */
|
|
138
|
+
cell: (e) => /* @__PURE__ */ s("span", {
|
|
138
139
|
className: "font-medium",
|
|
139
140
|
children: e.number
|
|
140
141
|
})
|
|
@@ -143,7 +144,7 @@ function S() {
|
|
|
143
144
|
key: "client",
|
|
144
145
|
header: "Client",
|
|
145
146
|
priority: "secondary",
|
|
146
|
-
cell: (e) => /* @__PURE__ */
|
|
147
|
+
cell: (e) => /* @__PURE__ */ s("span", {
|
|
147
148
|
className: "text-text-secondary",
|
|
148
149
|
children: e.clientName
|
|
149
150
|
})
|
|
@@ -152,7 +153,7 @@ function S() {
|
|
|
152
153
|
key: "items",
|
|
153
154
|
header: "Items",
|
|
154
155
|
priority: "hidden-on-mobile",
|
|
155
|
-
cell: (e) => /* @__PURE__ */
|
|
156
|
+
cell: (e) => /* @__PURE__ */ s("span", {
|
|
156
157
|
className: "text-xs text-text-secondary",
|
|
157
158
|
children: e.items.map((e) => e.description).join(", ")
|
|
158
159
|
})
|
|
@@ -163,7 +164,7 @@ function S() {
|
|
|
163
164
|
priority: "secondary",
|
|
164
165
|
headerClassName: "text-right",
|
|
165
166
|
cellClassName: "text-right",
|
|
166
|
-
cell: (e) => /* @__PURE__ */
|
|
167
|
+
cell: (e) => /* @__PURE__ */ c("span", {
|
|
167
168
|
className: "font-medium",
|
|
168
169
|
children: ["$", e.amount.toLocaleString()]
|
|
169
170
|
})
|
|
@@ -172,7 +173,7 @@ function S() {
|
|
|
172
173
|
key: "dueDate",
|
|
173
174
|
header: "Due Date",
|
|
174
175
|
priority: "secondary",
|
|
175
|
-
cell: (e) => /* @__PURE__ */
|
|
176
|
+
cell: (e) => /* @__PURE__ */ s("span", {
|
|
176
177
|
className: "text-text-secondary",
|
|
177
178
|
children: e.dueDate
|
|
178
179
|
})
|
|
@@ -181,64 +182,64 @@ function S() {
|
|
|
181
182
|
key: "status",
|
|
182
183
|
header: "Status",
|
|
183
184
|
priority: "secondary",
|
|
184
|
-
cell: (e) => /* @__PURE__ */
|
|
185
|
-
variant:
|
|
185
|
+
cell: (e) => /* @__PURE__ */ s(l, {
|
|
186
|
+
variant: S(e.status),
|
|
186
187
|
className: "text-[10px]",
|
|
187
|
-
children: e.status
|
|
188
|
+
children: t(e.status)
|
|
188
189
|
})
|
|
189
190
|
}
|
|
190
191
|
],
|
|
191
|
-
emptyState: /* @__PURE__ */
|
|
192
|
+
emptyState: /* @__PURE__ */ s(m, {
|
|
192
193
|
illustration: "empty-data",
|
|
193
194
|
title: "No invoices yet",
|
|
194
195
|
description: "Create your first invoice to start getting paid."
|
|
195
196
|
}),
|
|
196
|
-
rowActions: (e) => /* @__PURE__ */
|
|
197
|
+
rowActions: (e) => /* @__PURE__ */ c("div", {
|
|
197
198
|
className: "flex items-center justify-end gap-1",
|
|
198
|
-
children: [/* @__PURE__ */
|
|
199
|
+
children: [/* @__PURE__ */ s(u, {
|
|
199
200
|
variant: "ghost",
|
|
200
201
|
size: "sm",
|
|
201
202
|
"aria-label": `Edit invoice ${e.number}`,
|
|
202
|
-
onClick: () =>
|
|
203
|
-
children: /* @__PURE__ */
|
|
204
|
-
}), e.status === "paid" ? /* @__PURE__ */
|
|
203
|
+
onClick: () => E.openModal(e),
|
|
204
|
+
children: /* @__PURE__ */ s(a, { className: "h-3.5 w-3.5" })
|
|
205
|
+
}), e.status === "paid" ? /* @__PURE__ */ c("span", {
|
|
205
206
|
className: "inline-flex items-center gap-1 text-xs text-status-success-text",
|
|
206
|
-
children: [/* @__PURE__ */
|
|
207
|
-
}) : /* @__PURE__ */
|
|
207
|
+
children: [/* @__PURE__ */ s(i, { className: "h-3.5 w-3.5" }), "Paid"]
|
|
208
|
+
}) : /* @__PURE__ */ c(u, {
|
|
208
209
|
variant: "outline",
|
|
209
210
|
size: "sm",
|
|
210
211
|
"aria-label": `Mark invoice ${e.number} as paid`,
|
|
211
|
-
onClick: () => void
|
|
212
|
-
children: [/* @__PURE__ */
|
|
212
|
+
onClick: () => void T(e.id, { status: "paid" }),
|
|
213
|
+
children: [/* @__PURE__ */ s(i, { className: "h-3.5 w-3.5 mr-1" }), "Mark Paid"]
|
|
213
214
|
})]
|
|
214
215
|
})
|
|
215
|
-
}),
|
|
216
|
+
}), j.length > O && /* @__PURE__ */ s("div", {
|
|
216
217
|
className: "mt-4",
|
|
217
|
-
children: /* @__PURE__ */
|
|
218
|
-
page:
|
|
219
|
-
pageSize:
|
|
220
|
-
totalItems:
|
|
221
|
-
onPageChange:
|
|
218
|
+
children: /* @__PURE__ */ s(g, {
|
|
219
|
+
page: D,
|
|
220
|
+
pageSize: O,
|
|
221
|
+
totalItems: j.length,
|
|
222
|
+
onPageChange: A
|
|
222
223
|
})
|
|
223
224
|
})]
|
|
224
225
|
})
|
|
225
226
|
}),
|
|
226
|
-
/* @__PURE__ */
|
|
227
|
-
open:
|
|
228
|
-
onOpenChange:
|
|
229
|
-
title:
|
|
227
|
+
/* @__PURE__ */ s(n, {
|
|
228
|
+
open: E.open,
|
|
229
|
+
onOpenChange: E.onOpenChange,
|
|
230
|
+
title: E.context ? "Edit invoice" : "Create invoice",
|
|
230
231
|
description: "Issue a new invoice to a client and track its payment status.",
|
|
231
|
-
fields:
|
|
232
|
-
initialValues:
|
|
233
|
-
submitLabel:
|
|
232
|
+
fields: y,
|
|
233
|
+
initialValues: E.context ? b(E.context) : void 0,
|
|
234
|
+
submitLabel: E.context ? "Save changes" : "Create invoice",
|
|
234
235
|
onSubmit: async (e) => {
|
|
235
|
-
|
|
236
|
+
E.context ? await T(E.context.id, x(e, E.context)) : await w(x(e));
|
|
236
237
|
}
|
|
237
238
|
})
|
|
238
239
|
]
|
|
239
240
|
});
|
|
240
241
|
}
|
|
241
242
|
//#endregion
|
|
242
|
-
export {
|
|
243
|
+
export { C as PaymentsInvoicesPagePage };
|
|
243
244
|
|
|
244
245
|
//# 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 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 {\n name: 'number',\n label: 'Invoice number',\n type: 'text',\n required: true,\n placeholder: 'INV-0001',\n },\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\">\n Create, send, and track invoices — see what's paid, pending, or overdue so you stay\n on top of getting paid.\n </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
|
+
{"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';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\n\nconst INVOICE_FIELDS: FieldConfig[] = [\n {\n name: 'number',\n label: 'Invoice number',\n type: 'text',\n required: true,\n placeholder: 'INV-0001',\n },\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 {formatEnumLabel(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\">\n Create, send, and track invoices — see what's paid, pending, or overdue so you stay\n on top of getting paid.\n </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":";;;;;;;;AAuBA,IAAM,IAAgC;CACpC;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,UAAU;EACV,aAAa;EACd;CACD;EAAE,MAAM;EAAc,OAAO;EAAe,MAAM;EAAQ,UAAU;EAAM;CAC1E;EAAE,MAAM;EAAU,OAAO;EAAgB,MAAM;EAAU,UAAU;EAAM;CACzE;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,SAAS;GACP;IAAE,OAAO;IAAS,OAAO;IAAS;GAClC;IAAE,OAAO;IAAQ,OAAO;IAAQ;GAChC;IAAE,OAAO;IAAQ,OAAO;IAAQ;GAChC;IAAE,OAAO;IAAW,OAAO;IAAW;GACtC;IAAE,OAAO;IAAa,OAAO;IAAa;GAC3C;EACF;CACD;EAAE,MAAM;EAAa,OAAO;EAAc,MAAM;EAAQ,UAAU;EAAM;CACxE;EAAE,MAAM;EAAW,OAAO;EAAY,MAAM;EAAQ;CACpD;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,SAAS;EACT,aAAa;EACd;CACF,EAEK,KAAmB,OAAkC;CACzD,QAAQ,EAAQ;CAChB,YAAY,EAAQ;CACpB,QAAQ,EAAQ;CAChB,QAAQ,EAAQ;CAChB,WAAW,EAAQ,YAAY,EAAQ,UAAU,MAAM,GAAG,GAAG,GAAG;CAChE,SAAS,EAAQ,UAAU,EAAQ,QAAQ,MAAM,GAAG,GAAG,GAAG;CAC1D,UAAU,EAAQ,MAAM,IAAI,eAAe;CAC5C,GAEK,KAAmB,GAAoB,MAA4B;CACvE,IAAM,IAAS,OAAO,EAAO,UAAW,WAAW,EAAO,SAAS,OAAO,EAAO,OAAO,IAAI,GACtF,IAAc,OAAO,EAAO,YAAY,GAAG,CAAC,MAAM,IAAI;AAC5D,QAAO;EACL,IAAI,GAAM,MAAM,OAAO,YAAY;EACnC,QAAQ,OAAO,EAAO,UAAU,GAAG;EACnC,YAAY,OAAO,EAAO,cAAc,GAAG;EAC3C;EACA,QAAS,EAAO,UAAgC;EAChD,WAAW,OAAO,EAAO,aAAa,GAAG;EACzC,SAAS,OAAO,EAAO,WAAW,GAAG;EACrC,OAAO,CAAC;GAAE;GAAa;GAAQ,CAAC;EACjC;GAGG,KAAiB,MACrB,MAAW,SACP,YACA,MAAW,YACT,gBACA,MAAW,UACT,YACA;AAEV,SAAgB,IAA2B;CACzC,IAAM,EAAE,aAAU,eAAY,qBAAkB,GAAqB,EAC/D,IAAQ,GAAuB,EAC/B,EAAE,SAAM,aAAU,WAAQ,eAAY,EAAc,EAAE,iBAAiB,IAAI,CAAC,EAE5E,IAAS,CAAC,GAAG,EAAS,CAAC,MAAM,GAAG,OAAO,EAAE,aAAa,IAAI,cAAc,EAAE,aAAa,GAAG,CAAC,EAC3F,IAAQ,EAAO,MAAM,GAAQ,IAAS,EAAS;AA2DrD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA;KACE,kBAAC,MAAD;MAAI,WAAU;gBACZ,kBAAC,GAAD,EAAA,UAAc,YAAuB,CAAA;MAClC,CAAA;KACL,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAA4C,EAAS,QAAO,YAAa;;KACzE,kBAAC,GAAD;MAAa,WAAU;gBAAO;MAGhB,CAAA;KACV,EAAA,CAAA,EACN,kBAAC,GAAD;KAAQ,MAAK;KAAK,eAAe,EAAM,WAAW;eAAlD,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,iBAE1B;OACL;;GACN,kBAAC,GAAD;IAAW,WAAU;IAAQ,MAAA;IAAK,WAAU;cAC1C,kBAAC,GAAD;KAAa,WAAU;eAAvB,CACE,kBAAC,GAAD;MACE,MAAM;MACN,SAAS,MAAQ,EAAI;MACZ,SAxE+B;OAChD;QACE,KAAK;QACL,QAAQ;QACR,UAAU;QACV,OAAO,MAAQ,kBAAC,QAAD;SAAM,WAAU;mBAAe,EAAI;SAAc,CAAA;QACjE;OACD;QACE,KAAK;QACL,QAAQ;QACR,UAAU;QACV,OAAO,MAAQ,kBAAC,QAAD;SAAM,WAAU;mBAAuB,EAAI;SAAkB,CAAA;QAC7E;OACD;QACE,KAAK;QACL,QAAQ;QACR,UAAU;QACV,OAAO,MACL,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAI,MAAM,KAAK,MAAM,EAAE,YAAY,CAAC,KAAK,KAAK;SAC1C,CAAA;QAEV;OACD;QACE,KAAK;QACL,QAAQ;QACR,UAAU;QACV,iBAAiB;QACjB,eAAe;QACf,OAAO,MAAQ,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CAA8B,KAAE,EAAI,OAAO,gBAAgB,CAAQ;;QACnF;OACD;QACE,KAAK;QACL,QAAQ;QACR,UAAU;QACV,OAAO,MAAQ,kBAAC,QAAD;SAAM,WAAU;mBAAuB,EAAI;SAAe,CAAA;QAC1E;OACD;QACE,KAAK;QACL,QAAQ;QACR,UAAU;QACV,OAAO,MACL,kBAAC,GAAD;SAAO,SAAS,EAAc,EAAI,OAAO;SAAE,WAAU;mBAClD,EAAgB,EAAI,OAAO;SACtB,CAAA;QAEX;OACF;MA0BS,YACE,kBAAC,GAAD;OACE,cAAa;OACb,OAAM;OACN,aAAY;OACZ,CAAA;MAEJ,aAAa,MACX,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,cAAY,gBAAgB,EAAI;QAChC,eAAe,EAAM,UAAU,EAAI;kBAEnC,kBAAC,GAAD,EAAQ,WAAU,eAAgB,CAAA;QAC3B,CAAA,EACR,EAAI,WAAW,SACd,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAc,WAAU,eAAgB,CAAA,EAAA,OAEnC;YAEP,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,cAAY,gBAAgB,EAAI,OAAO;QACvC,eAAe,KAAK,EAAc,EAAI,IAAI,EAAE,QAAQ,QAAQ,CAAC;kBAJ/D,CAME,kBAAC,GAAD,EAAc,WAAU,oBAAqB,CAAA,EAAA,YAEtC;UAEP;;MAER,CAAA,EACD,EAAO,SAAS,KACf,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD;OACQ;OACI;OACV,YAAY,EAAO;OACnB,cAAc;OACd,CAAA;MACE,CAAA,CAEI;;IACJ,CAAA;GAEZ,kBAAC,GAAD;IACE,MAAM,EAAM;IACZ,cAAc,EAAM;IACpB,OAAO,EAAM,UAAU,iBAAiB;IACxC,aAAY;IACZ,QAAQ;IACR,eAAe,EAAM,UAAU,EAAgB,EAAM,QAAQ,GAAG,KAAA;IAChE,aAAa,EAAM,UAAU,iBAAiB;IAC9C,UA1Ie,OAAO,MAAuB;AACjD,KAAI,EAAM,UACR,MAAM,EAAc,EAAM,QAAQ,IAAI,EAAgB,GAAQ,EAAM,QAAQ,CAAC,GAE7E,MAAM,EAAW,EAAgB,EAAO,CAAC;;IAuIvC,CAAA;GACE"}
|
|
@@ -1,108 +1,109 @@
|
|
|
1
1
|
import { useCrewFoundryStore as e } from "../store/crewfoundryStore.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { formatEnumLabel as t } from "../utils/formatEnumLabel.js";
|
|
3
|
+
import { CreditCard as n, DollarSign as r, Receipt as i, TrendingUp as a } from "lucide-react";
|
|
4
|
+
import { useNavigate as o } from "react-router-dom";
|
|
5
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
6
|
+
import { Badge as l, Button as u, Card as d, CardContent as f, CardHeader as p, CardTitle as m, GlassCard as h, GradientText as g, IllustratedEmptyState as _, PagePurpose as v, ResponsiveTable as y } from "@burdenoff/fe-libs/ui";
|
|
6
7
|
//#region src/crewfoundry/pages/PaymentsPaymentDashboardPagePage.tsx
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
-
let
|
|
10
|
-
return /* @__PURE__ */
|
|
8
|
+
var b = 5, x = (e) => e === "paid" ? "default" : e === "overdue" ? "destructive" : "secondary";
|
|
9
|
+
function S() {
|
|
10
|
+
let S = o(), { invoices: C, payrollRecords: w } = e(), T = C.reduce((e, t) => e + t.amount, 0), E = C.filter((e) => e.status === "paid").reduce((e, t) => e + t.amount, 0), D = w.reduce((e, t) => e + t.grossPay, 0), O = [...C].sort((e, t) => (t.issueDate ?? "").localeCompare(e.issueDate ?? "")).slice(0, b);
|
|
11
|
+
return /* @__PURE__ */ c("div", {
|
|
11
12
|
className: "space-y-6 p-6",
|
|
12
13
|
children: [
|
|
13
|
-
/* @__PURE__ */
|
|
14
|
-
/* @__PURE__ */
|
|
14
|
+
/* @__PURE__ */ c("div", { children: [
|
|
15
|
+
/* @__PURE__ */ s("h1", {
|
|
15
16
|
className: "text-2xl font-semibold",
|
|
16
|
-
children: /* @__PURE__ */
|
|
17
|
+
children: /* @__PURE__ */ s(g, { children: "Payment Dashboard" })
|
|
17
18
|
}),
|
|
18
|
-
/* @__PURE__ */
|
|
19
|
+
/* @__PURE__ */ s("p", {
|
|
19
20
|
className: "text-sm text-text-secondary",
|
|
20
21
|
children: "Financial transactions and payment overview"
|
|
21
22
|
}),
|
|
22
|
-
/* @__PURE__ */
|
|
23
|
+
/* @__PURE__ */ s(v, {
|
|
23
24
|
className: "mt-1",
|
|
24
25
|
children: "A snapshot of all money movement — incoming payments, payouts, and balances so you understand your financial position at a glance."
|
|
25
26
|
})
|
|
26
27
|
] }),
|
|
27
|
-
/* @__PURE__ */
|
|
28
|
+
/* @__PURE__ */ c("div", {
|
|
28
29
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
29
30
|
children: [
|
|
30
|
-
/* @__PURE__ */
|
|
31
|
+
/* @__PURE__ */ c(h, {
|
|
31
32
|
treatment: "glass",
|
|
32
33
|
glow: !0,
|
|
33
34
|
className: "border-border-seam",
|
|
34
|
-
children: [/* @__PURE__ */
|
|
35
|
+
children: [/* @__PURE__ */ c(p, {
|
|
35
36
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
36
|
-
children: [/* @__PURE__ */
|
|
37
|
+
children: [/* @__PURE__ */ s(m, {
|
|
37
38
|
className: "text-sm font-medium",
|
|
38
39
|
children: "Total Invoiced"
|
|
39
|
-
}), /* @__PURE__ */
|
|
40
|
-
}), /* @__PURE__ */
|
|
40
|
+
}), /* @__PURE__ */ s(i, { className: "h-4 w-4 text-text-secondary" })]
|
|
41
|
+
}), /* @__PURE__ */ s(f, { children: /* @__PURE__ */ c("div", {
|
|
41
42
|
className: "text-2xl font-bold tabular-nums",
|
|
42
|
-
children: ["$",
|
|
43
|
+
children: ["$", T.toLocaleString()]
|
|
43
44
|
}) })]
|
|
44
45
|
}),
|
|
45
|
-
/* @__PURE__ */
|
|
46
|
+
/* @__PURE__ */ c(h, {
|
|
46
47
|
treatment: "metric",
|
|
47
48
|
className: "border-border-seam",
|
|
48
|
-
children: [/* @__PURE__ */
|
|
49
|
+
children: [/* @__PURE__ */ c(p, {
|
|
49
50
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
50
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ s(m, {
|
|
51
52
|
className: "text-sm font-medium",
|
|
52
53
|
children: "Collected"
|
|
53
|
-
}), /* @__PURE__ */
|
|
54
|
-
}), /* @__PURE__ */
|
|
54
|
+
}), /* @__PURE__ */ s(r, { className: "h-4 w-4 text-status-success-text" })]
|
|
55
|
+
}), /* @__PURE__ */ s(f, { children: /* @__PURE__ */ c("div", {
|
|
55
56
|
className: "text-2xl font-bold tabular-nums",
|
|
56
|
-
children: ["$",
|
|
57
|
+
children: ["$", E.toLocaleString()]
|
|
57
58
|
}) })]
|
|
58
59
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ c(h, {
|
|
60
61
|
treatment: "metric",
|
|
61
62
|
className: "border-border-seam",
|
|
62
|
-
children: [/* @__PURE__ */
|
|
63
|
+
children: [/* @__PURE__ */ c(p, {
|
|
63
64
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
64
|
-
children: [/* @__PURE__ */
|
|
65
|
+
children: [/* @__PURE__ */ s(m, {
|
|
65
66
|
className: "text-sm font-medium",
|
|
66
67
|
children: "Payroll Processed"
|
|
67
|
-
}), /* @__PURE__ */
|
|
68
|
-
}), /* @__PURE__ */
|
|
68
|
+
}), /* @__PURE__ */ s(n, { className: "h-4 w-4 text-text-secondary" })]
|
|
69
|
+
}), /* @__PURE__ */ s(f, { children: /* @__PURE__ */ c("div", {
|
|
69
70
|
className: "text-2xl font-bold tabular-nums",
|
|
70
|
-
children: ["$",
|
|
71
|
+
children: ["$", D.toLocaleString()]
|
|
71
72
|
}) })]
|
|
72
73
|
}),
|
|
73
|
-
/* @__PURE__ */
|
|
74
|
+
/* @__PURE__ */ c(h, {
|
|
74
75
|
treatment: "metric",
|
|
75
76
|
className: "border-border-seam",
|
|
76
|
-
children: [/* @__PURE__ */
|
|
77
|
+
children: [/* @__PURE__ */ c(p, {
|
|
77
78
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
78
|
-
children: [/* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ s(m, {
|
|
79
80
|
className: "text-sm font-medium",
|
|
80
81
|
children: "Outstanding"
|
|
81
|
-
}), /* @__PURE__ */
|
|
82
|
-
}), /* @__PURE__ */
|
|
82
|
+
}), /* @__PURE__ */ s(a, { className: "h-4 w-4 text-status-warning-text" })]
|
|
83
|
+
}), /* @__PURE__ */ s(f, { children: /* @__PURE__ */ c("div", {
|
|
83
84
|
className: "text-2xl font-bold tabular-nums",
|
|
84
|
-
children: ["$", (
|
|
85
|
+
children: ["$", (T - E).toLocaleString()]
|
|
85
86
|
}) })]
|
|
86
87
|
})
|
|
87
88
|
]
|
|
88
89
|
}),
|
|
89
|
-
/* @__PURE__ */
|
|
90
|
+
/* @__PURE__ */ c(d, { children: [/* @__PURE__ */ c(p, {
|
|
90
91
|
className: "flex flex-row items-center justify-between space-y-0",
|
|
91
|
-
children: [/* @__PURE__ */
|
|
92
|
+
children: [/* @__PURE__ */ s(m, { children: "Recent Invoices" }), C.length > b && /* @__PURE__ */ s(u, {
|
|
92
93
|
variant: "ghost",
|
|
93
94
|
size: "sm",
|
|
94
|
-
onClick: () =>
|
|
95
|
+
onClick: () => S("../../payments/invoices-page"),
|
|
95
96
|
children: "View all"
|
|
96
97
|
})]
|
|
97
|
-
}), /* @__PURE__ */
|
|
98
|
-
data:
|
|
98
|
+
}), /* @__PURE__ */ s(f, { children: /* @__PURE__ */ s(y, {
|
|
99
|
+
data: O,
|
|
99
100
|
rowKey: (e) => e.id,
|
|
100
101
|
columns: [
|
|
101
102
|
{
|
|
102
103
|
key: "number",
|
|
103
104
|
header: "Invoice",
|
|
104
105
|
priority: "primary",
|
|
105
|
-
cell: (e) => /* @__PURE__ */
|
|
106
|
+
cell: (e) => /* @__PURE__ */ s("span", {
|
|
106
107
|
className: "font-medium",
|
|
107
108
|
children: e.number
|
|
108
109
|
})
|
|
@@ -111,7 +112,7 @@ function x() {
|
|
|
111
112
|
key: "client",
|
|
112
113
|
header: "Client",
|
|
113
114
|
priority: "secondary",
|
|
114
|
-
cell: (e) => /* @__PURE__ */
|
|
115
|
+
cell: (e) => /* @__PURE__ */ s("span", {
|
|
115
116
|
className: "text-text-secondary",
|
|
116
117
|
children: e.clientName
|
|
117
118
|
})
|
|
@@ -122,13 +123,13 @@ function x() {
|
|
|
122
123
|
priority: "secondary",
|
|
123
124
|
headerClassName: "text-right",
|
|
124
125
|
cellClassName: "text-right",
|
|
125
|
-
cell: (e) => /* @__PURE__ */
|
|
126
|
+
cell: (e) => /* @__PURE__ */ c("span", { children: ["$", e.amount.toLocaleString()] })
|
|
126
127
|
},
|
|
127
128
|
{
|
|
128
129
|
key: "dueDate",
|
|
129
130
|
header: "Due Date",
|
|
130
131
|
priority: "hidden-on-mobile",
|
|
131
|
-
cell: (e) => /* @__PURE__ */
|
|
132
|
+
cell: (e) => /* @__PURE__ */ s("span", {
|
|
132
133
|
className: "text-text-secondary",
|
|
133
134
|
children: e.dueDate
|
|
134
135
|
})
|
|
@@ -137,14 +138,14 @@ function x() {
|
|
|
137
138
|
key: "status",
|
|
138
139
|
header: "Status",
|
|
139
140
|
priority: "secondary",
|
|
140
|
-
cell: (e) => /* @__PURE__ */
|
|
141
|
-
variant:
|
|
141
|
+
cell: (e) => /* @__PURE__ */ s(l, {
|
|
142
|
+
variant: x(e.status),
|
|
142
143
|
className: "text-[10px]",
|
|
143
|
-
children: e.status
|
|
144
|
+
children: t(e.status)
|
|
144
145
|
})
|
|
145
146
|
}
|
|
146
147
|
],
|
|
147
|
-
emptyState: /* @__PURE__ */
|
|
148
|
+
emptyState: /* @__PURE__ */ s(_, {
|
|
148
149
|
illustration: "empty-data",
|
|
149
150
|
title: "No invoices yet",
|
|
150
151
|
description: "Invoices you create will show up here."
|
|
@@ -154,6 +155,6 @@ function x() {
|
|
|
154
155
|
});
|
|
155
156
|
}
|
|
156
157
|
//#endregion
|
|
157
|
-
export {
|
|
158
|
+
export { S as PaymentsPaymentDashboardPagePage };
|
|
158
159
|
|
|
159
160
|
//# sourceMappingURL=PaymentsPaymentDashboardPagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
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\">\n A snapshot of all money movement — incoming payments, payouts, and balances so you\n understand your financial position at a glance.\n </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
|
|
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';\nimport { formatEnumLabel } from '../utils/formatEnumLabel';\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 {formatEnumLabel(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\">\n A snapshot of all money movement — incoming payments, payouts, and balances so you\n understand your financial position at a glance.\n </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\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => navigate('../../payments/invoices-page')}\n >\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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"}
|