@powerhousedao/contributor-billing 0.1.36 → 0.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/document-models/account-transactions/gen/schema/types.d.ts +3 -3
  2. package/dist/document-models/account-transactions/gen/schema/types.d.ts.map +1 -1
  3. package/dist/document-models/accounts/gen/schema/types.d.ts +7 -7
  4. package/dist/document-models/accounts/gen/schema/types.d.ts.map +1 -1
  5. package/dist/document-models/billing-statement/gen/document-schema.d.ts +16 -16
  6. package/dist/document-models/billing-statement/gen/document-schema.d.ts.map +1 -1
  7. package/dist/document-models/billing-statement/gen/schema/types.d.ts +5 -5
  8. package/dist/document-models/billing-statement/gen/schema/types.d.ts.map +1 -1
  9. package/dist/document-models/expense-report/gen/document-model.js +1 -1
  10. package/dist/document-models/expense-report/gen/document-schema.d.ts +16 -16
  11. package/dist/document-models/expense-report/gen/ph-factories.d.ts.map +1 -1
  12. package/dist/document-models/expense-report/gen/ph-factories.js +5 -0
  13. package/dist/document-models/expense-report/gen/schema/types.d.ts +2 -2
  14. package/dist/document-models/expense-report/gen/schema/types.d.ts.map +1 -1
  15. package/dist/document-models/expense-report/gen/schema/zod.d.ts.map +1 -1
  16. package/dist/document-models/expense-report/gen/schema/zod.js +10 -30
  17. package/dist/document-models/expense-report/gen/utils.d.ts.map +1 -1
  18. package/dist/document-models/expense-report/gen/utils.js +5 -0
  19. package/dist/document-models/expense-report/src/reducers/wallet.d.ts.map +1 -1
  20. package/dist/document-models/expense-report/src/reducers/wallet.js +61 -0
  21. package/dist/document-models/invoice/gen/document-schema.d.ts +32 -32
  22. package/dist/document-models/invoice/gen/document-schema.d.ts.map +1 -1
  23. package/dist/document-models/invoice/gen/schema/types.d.ts +10 -10
  24. package/dist/document-models/invoice/gen/schema/types.d.ts.map +1 -1
  25. package/dist/document-models/invoice/gen/schema/zod.d.ts.map +1 -1
  26. package/dist/document-models/service-offering/gen/document-schema.d.ts +16 -16
  27. package/dist/document-models/service-offering/gen/document-schema.d.ts.map +1 -1
  28. package/dist/document-models/service-offering/gen/schema/types.d.ts +11 -11
  29. package/dist/document-models/service-offering/gen/schema/types.d.ts.map +1 -1
  30. package/dist/document-models/service-subscriptions/gen/schema/types.d.ts +6 -6
  31. package/dist/document-models/service-subscriptions/gen/schema/types.d.ts.map +1 -1
  32. package/dist/document-models/snapshot-report/gen/document-schema.d.ts.map +1 -1
  33. package/dist/document-models/snapshot-report/gen/schema/types.d.ts +8 -8
  34. package/dist/document-models/snapshot-report/gen/schema/types.d.ts.map +1 -1
  35. package/dist/document-models/snapshot-report/src/reducers/configuration.d.ts.map +1 -1
  36. package/dist/document-models/snapshot-report/src/reducers/configuration.js +1 -1
  37. package/dist/editors/accounts-editor/components/AccountForm.d.ts.map +1 -1
  38. package/dist/editors/accounts-editor/components/AccountForm.js +3 -1
  39. package/dist/editors/builder-team-admin/components/FolderTree.d.ts.map +1 -1
  40. package/dist/editors/builder-team-admin/components/FolderTree.js +2 -2
  41. package/dist/editors/contributor-billing/components/AddMonthButton.d.ts +5 -0
  42. package/dist/editors/contributor-billing/components/AddMonthButton.d.ts.map +1 -0
  43. package/dist/editors/contributor-billing/components/AddMonthButton.js +56 -0
  44. package/dist/editors/contributor-billing/components/BillingOverview.d.ts +10 -0
  45. package/dist/editors/contributor-billing/components/BillingOverview.d.ts.map +1 -0
  46. package/dist/editors/contributor-billing/components/BillingOverview.js +117 -0
  47. package/dist/editors/contributor-billing/components/DashboardHome.d.ts +11 -0
  48. package/dist/editors/contributor-billing/components/DashboardHome.d.ts.map +1 -0
  49. package/dist/editors/contributor-billing/components/DashboardHome.js +51 -0
  50. package/dist/editors/contributor-billing/components/DriveContents.d.ts +8 -2
  51. package/dist/editors/contributor-billing/components/DriveContents.d.ts.map +1 -1
  52. package/dist/editors/contributor-billing/components/DriveContents.js +24 -10
  53. package/dist/editors/contributor-billing/components/DriveExplorer.d.ts.map +1 -1
  54. package/dist/editors/contributor-billing/components/DriveExplorer.js +18 -3
  55. package/dist/editors/contributor-billing/components/FolderTree.d.ts +19 -9
  56. package/dist/editors/contributor-billing/components/FolderTree.d.ts.map +1 -1
  57. package/dist/editors/contributor-billing/components/FolderTree.js +200 -103
  58. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.d.ts +8 -1
  59. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.d.ts.map +1 -1
  60. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.js +5 -3
  61. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderStats.d.ts +6 -1
  62. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderStats.d.ts.map +1 -1
  63. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderStats.js +14 -6
  64. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts +6 -2
  65. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts.map +1 -1
  66. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.js +68 -19
  67. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.d.ts +10 -1
  68. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.d.ts.map +1 -1
  69. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.js +145 -32
  70. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableRow.d.ts.map +1 -1
  71. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableRow.js +6 -1
  72. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableSection.d.ts +1 -1
  73. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableSection.d.ts.map +1 -1
  74. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableSection.js +33 -7
  75. package/dist/editors/contributor-billing/components/MonthOverview.d.ts +12 -0
  76. package/dist/editors/contributor-billing/components/MonthOverview.d.ts.map +1 -0
  77. package/dist/editors/contributor-billing/components/MonthOverview.js +35 -0
  78. package/dist/editors/contributor-billing/components/MonthlyReporting.d.ts +13 -0
  79. package/dist/editors/contributor-billing/components/MonthlyReporting.d.ts.map +1 -0
  80. package/dist/editors/contributor-billing/components/MonthlyReporting.js +90 -0
  81. package/dist/editors/contributor-billing/components/ReportingView.d.ts +10 -0
  82. package/dist/editors/contributor-billing/components/ReportingView.d.ts.map +1 -0
  83. package/dist/editors/contributor-billing/components/ReportingView.js +112 -0
  84. package/dist/editors/contributor-billing/config.js +1 -1
  85. package/dist/editors/contributor-billing/hooks/useBillingFolderStructure.d.ts +54 -0
  86. package/dist/editors/contributor-billing/hooks/useBillingFolderStructure.d.ts.map +1 -0
  87. package/dist/editors/contributor-billing/hooks/useBillingFolderStructure.js +145 -0
  88. package/dist/editors/expense-report/components/AddBillingStatementModal.d.ts +3 -1
  89. package/dist/editors/expense-report/components/AddBillingStatementModal.d.ts.map +1 -1
  90. package/dist/editors/expense-report/components/AddBillingStatementModal.js +23 -7
  91. package/dist/editors/expense-report/components/AggregatedExpensesTable.js +2 -2
  92. package/dist/editors/expense-report/components/ExpenseReportPDF.js +2 -2
  93. package/dist/editors/expense-report/editor.d.ts.map +1 -1
  94. package/dist/editors/expense-report/editor.js +70 -14
  95. package/dist/editors/expense-report/hooks/useSyncWallet.js +9 -9
  96. package/dist/editors/invoice/ingestPDF.js +1 -1
  97. package/dist/editors/invoice/invoiceToGnosis.js +2 -2
  98. package/dist/editors/invoice/requestFinance.js +2 -2
  99. package/dist/editors/invoice/uploadPdfChunked.js +2 -2
  100. package/dist/editors/snapshot-report-editor/editor.d.ts.map +1 -1
  101. package/dist/editors/snapshot-report-editor/editor.js +26 -5
  102. package/dist/scripts/invoice/pdfToClaudeAI.d.ts.map +1 -1
  103. package/dist/scripts/invoice/pdfToClaudeAI.js +3 -1
  104. package/dist/style.css +85 -0
  105. package/dist/subgraphs/budget-statements/index.d.ts +11 -0
  106. package/dist/subgraphs/budget-statements/index.d.ts.map +1 -0
  107. package/dist/subgraphs/budget-statements/index.js +11 -0
  108. package/dist/subgraphs/budget-statements/resolvers.d.ts +3 -0
  109. package/dist/subgraphs/budget-statements/resolvers.d.ts.map +1 -0
  110. package/dist/subgraphs/budget-statements/resolvers.js +335 -0
  111. package/dist/subgraphs/budget-statements/schema.d.ts +3 -0
  112. package/dist/subgraphs/budget-statements/schema.d.ts.map +1 -0
  113. package/dist/subgraphs/budget-statements/schema.js +131 -0
  114. package/dist/subgraphs/index.d.ts +1 -0
  115. package/dist/subgraphs/index.d.ts.map +1 -1
  116. package/dist/subgraphs/index.js +1 -0
  117. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useMemo, useEffect } from "react";
3
+ import { setName } from "document-model";
3
4
  import { useSelectedExpenseReportDocument } from "../../document-models/expense-report/hooks.js";
4
5
  import { actions, } from "../../document-models/expense-report/index.js";
5
6
  import { Icon, Button, Select } from "@powerhousedao/document-engineering";
@@ -9,7 +10,7 @@ import { AddBillingStatementModal } from "./components/AddBillingStatementModal.
9
10
  import { ExpenseReportPDF } from "./components/ExpenseReportPDF.js";
10
11
  import { pdf } from "@react-pdf/renderer";
11
12
  import { DocumentToolbar } from "@powerhousedao/design-system/connect";
12
- import { setSelectedNode, useParentFolderForSelectedNode, } from "@powerhousedao/reactor-browser";
13
+ import { setSelectedNode, useParentFolderForSelectedNode, useSelectedDrive, isFolderNodeKind, } from "@powerhousedao/reactor-browser";
13
14
  import { useSyncWallet } from "./hooks/useSyncWallet.js";
14
15
  import { RefreshCw } from "lucide-react";
15
16
  import { SetOwner } from "./components/SetOwner.js";
@@ -61,8 +62,9 @@ export default function Editor() {
61
62
  // Local state for the selected period (before confirmation)
62
63
  const [selectedPeriod, setSelectedPeriod] = useState(() => {
63
64
  if (periodStart) {
65
+ // Use UTC methods to avoid timezone issues
64
66
  const date = new Date(periodStart);
65
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
67
+ return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}`;
66
68
  }
67
69
  // Default to current month
68
70
  const now = new Date();
@@ -71,8 +73,9 @@ export default function Editor() {
71
73
  // Track if the selected period differs from the saved period
72
74
  const savedPeriod = useMemo(() => {
73
75
  if (periodStart) {
76
+ // Use UTC methods to avoid timezone issues
74
77
  const date = new Date(periodStart);
75
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
78
+ return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}`;
76
79
  }
77
80
  return "";
78
81
  }, [periodStart]);
@@ -92,23 +95,45 @@ export default function Editor() {
92
95
  // Handle period confirmation (saves to document)
93
96
  const handleConfirmPeriod = () => {
94
97
  const { periodStart, periodEnd } = getMonthDateRange(selectedPeriod);
95
- // Dispatch both start and end dates
98
+ // Get the formatted month label (e.g., "January 2025") - timezone agnostic
99
+ const [year, month] = selectedPeriod.split("-").map(Number);
100
+ const monthNames = [
101
+ "January",
102
+ "February",
103
+ "March",
104
+ "April",
105
+ "May",
106
+ "June",
107
+ "July",
108
+ "August",
109
+ "September",
110
+ "October",
111
+ "November",
112
+ "December",
113
+ ];
114
+ const monthLabel = `${monthNames[month - 1]} ${year}`;
115
+ // Dispatch period dates
96
116
  dispatch(actions.setPeriodStart({ periodStart }));
97
117
  dispatch(actions.setPeriodEnd({ periodEnd }));
118
+ // Auto-set document name based on reporting period
119
+ dispatch(setName(`${monthLabel} - Expense Report`));
98
120
  // Exit editing mode
99
121
  setIsEditingPeriod(false);
100
122
  };
101
- // Handle starting to edit the period
102
- const handleEditPeriod = () => {
103
- setIsEditingPeriod(true);
104
- };
105
123
  // Generate month options
106
124
  const monthOptions = useMemo(() => generateMonthOptions(), []);
107
125
  // Get the formatted display label for the current period
108
126
  const periodDisplayLabel = useMemo(() => {
109
- const option = monthOptions.find((opt) => opt.value === selectedPeriod);
110
- return option ? option.label : selectedPeriod;
111
- }, [selectedPeriod, monthOptions]);
127
+ if (!periodStart)
128
+ return selectedPeriod;
129
+ const date = new Date(periodStart);
130
+ const monthName = date.toLocaleDateString("en-US", {
131
+ month: "long",
132
+ timeZone: "UTC",
133
+ });
134
+ const year = date.getUTCFullYear();
135
+ return `${monthName} ${year}`;
136
+ }, [periodStart, selectedPeriod]);
112
137
  // Handle wallet selection for adding billing statements
113
138
  const handleAddBillingStatement = (walletAddress) => {
114
139
  setSelectedWallet(walletAddress);
@@ -166,17 +191,48 @@ export default function Editor() {
166
191
  const year = date.getFullYear();
167
192
  return `${month} ${year} Breakdown`;
168
193
  }, [periodStart]);
169
- // Get the parent folder node for the currently selected node
194
+ // Get the parent folder node for the currently selected node (this is the Reporting folder)
170
195
  const parentFolder = useParentFolderForSelectedNode();
196
+ const [driveDocument] = useSelectedDrive();
197
+ // Find the sibling "Payments" folder dynamically
198
+ // Structure: Month Folder -> Reporting (where expense report lives) | Payments (sibling)
199
+ // We find the expense report's file node, get its parent (Reporting), then find the sibling Payments folder
200
+ const paymentsFolderId = useMemo(() => {
201
+ if (!driveDocument || !document)
202
+ return null;
203
+ const nodes = driveDocument.state.global.nodes;
204
+ const expenseReportId = document.header.id;
205
+ // Find the expense report's file node in the drive
206
+ const expenseReportFileNode = nodes.find((node) => node.id === expenseReportId);
207
+ if (!expenseReportFileNode)
208
+ return null;
209
+ // Get the Reporting folder (parent of expense report)
210
+ const reportingFolderId = expenseReportFileNode.parentFolder;
211
+ if (!reportingFolderId)
212
+ return null;
213
+ // Find the Reporting folder node to get its parent (month folder)
214
+ const reportingFolder = nodes.find((node) => isFolderNodeKind(node) && node.id === reportingFolderId);
215
+ if (!reportingFolder)
216
+ return null;
217
+ // Get the month folder (parent of Reporting)
218
+ const monthFolderId = reportingFolder.parentFolder;
219
+ if (!monthFolderId)
220
+ return null;
221
+ // Find the "Payments" sibling folder under the same month folder
222
+ const paymentsFolder = nodes.find((node) => isFolderNodeKind(node) &&
223
+ node.parentFolder === monthFolderId &&
224
+ node.name === "Payments");
225
+ return paymentsFolder?.id ?? null;
226
+ }, [driveDocument, document]);
171
227
  // Set the selected node to the parent folder node (close the editor)
172
228
  function handleClose() {
173
229
  setSelectedNode(parentFolder?.id);
174
230
  }
175
- return (_jsxs("div", { className: "flex flex-col h-full w-full overflow-hidden", children: [_jsx(DocumentToolbar, { document: document, onClose: handleClose }), _jsxs("div", { className: "ph-default-styles flex flex-col flex-1 min-h-0 w-full bg-gray-50 dark:bg-gray-900", children: [_jsx("div", { className: "flex-1 overflow-auto px-3 sm:px-4 lg:px-6 py-4", children: _jsxs("div", { className: "w-full max-w-none space-y-4 lg:space-y-6", children: [_jsx("section", { className: "bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700", children: _jsxs("div", { className: "px-4 sm:px-6 py-4 sm:py-6", children: [_jsxs("div", { className: "flex items-start justify-between gap-4 mb-4", children: [_jsx("h1", { className: "text-xl sm:text-2xl lg:text-3xl font-bold text-gray-900 dark:text-white", children: "Expense Report" }), _jsxs(Button, { variant: "ghost", onClick: handleExportPDF, className: "flex items-center gap-2 shrink-0", children: [_jsx(Icon, { name: "ExportPdf", size: 18 }), _jsx("span", { children: "Export to PDF" })] })] }), _jsxs("div", { className: "flex flex-wrap justify-between gap-12", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Period:" }), isEditingPeriod ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Select, { options: monthOptions, value: selectedPeriod, onChange: (value) => handlePeriodChange(value), className: "min-w-[180px]" }), isPeriodChanged && (_jsx(Button, { variant: "default", onClick: handleConfirmPeriod, className: "text-sm", children: "Set Period" }))] })) : (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-lg font-bold text-gray-900 dark:text-white", children: periodDisplayLabel }), _jsx(Button, { variant: "ghost", onClick: handleEditPeriod, className: "text-sm", children: "Change" })] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Status:" }), _jsx(Select, { options: [
231
+ return (_jsxs("div", { className: "flex flex-col h-full w-full overflow-hidden", children: [_jsx(DocumentToolbar, { document: document, onClose: handleClose }), _jsxs("div", { className: "ph-default-styles flex flex-col flex-1 min-h-0 w-full bg-gray-50 dark:bg-gray-900", children: [_jsx("div", { className: "flex-1 overflow-auto px-3 sm:px-4 lg:px-6 py-4", children: _jsxs("div", { className: "w-full max-w-none space-y-4 lg:space-y-6", children: [_jsx("section", { className: "bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700", children: _jsxs("div", { className: "px-4 sm:px-6 py-4 sm:py-6", children: [_jsxs("div", { className: "flex items-start justify-between gap-4 mb-4", children: [_jsx("h1", { className: "text-xl sm:text-2xl lg:text-3xl font-bold text-gray-900 dark:text-white", children: "Expense Report" }), _jsxs(Button, { variant: "ghost", onClick: handleExportPDF, className: "flex items-center gap-2 shrink-0", children: [_jsx(Icon, { name: "ExportPdf", size: 18 }), _jsx("span", { children: "Export to PDF" })] })] }), _jsxs("div", { className: "flex flex-wrap justify-between gap-12", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Period:" }), isEditingPeriod ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Select, { options: monthOptions, value: selectedPeriod, onChange: (value) => handlePeriodChange(value), className: "min-w-[180px]" }), isPeriodChanged && (_jsx(Button, { variant: "default", onClick: handleConfirmPeriod, className: "text-sm", children: "Set Period" }))] })) : (_jsx("span", { className: "text-lg font-bold text-gray-900 dark:text-white", children: periodDisplayLabel }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Status:" }), _jsx(Select, { options: [
176
232
  { label: "Draft", value: "DRAFT" },
177
233
  { label: "Review", value: "REVIEW" },
178
234
  { label: "Final", value: "FINAL" },
179
235
  ], value: document.state.global.status, onChange: (value) => dispatch(actions.setStatus({
180
236
  status: value,
181
- })), className: "min-w-[180px]" })] }), _jsx(SetOwner, { ownerId: ownerId, dispatch: dispatch })] })] }) }), _jsxs("section", { className: "bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden", children: [_jsxs("div", { className: "px-4 sm:px-6 py-3 sm:py-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between", children: [_jsx("h2", { className: "text-lg sm:text-xl font-semibold text-gray-900 dark:text-white", children: "Wallets" }), _jsxs(Button, { variant: "ghost", onClick: handleSyncAllWallets, disabled: isSyncingAll, className: "flex items-center gap-2", children: [_jsx(RefreshCw, { size: 16, className: isSyncingAll ? "animate-spin" : "" }), _jsx("span", { className: "hidden sm:inline", children: isSyncingAll ? "Syncing..." : "Sync All" })] })] }), _jsx("div", { className: "p-3 sm:p-4 lg:p-6 overflow-x-auto", children: _jsx(WalletsTable, { wallets: wallets, groups: groups, onAddBillingStatement: handleAddBillingStatement, periodStart: periodStart, periodEnd: periodEnd, dispatch: dispatch }) })] }), wallets.length > 0 && (_jsxs("section", { className: "bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden", children: [_jsx("div", { className: "px-4 sm:px-6 py-3 sm:py-4 border-b border-gray-200 dark:border-gray-700", children: _jsx("h2", { className: "text-lg sm:text-xl font-semibold text-gray-900 dark:text-white", children: breakdownTitle }) }), _jsx("div", { className: "p-3 sm:p-4 lg:p-6 overflow-x-auto", children: _jsx(AggregatedExpensesTable, { wallets: wallets, groups: groups, periodStart: periodStart, periodEnd: periodEnd, dispatch: dispatch }) })] }))] }) }), isModalOpen && selectedWallet && (_jsx(AddBillingStatementModal, { isOpen: isModalOpen, onClose: handleCloseModal, walletAddress: selectedWallet, dispatch: dispatch, groups: groups }))] })] }));
237
+ })), className: "min-w-[180px]" })] }), _jsx(SetOwner, { ownerId: ownerId, dispatch: dispatch })] })] }) }), _jsxs("section", { className: "bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden", children: [_jsxs("div", { className: "px-4 sm:px-6 py-3 sm:py-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between", children: [_jsx("h2", { className: "text-lg sm:text-xl font-semibold text-gray-900 dark:text-white", children: "Wallets" }), _jsxs(Button, { variant: "ghost", onClick: handleSyncAllWallets, disabled: isSyncingAll, className: "flex items-center gap-2", children: [_jsx(RefreshCw, { size: 16, className: isSyncingAll ? "animate-spin" : "" }), _jsx("span", { className: "hidden sm:inline", children: isSyncingAll ? "Syncing..." : "Sync All" })] })] }), _jsx("div", { className: "p-3 sm:p-4 lg:p-6 overflow-x-auto", children: _jsx(WalletsTable, { wallets: wallets, groups: groups, onAddBillingStatement: handleAddBillingStatement, periodStart: periodStart, periodEnd: periodEnd, dispatch: dispatch }) })] }), wallets.length > 0 && (_jsxs("section", { className: "bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden", children: [_jsx("div", { className: "px-4 sm:px-6 py-3 sm:py-4 border-b border-gray-200 dark:border-gray-700", children: _jsx("h2", { className: "text-lg sm:text-xl font-semibold text-gray-900 dark:text-white", children: breakdownTitle }) }), _jsx("div", { className: "p-3 sm:p-4 lg:p-6 overflow-x-auto", children: _jsx(AggregatedExpensesTable, { wallets: wallets, groups: groups, periodStart: periodStart, periodEnd: periodEnd, dispatch: dispatch }) })] }))] }) }), isModalOpen && selectedWallet && (_jsx(AddBillingStatementModal, { isOpen: isModalOpen, onClose: handleCloseModal, walletAddress: selectedWallet, dispatch: dispatch, groups: groups, paymentsFolderId: paymentsFolderId }))] })] }));
182
238
  }
@@ -71,7 +71,7 @@ export function useSyncWallet() {
71
71
  const lineItems = statement.state.global.lineItems || [];
72
72
  lineItems.forEach((billingLineItem) => {
73
73
  const groupId = mapTagToGroup(billingLineItem);
74
- const categoryKey = groupId || "uncategorized";
74
+ const categoryKey = groupId || "Uncategorized";
75
75
  const existing = categoryAggregation.get(categoryKey);
76
76
  if (existing) {
77
77
  // Aggregate values for the same category
@@ -95,16 +95,16 @@ export function useSyncWallet() {
95
95
  if (accountTransactionsDocumentId && periodStart && periodEnd) {
96
96
  const transactionPayments = calculatePaymentsFromTransactions(accountTransactionsDocumentId, periodStart, periodEnd);
97
97
  if (transactionPayments > 0) {
98
- // Add payments to "uncategorized" category
99
- const uncategorized = categoryAggregation.get("uncategorized");
100
- if (uncategorized) {
101
- // Update existing uncategorized category with payments
102
- uncategorized.payments = transactionPayments;
98
+ // Add payments to "Uncategorized" category
99
+ const Uncategorized = categoryAggregation.get("Uncategorized");
100
+ if (Uncategorized) {
101
+ // Update existing Uncategorized category with payments
102
+ Uncategorized.payments = transactionPayments;
103
103
  }
104
104
  else {
105
- // Create new uncategorized category entry with payments
106
- categoryAggregation.set("uncategorized", {
107
- groupId: null,
105
+ // Create new Uncategorized category entry with payments
106
+ categoryAggregation.set("Uncategorized", {
107
+ groupId: "121482a1-b69f-4511-g46f-267c24450238",
108
108
  groupLabel: "Uncategorized",
109
109
  budget: 0,
110
110
  actuals: 0,
@@ -7,7 +7,7 @@ import { getCountryCodeFromName, mapChainNameToConfig } from "./utils/utils.js";
7
7
  import { LoaderCircle } from "lucide-react";
8
8
  let GRAPHQL_URL = "http://localhost:4001/graphql";
9
9
  if (!window.document.baseURI.includes("localhost")) {
10
- GRAPHQL_URL = "https://switchboard.powerhouse.xyz/graphql";
10
+ GRAPHQL_URL = "https://switchboard-dev.powerhouse.xyz/graphql";
11
11
  }
12
12
  export async function loadPDFFile({ file, dispatch, }) {
13
13
  if (!file)
@@ -3,8 +3,8 @@ import React, { useState, useEffect } from "react";
3
3
  import { actions } from "../../document-models/invoice/index.js";
4
4
  import { generateId } from "document-model";
5
5
  let GRAPHQL_URL = "http://localhost:4001/graphql";
6
- if (!window.document.baseURI.includes('localhost')) {
7
- GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql';
6
+ if (!window.document.baseURI.includes("localhost")) {
7
+ GRAPHQL_URL = "https://switchboard-dev.powerhouse.xyz/graphql";
8
8
  }
9
9
  const InvoiceToGnosis = ({ docState, dispatch, }) => {
10
10
  const [isLoading, setIsLoading] = useState(false);
@@ -3,8 +3,8 @@ import React, { useState } from "react";
3
3
  import { actions } from "../../document-models/invoice/index.js";
4
4
  import { generateId } from "document-model";
5
5
  let GRAPHQL_URL = "http://localhost:4001/graphql";
6
- if (!window.document.baseURI.includes('localhost')) {
7
- GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql';
6
+ if (!window.document.baseURI.includes("localhost")) {
7
+ GRAPHQL_URL = "https://switchboard-dev.powerhouse.xyz/graphql";
8
8
  }
9
9
  const RequestFinance = ({ docState, dispatch, }) => {
10
10
  const [isLoading, setIsLoading] = useState(false);
@@ -6,8 +6,8 @@
6
6
  * @param onProgress Callback for upload progress
7
7
  */
8
8
  let GRAPHQL_URL = "http://localhost:4001/graphql";
9
- if (!window.document.baseURI.includes('localhost')) {
10
- GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql';
9
+ if (!window.document.baseURI.includes("localhost")) {
10
+ GRAPHQL_URL = "https://switchboard-dev.powerhouse.xyz/graphql";
11
11
  }
12
12
  export async function uploadPdfChunked(pdfData, endpoint = GRAPHQL_URL, chunkSize = 500 * 1024, // 500KB chunks
13
13
  onProgress) {
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/snapshot-report-editor/editor.tsx"],"names":[],"mappings":"AAyEA,MAAM,CAAC,OAAO,UAAU,MAAM,4CA8qC7B"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/snapshot-report-editor/editor.tsx"],"names":[],"mappings":"AA6EA,MAAM,CAAC,OAAO,UAAU,MAAM,4CAqsC7B"}
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { generateId } from "document-model/core";
2
+ import { generateId, setName } from "document-model";
3
3
  import { useState, useMemo, useEffect } from "react";
4
4
  import { useDocumentsInSelectedDrive, useParentFolderForSelectedNode, setSelectedNode, dispatchActions, } from "@powerhousedao/reactor-browser";
5
5
  import { DocumentToolbar } from "@powerhousedao/design-system/connect";
6
- import { Button, Select, DatePicker } from "@powerhousedao/document-engineering";
6
+ import { Button, Select, DatePicker, } from "@powerhousedao/document-engineering";
7
7
  import { ChevronDown, ChevronUp, RefreshCw } from "lucide-react";
8
8
  import { useSelectedSnapshotReportDocument } from "../hooks/useSnapshotReportDocument.js";
9
9
  import { setReportConfig, addSnapshotAccount, addTransaction, setPeriodStart, setPeriodEnd, } from "../../document-models/snapshot-report/gen/creators.js";
@@ -75,8 +75,9 @@ export default function Editor() {
75
75
  // Local state for the selected period (before confirmation)
76
76
  const [selectedPeriod, setSelectedPeriod] = useState(() => {
77
77
  if (reportPeriodStart) {
78
+ // Use UTC methods to avoid timezone issues
78
79
  const date = new Date(reportPeriodStart);
79
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
80
+ return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}`;
80
81
  }
81
82
  // Default to current month
82
83
  const now = new Date();
@@ -85,8 +86,9 @@ export default function Editor() {
85
86
  // Track if the selected period differs from the saved period
86
87
  const savedPeriod = useMemo(() => {
87
88
  if (reportPeriodStart) {
89
+ // Use UTC methods to avoid timezone issues
88
90
  const date = new Date(reportPeriodStart);
89
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
91
+ return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}`;
90
92
  }
91
93
  return "";
92
94
  }, [reportPeriodStart]);
@@ -106,9 +108,28 @@ export default function Editor() {
106
108
  // Handle period confirmation (saves to document)
107
109
  const handleConfirmPeriod = () => {
108
110
  const { periodStart, periodEnd } = getMonthDateRange(selectedPeriod);
109
- // Dispatch both start and end dates
111
+ // Get the formatted month label (e.g., "January 2025") - timezone agnostic
112
+ const [year, month] = selectedPeriod.split("-").map(Number);
113
+ const monthNames = [
114
+ "January",
115
+ "February",
116
+ "March",
117
+ "April",
118
+ "May",
119
+ "June",
120
+ "July",
121
+ "August",
122
+ "September",
123
+ "October",
124
+ "November",
125
+ "December",
126
+ ];
127
+ const monthLabel = `${monthNames[month - 1]} ${year}`;
128
+ // Dispatch period dates
110
129
  dispatch?.(setPeriodStart({ periodStart }));
111
130
  dispatch?.(setPeriodEnd({ periodEnd }));
131
+ // Auto-set document name based on reporting period
132
+ dispatch?.(setName(`${monthLabel} - Snapshot Report`));
112
133
  // Exit editing mode
113
134
  setIsEditingPeriod(false);
114
135
  };
@@ -1 +1 @@
1
- {"version":3,"file":"pdfToClaudeAI.d.ts","sourceRoot":"","sources":["../../../scripts/invoice/pdfToClaudeAI.ts"],"names":[],"mappings":"AA4LA,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,MAAM;;GAsR/D"}
1
+ {"version":3,"file":"pdfToClaudeAI.d.ts","sourceRoot":"","sources":["../../../scripts/invoice/pdfToClaudeAI.ts"],"names":[],"mappings":"AAiMA,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,MAAM;;GAsR/D"}
@@ -148,7 +148,9 @@ function truncateToLastCompleteElement(json) {
148
148
  if (lastPropStart > 0) {
149
149
  // Find the comma or opening brace before this property
150
150
  let searchFrom = lastPropStart;
151
- while (searchFrom > 0 && json[searchFrom] !== "," && json[searchFrom] !== "{") {
151
+ while (searchFrom > 0 &&
152
+ json[searchFrom] !== "," &&
153
+ json[searchFrom] !== "{") {
152
154
  searchFrom--;
153
155
  }
154
156
  if (json[searchFrom] === ",") {
package/dist/style.css CHANGED
@@ -83,10 +83,13 @@
83
83
  --color-violet-50: oklch(96.9% 0.016 293.756);
84
84
  --color-violet-500: oklch(60.6% 0.25 292.717);
85
85
  --color-violet-600: oklch(54.1% 0.281 293.009);
86
+ --color-purple-50: oklch(97.7% 0.014 308.299);
86
87
  --color-purple-100: hsl(262 79% 93%);
87
88
  --color-purple-200: hsl(263 79% 89%);
88
89
  --color-purple-300: hsl(263 79% 85%);
89
90
  --color-purple-500: hsl(264 77% 77%);
91
+ --color-purple-600: hsl(263 76% 74%);
92
+ --color-purple-700: hsl(263 78% 70%);
90
93
  --color-purple-800: hsl(263 78% 66%);
91
94
  --color-purple-900: hsl(263 78% 63%);
92
95
  --color-pink-500: oklch(65.6% 0.241 354.308);
@@ -346,6 +349,9 @@
346
349
  .-top-20 {
347
350
  top: calc(var(--spacing) * -20);
348
351
  }
352
+ .top-full {
353
+ top: 100%;
354
+ }
349
355
  .-right-20 {
350
356
  right: calc(var(--spacing) * -20);
351
357
  }
@@ -364,6 +370,9 @@
364
370
  .-left-16 {
365
371
  left: calc(var(--spacing) * -16);
366
372
  }
373
+ .left-0 {
374
+ left: calc(var(--spacing) * 0);
375
+ }
367
376
  .z-10 {
368
377
  z-index: 10;
369
378
  }
@@ -454,6 +463,9 @@
454
463
  .mb-4 {
455
464
  margin-bottom: calc(var(--spacing) * 4);
456
465
  }
466
+ .mb-5 {
467
+ margin-bottom: calc(var(--spacing) * 5);
468
+ }
457
469
  .mb-6 {
458
470
  margin-bottom: calc(var(--spacing) * 6);
459
471
  }
@@ -472,6 +484,9 @@
472
484
  .ml-4 {
473
485
  margin-left: calc(var(--spacing) * 4);
474
486
  }
487
+ .ml-auto {
488
+ margin-left: auto;
489
+ }
475
490
  .block {
476
491
  display: block;
477
492
  }
@@ -572,6 +587,12 @@
572
587
  .max-h-32 {
573
588
  max-height: calc(var(--spacing) * 32);
574
589
  }
590
+ .max-h-60 {
591
+ max-height: calc(var(--spacing) * 60);
592
+ }
593
+ .max-h-72 {
594
+ max-height: calc(var(--spacing) * 72);
595
+ }
575
596
  .max-h-\[80vh\] {
576
597
  max-height: 80vh;
577
598
  }
@@ -653,6 +674,9 @@
653
674
  .w-50 {
654
675
  width: calc(var(--spacing) * 50);
655
676
  }
677
+ .w-56 {
678
+ width: calc(var(--spacing) * 56);
679
+ }
656
680
  .w-64 {
657
681
  width: calc(var(--spacing) * 64);
658
682
  }
@@ -1306,6 +1330,9 @@
1306
1330
  .bg-orange-100 {
1307
1331
  background-color: var(--color-orange-100);
1308
1332
  }
1333
+ .bg-purple-50 {
1334
+ background-color: var(--color-purple-50);
1335
+ }
1309
1336
  .bg-purple-100 {
1310
1337
  background-color: var(--color-purple-100);
1311
1338
  }
@@ -1371,6 +1398,10 @@
1371
1398
  --tw-gradient-position: to right in oklab;
1372
1399
  background-image: linear-gradient(var(--tw-gradient-stops));
1373
1400
  }
1401
+ .from-blue-50 {
1402
+ --tw-gradient-from: var(--color-blue-50);
1403
+ --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
1404
+ }
1374
1405
  .from-blue-400\/20 {
1375
1406
  --tw-gradient-from: color-mix(in srgb, hsl(209 100% 75%) 20%, transparent);
1376
1407
  @supports (color: color-mix(in lab, red, red)) {
@@ -1436,6 +1467,10 @@
1436
1467
  --tw-gradient-to: var(--color-blue-600);
1437
1468
  --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
1438
1469
  }
1470
+ .to-indigo-50 {
1471
+ --tw-gradient-to: var(--color-indigo-50);
1472
+ --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
1473
+ }
1439
1474
  .to-indigo-50\/40 {
1440
1475
  --tw-gradient-to: color-mix(in srgb, oklch(96.2% 0.018 272.314) 40%, transparent);
1441
1476
  @supports (color: color-mix(in lab, red, red)) {
@@ -1735,6 +1770,9 @@
1735
1770
  .text-amber-600 {
1736
1771
  color: var(--color-amber-600);
1737
1772
  }
1773
+ .text-amber-700 {
1774
+ color: var(--color-amber-700);
1775
+ }
1738
1776
  .text-amber-800 {
1739
1777
  color: var(--color-amber-800);
1740
1778
  }
@@ -1804,6 +1842,9 @@
1804
1842
  .text-gray-100 {
1805
1843
  color: var(--color-gray-100);
1806
1844
  }
1845
+ .text-gray-300 {
1846
+ color: var(--color-gray-300);
1847
+ }
1807
1848
  .text-gray-400 {
1808
1849
  color: var(--color-gray-400);
1809
1850
  }
@@ -1855,6 +1896,12 @@
1855
1896
  .text-orange-800 {
1856
1897
  color: var(--color-orange-800);
1857
1898
  }
1899
+ .text-purple-600 {
1900
+ color: var(--color-purple-600);
1901
+ }
1902
+ .text-purple-700 {
1903
+ color: var(--color-purple-700);
1904
+ }
1858
1905
  .text-purple-800 {
1859
1906
  color: var(--color-purple-800);
1860
1907
  }
@@ -1922,6 +1969,9 @@
1922
1969
  --tw-numeric-spacing: tabular-nums;
1923
1970
  font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
1924
1971
  }
1972
+ .line-through {
1973
+ text-decoration-line: line-through;
1974
+ }
1925
1975
  .underline {
1926
1976
  text-decoration-line: underline;
1927
1977
  }
@@ -2173,6 +2223,13 @@
2173
2223
  }
2174
2224
  }
2175
2225
  }
2226
+ .group-hover\:text-blue-500 {
2227
+ &:is(:where(.group):hover *) {
2228
+ @media (hover: hover) {
2229
+ color: var(--color-blue-500);
2230
+ }
2231
+ }
2232
+ }
2176
2233
  .group-hover\:text-indigo-500 {
2177
2234
  &:is(:where(.group):hover *) {
2178
2235
  @media (hover: hover) {
@@ -2240,6 +2297,20 @@
2240
2297
  }
2241
2298
  }
2242
2299
  }
2300
+ .hover\:border-blue-200 {
2301
+ &:hover {
2302
+ @media (hover: hover) {
2303
+ border-color: var(--color-blue-200);
2304
+ }
2305
+ }
2306
+ }
2307
+ .hover\:border-blue-300 {
2308
+ &:hover {
2309
+ @media (hover: hover) {
2310
+ border-color: var(--color-blue-300);
2311
+ }
2312
+ }
2313
+ }
2243
2314
  .hover\:border-gray-300 {
2244
2315
  &:hover {
2245
2316
  @media (hover: hover) {
@@ -2254,6 +2325,13 @@
2254
2325
  }
2255
2326
  }
2256
2327
  }
2328
+ .hover\:border-purple-300 {
2329
+ &:hover {
2330
+ @media (hover: hover) {
2331
+ border-color: var(--color-purple-300);
2332
+ }
2333
+ }
2334
+ }
2257
2335
  .hover\:bg-\[\#1b1d26\] {
2258
2336
  &:hover {
2259
2337
  @media (hover: hover) {
@@ -2418,6 +2496,13 @@
2418
2496
  }
2419
2497
  }
2420
2498
  }
2499
+ .hover\:bg-purple-50 {
2500
+ &:hover {
2501
+ @media (hover: hover) {
2502
+ background-color: var(--color-purple-50);
2503
+ }
2504
+ }
2505
+ }
2421
2506
  .hover\:bg-red-50 {
2422
2507
  &:hover {
2423
2508
  @media (hover: hover) {
@@ -0,0 +1,11 @@
1
+ import { BaseSubgraph } from "@powerhousedao/reactor-api";
2
+ import type { DocumentNode } from "graphql";
3
+ export declare class BudgetStatementsSubgraph extends BaseSubgraph {
4
+ name: string;
5
+ typeDefs: DocumentNode;
6
+ resolvers: Record<string, unknown>;
7
+ additionalContextFields: {};
8
+ onSetup(): Promise<void>;
9
+ onDisconnect(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../subgraphs/budget-statements/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5C,qBAAa,wBAAyB,SAAQ,YAAY;IACxD,IAAI,SAAuB;IAC3B,QAAQ,EAAE,YAAY,CAAU;IAChC,SAAS,0BAAsB;IAC/B,uBAAuB,KAAM;IACvB,OAAO;IACP,YAAY;CACnB"}
@@ -0,0 +1,11 @@
1
+ import { BaseSubgraph } from "@powerhousedao/reactor-api";
2
+ import { schema } from "./schema.js";
3
+ import { getResolvers } from "./resolvers.js";
4
+ export class BudgetStatementsSubgraph extends BaseSubgraph {
5
+ name = "budget-statements";
6
+ typeDefs = schema;
7
+ resolvers = getResolvers(this);
8
+ additionalContextFields = {};
9
+ async onSetup() { }
10
+ async onDisconnect() { }
11
+ }
@@ -0,0 +1,3 @@
1
+ import { type ISubgraph } from "@powerhousedao/reactor-api";
2
+ export declare const getResolvers: (subgraph: ISubgraph) => Record<string, unknown>;
3
+ //# sourceMappingURL=resolvers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../subgraphs/budget-statements/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AA0E5D,eAAO,MAAM,YAAY,GAAI,UAAU,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CA+LxE,CAAC"}