@powerhousedao/contributor-billing 0.1.53 → 1.0.0-dev.10

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 (189) hide show
  1. package/dist/document-models/account-transactions/gen/schema/zod.d.ts.map +1 -1
  2. package/dist/document-models/account-transactions/gen/schema/zod.js +3 -3
  3. package/dist/document-models/account-transactions/module.d.ts +1 -1
  4. package/dist/document-models/account-transactions/module.d.ts.map +1 -1
  5. package/dist/document-models/account-transactions/module.js +1 -1
  6. package/dist/document-models/accounts/gen/schema/zod.d.ts.map +1 -1
  7. package/dist/document-models/accounts/module.d.ts +1 -1
  8. package/dist/document-models/accounts/module.d.ts.map +1 -1
  9. package/dist/document-models/accounts/module.js +1 -1
  10. package/dist/document-models/billing-statement/gen/schema/zod.d.ts.map +1 -1
  11. package/dist/document-models/billing-statement/gen/schema/zod.js +4 -4
  12. package/dist/document-models/billing-statement/module.d.ts +1 -1
  13. package/dist/document-models/billing-statement/module.d.ts.map +1 -1
  14. package/dist/document-models/billing-statement/module.js +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 +38 -18
  17. package/dist/document-models/expense-report/module.d.ts +1 -1
  18. package/dist/document-models/expense-report/module.d.ts.map +1 -1
  19. package/dist/document-models/expense-report/module.js +1 -1
  20. package/dist/document-models/invoice/gen/document-model.d.ts.map +1 -1
  21. package/dist/document-models/invoice/gen/document-model.js +150 -150
  22. package/dist/document-models/invoice/gen/schema/types.d.ts +3 -6
  23. package/dist/document-models/invoice/gen/schema/types.d.ts.map +1 -1
  24. package/dist/document-models/invoice/gen/schema/zod.d.ts +2 -8
  25. package/dist/document-models/invoice/gen/schema/zod.d.ts.map +1 -1
  26. package/dist/document-models/invoice/gen/schema/zod.js +14 -25
  27. package/dist/document-models/invoice/module.d.ts +1 -1
  28. package/dist/document-models/invoice/module.d.ts.map +1 -1
  29. package/dist/document-models/invoice/module.js +1 -1
  30. package/dist/document-models/invoice/src/reducers/general.d.ts.map +1 -1
  31. package/dist/document-models/invoice/src/reducers/general.js +8 -0
  32. package/dist/document-models/invoice/src/reducers/items.d.ts.map +1 -1
  33. package/dist/document-models/invoice/src/reducers/items.js +2 -1
  34. package/dist/document-models/invoice/src/reducers/parties.d.ts.map +1 -1
  35. package/dist/document-models/invoice/src/reducers/parties.js +6 -2
  36. package/dist/document-models/invoice/src/reducers/transitions.d.ts +0 -5
  37. package/dist/document-models/invoice/src/reducers/transitions.d.ts.map +1 -1
  38. package/dist/document-models/invoice/src/reducers/transitions.js +19 -6
  39. package/dist/document-models/invoice/tests/general.test.js +11 -2
  40. package/dist/document-models/invoice/tests/items.test.js +1 -1
  41. package/dist/document-models/invoice/tests/parties.test.js +1 -1
  42. package/dist/document-models/invoice/tests/transitions.test.js +7 -2
  43. package/dist/document-models/operational-hub-profile/module.d.ts +1 -1
  44. package/dist/document-models/operational-hub-profile/module.d.ts.map +1 -1
  45. package/dist/document-models/operational-hub-profile/module.js +1 -1
  46. package/dist/document-models/snapshot-report/gen/schema/zod.d.ts.map +1 -1
  47. package/dist/document-models/snapshot-report/gen/schema/zod.js +12 -12
  48. package/dist/document-models/snapshot-report/module.d.ts +1 -1
  49. package/dist/document-models/snapshot-report/module.d.ts.map +1 -1
  50. package/dist/document-models/snapshot-report/module.js +1 -1
  51. package/dist/editors/accounts-editor/editor.d.ts.map +1 -1
  52. package/dist/editors/accounts-editor/editor.js +2 -2
  53. package/dist/editors/builder-team-admin/components/DriveExplorer.d.ts.map +1 -1
  54. package/dist/editors/builder-team-admin/components/DriveExplorer.js +64 -4
  55. package/dist/editors/builder-team-admin/module.js +1 -1
  56. package/dist/editors/contributor-billing/components/DashboardHome.d.ts.map +1 -1
  57. package/dist/editors/contributor-billing/components/DashboardHome.js +2 -8
  58. package/dist/editors/contributor-billing/components/DocumentDropZone.d.ts.map +1 -1
  59. package/dist/editors/contributor-billing/components/DocumentDropZone.js +37 -8
  60. package/dist/editors/contributor-billing/components/DriveContents.d.ts.map +1 -1
  61. package/dist/editors/contributor-billing/components/DriveContents.js +4 -1
  62. package/dist/editors/contributor-billing/components/DriveExplorer.d.ts.map +1 -1
  63. package/dist/editors/contributor-billing/components/DriveExplorer.js +54 -3
  64. package/dist/editors/contributor-billing/components/FolderTree.d.ts.map +1 -1
  65. package/dist/editors/contributor-billing/components/FolderTree.js +6 -15
  66. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.d.ts +2 -1
  67. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.d.ts.map +1 -1
  68. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.js +41 -6
  69. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts +1 -1
  70. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts.map +1 -1
  71. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.js +16 -1
  72. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.d.ts +3 -1
  73. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.d.ts.map +1 -1
  74. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.js +13 -11
  75. package/dist/editors/contributor-billing/components/MonthReportCard.d.ts +11 -4
  76. package/dist/editors/contributor-billing/components/MonthReportCard.d.ts.map +1 -1
  77. package/dist/editors/contributor-billing/components/MonthReportCard.js +55 -6
  78. package/dist/editors/contributor-billing/components/MonthlyReportsOverview.d.ts +1 -1
  79. package/dist/editors/contributor-billing/components/MonthlyReportsOverview.d.ts.map +1 -1
  80. package/dist/editors/contributor-billing/components/MonthlyReportsOverview.js +104 -7
  81. package/dist/editors/contributor-billing/components/ReportingView.d.ts +0 -3
  82. package/dist/editors/contributor-billing/components/ReportingView.d.ts.map +1 -1
  83. package/dist/editors/contributor-billing/components/ReportingView.js +65 -8
  84. package/dist/editors/contributor-billing/components/ToastRenderer.d.ts +2 -0
  85. package/dist/editors/contributor-billing/components/ToastRenderer.d.ts.map +1 -0
  86. package/dist/editors/contributor-billing/components/ToastRenderer.js +14 -0
  87. package/dist/editors/contributor-billing/components/cbToast.d.ts +16 -0
  88. package/dist/editors/contributor-billing/components/cbToast.d.ts.map +1 -0
  89. package/dist/editors/contributor-billing/components/cbToast.js +29 -0
  90. package/dist/editors/contributor-billing/hooks/useDocumentAutoPlacement.d.ts.map +1 -1
  91. package/dist/editors/contributor-billing/hooks/useDocumentAutoPlacement.js +42 -2
  92. package/dist/editors/contributor-billing/hooks/useMonthlyReports.d.ts +4 -0
  93. package/dist/editors/contributor-billing/hooks/useMonthlyReports.d.ts.map +1 -1
  94. package/dist/editors/contributor-billing/hooks/useMonthlyReports.js +4 -0
  95. package/dist/editors/contributor-billing/module.js +1 -1
  96. package/dist/editors/invoice/InvoicePDF.d.ts.map +1 -1
  97. package/dist/editors/invoice/InvoicePDF.js +12 -9
  98. package/dist/editors/invoice/editor.d.ts.map +1 -1
  99. package/dist/editors/invoice/editor.js +6 -10
  100. package/dist/editors/invoice/exportUBL.d.ts.map +1 -1
  101. package/dist/editors/invoice/exportUBL.js +1 -2
  102. package/dist/editors/invoice/ingestPDF.js +1 -1
  103. package/dist/editors/invoice/invoiceToGnosis.d.ts.map +1 -1
  104. package/dist/editors/invoice/invoiceToGnosis.js +25 -22
  105. package/dist/editors/invoice/invoiceToast.d.ts +4 -0
  106. package/dist/editors/invoice/invoiceToast.d.ts.map +1 -0
  107. package/dist/editors/invoice/invoiceToast.js +6 -0
  108. package/dist/editors/invoice/legalEntity/legalEntity.d.ts +2 -1
  109. package/dist/editors/invoice/legalEntity/legalEntity.d.ts.map +1 -1
  110. package/dist/editors/invoice/legalEntity/legalEntity.js +3 -14
  111. package/dist/editors/invoice/legalEntity/walletSection.d.ts +1 -0
  112. package/dist/editors/invoice/legalEntity/walletSection.d.ts.map +1 -1
  113. package/dist/editors/invoice/legalEntity/walletSection.js +2 -2
  114. package/dist/editors/invoice/lineItems.js +1 -1
  115. package/dist/editors/invoice/requestFinance.d.ts +3 -2
  116. package/dist/editors/invoice/requestFinance.d.ts.map +1 -1
  117. package/dist/editors/invoice/requestFinance.js +38 -42
  118. package/dist/editors/invoice/validation/validationHandler.d.ts +1 -1
  119. package/dist/editors/invoice/validation/validationHandler.d.ts.map +1 -1
  120. package/dist/editors/invoice/validation/validationHandler.js +15 -2
  121. package/dist/editors/invoice/validation/validationManager.d.ts +1 -1
  122. package/dist/editors/invoice/validation/validationManager.d.ts.map +1 -1
  123. package/dist/editors/invoice/validation/validationManager.js +2 -1
  124. package/dist/editors/invoice/validation/validationRules.d.ts +1 -0
  125. package/dist/editors/invoice/validation/validationRules.d.ts.map +1 -1
  126. package/dist/editors/invoice/validation/validationRules.js +26 -1
  127. package/dist/editors/snapshot-report-editor/components/DateRangePicker.d.ts +19 -0
  128. package/dist/editors/snapshot-report-editor/components/DateRangePicker.d.ts.map +1 -0
  129. package/dist/editors/snapshot-report-editor/components/DateRangePicker.js +66 -0
  130. package/dist/editors/snapshot-report-editor/editor.d.ts.map +1 -1
  131. package/dist/editors/snapshot-report-editor/editor.js +72 -48
  132. package/dist/scripts/download-all-drive-documents/download-drive-documents.d.ts +33 -0
  133. package/dist/scripts/download-all-drive-documents/download-drive-documents.d.ts.map +1 -0
  134. package/dist/scripts/download-all-drive-documents/download-drive-documents.js +583 -0
  135. package/dist/scripts/invoice/requestFinance.d.ts +18 -1
  136. package/dist/scripts/invoice/requestFinance.d.ts.map +1 -1
  137. package/dist/scripts/invoice/requestFinance.js +17 -5
  138. package/dist/scripts/upload-phd-documents/upload-phd-documents.d.ts +20 -0
  139. package/dist/scripts/upload-phd-documents/upload-phd-documents.d.ts.map +1 -0
  140. package/dist/scripts/upload-phd-documents/upload-phd-documents.js +313 -0
  141. package/dist/style.css +201 -106
  142. package/dist/subgraphs/budget-statements/resolvers.d.ts +38 -0
  143. package/dist/subgraphs/budget-statements/resolvers.d.ts.map +1 -1
  144. package/dist/subgraphs/budget-statements/resolvers.js +192 -62
  145. package/dist/subgraphs/budget-statements/resolvers.test.d.ts +2 -0
  146. package/dist/subgraphs/budget-statements/resolvers.test.d.ts.map +1 -0
  147. package/dist/subgraphs/budget-statements/resolvers.test.js +339 -0
  148. package/dist/subgraphs/budget-statements/schema.d.ts.map +1 -1
  149. package/dist/subgraphs/budget-statements/schema.js +8 -0
  150. package/dist/subgraphs/index.d.ts +0 -1
  151. package/dist/subgraphs/index.d.ts.map +1 -1
  152. package/dist/subgraphs/index.js +0 -1
  153. package/dist/subgraphs/invoice-addon/customResolvers.d.ts +70 -11
  154. package/dist/subgraphs/invoice-addon/customResolvers.d.ts.map +1 -1
  155. package/dist/subgraphs/invoice-addon/customResolvers.js +12 -27
  156. package/package.json +35 -28
  157. package/dist/document-models/invoice/src/tests/document-model.test.d.ts +0 -10
  158. package/dist/document-models/invoice/src/tests/document-model.test.d.ts.map +0 -1
  159. package/dist/document-models/invoice/src/tests/document-model.test.js +0 -104
  160. package/dist/document-models/invoice/src/tests/general.test.d.ts +0 -6
  161. package/dist/document-models/invoice/src/tests/general.test.d.ts.map +0 -1
  162. package/dist/document-models/invoice/src/tests/general.test.js +0 -49
  163. package/dist/document-models/invoice/src/tests/items.test.d.ts +0 -6
  164. package/dist/document-models/invoice/src/tests/items.test.d.ts.map +0 -1
  165. package/dist/document-models/invoice/src/tests/items.test.js +0 -59
  166. package/dist/document-models/invoice/src/tests/parties.test.d.ts +0 -6
  167. package/dist/document-models/invoice/src/tests/parties.test.d.ts.map +0 -1
  168. package/dist/document-models/invoice/src/tests/parties.test.js +0 -69
  169. package/dist/document-models/invoice/src/tests/transitions.test.d.ts +0 -6
  170. package/dist/document-models/invoice/src/tests/transitions.test.d.ts.map +0 -1
  171. package/dist/document-models/invoice/src/tests/transitions.test.js +0 -59
  172. package/dist/document-models/invoice/utils/statusTransitions.d.ts +0 -13
  173. package/dist/document-models/invoice/utils/statusTransitions.d.ts.map +0 -1
  174. package/dist/document-models/invoice/utils/statusTransitions.js +0 -13
  175. package/dist/editors/builder-team-admin/components/overview/SubscriptionsStats.d.ts +0 -15
  176. package/dist/editors/builder-team-admin/components/overview/SubscriptionsStats.d.ts.map +0 -1
  177. package/dist/editors/builder-team-admin/components/overview/SubscriptionsStats.js +0 -61
  178. package/dist/editors/contributor-billing/components/CreateHubProfileModal.d.ts +0 -12
  179. package/dist/editors/contributor-billing/components/CreateHubProfileModal.d.ts.map +0 -1
  180. package/dist/editors/contributor-billing/components/CreateHubProfileModal.js +0 -74
  181. package/dist/subgraphs/resources-services/index.d.ts +0 -11
  182. package/dist/subgraphs/resources-services/index.d.ts.map +0 -1
  183. package/dist/subgraphs/resources-services/index.js +0 -11
  184. package/dist/subgraphs/resources-services/resolvers.d.ts +0 -3
  185. package/dist/subgraphs/resources-services/resolvers.d.ts.map +0 -1
  186. package/dist/subgraphs/resources-services/resolvers.js +0 -462
  187. package/dist/subgraphs/resources-services/schema.d.ts +0 -3
  188. package/dist/subgraphs/resources-services/schema.d.ts.map +0 -1
  189. package/dist/subgraphs/resources-services/schema.js +0 -284
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useMemo, useState } from "react";
3
3
  import { addDocument, dispatchActions, setSelectedNode, useSelectedDrive, useDocumentsInSelectedDrive, } from "@powerhousedao/reactor-browser";
4
+ import { deleteNode } from "document-drive";
4
5
  import { actions as invoiceActions } from "../../../../document-models/invoice/index.js";
5
6
  import { actions as billingStatementActions } from "../../../../document-models/billing-statement/index.js";
6
7
  import { setPeriodStart, setPeriodEnd, } from "../../../../document-models/expense-report/gen/creators.js";
@@ -406,6 +407,20 @@ export const InvoiceTable = ({ files, selected, setSelected, filteredDocumentMod
406
407
  });
407
408
  }
408
409
  };
410
+ // Delete selected documents from the drive
411
+ const handleDeleteSelected = async (ids) => {
412
+ const driveId = selectedDrive?.header.id;
413
+ if (!driveId)
414
+ return;
415
+ for (const id of ids) {
416
+ try {
417
+ await dispatchActions(deleteNode({ id }), driveId);
418
+ }
419
+ catch (error) {
420
+ console.error(`Failed to delete document ${id}:`, error);
421
+ }
422
+ }
423
+ };
409
424
  // Check for integrations document - simple computed value
410
425
  const integrationsDoc = files.find((file) => file.documentType === "powerhouse/integrations");
411
426
  // Create integrations document - simple async function
@@ -490,7 +505,7 @@ export const InvoiceTable = ({ files, selected, setSelected, filteredDocumentMod
490
505
  const { showIssuer = true, showBillingStatement = false, showCreateButton = false, } = options || {};
491
506
  return (_jsx(InvoiceTableSection, { title: title, count: data.length, color: statusColors[status] || statusColors.OTHER, onSelectDocumentModel: showCreateButton ? onSelectDocumentModel : undefined, filteredDocumentModels: showCreateButton ? filteredDocumentModels : undefined, children: _jsxs("table", { className: "w-full text-sm rounded-sm border-separate border-spacing-0 border border-gray-300 overflow-hidden", children: [_jsx(TableHeader, { showIssuer: showIssuer, showBillingStatement: showBillingStatement }), _jsx("tbody", { children: data.map((row) => (_jsx(InvoiceTableRow, { files: files, row: row, isSelected: !!selected[row.id], onSelect: (checked) => onRowSelection(row.id, checked, row.status), onCreateBillingStatement: handleCreateBillingStatement, billingDocStates: billingDocStates, showIssuerColumn: showIssuer, showBillingStatementColumn: showBillingStatement }, row.id))) })] }) }));
492
507
  };
493
- return (_jsxs(_Fragment, { children: [_jsx(NotificationDialog, { show: notification.show, type: notification.type, title: notification.title, message: notification.message, details: notification.details, onClose: () => setNotification({ ...notification, show: false }) }), _jsxs("div", { className: "contributor-billing-table w-full h-full bg-white rounded-lg p-4 border border-gray-200 shadow-sm mt-4 overflow-x-auto", children: [_jsx(HeaderControls, { statusOptions: statusOptions, selectedStatuses: selectedStatuses, onStatusChange: onStatusChange, onExport: handleCSVExport, onExpenseReportExport: handleExpenseReportExport, createIntegrationsDocument: createIntegrationsDocument, integrationsDoc: integrationsDoc, hasBillingStatements: hasBillingStatements, expenseReportDoc: expenseReportDoc, onCreateOrOpenExpenseReport: handleCreateExpenseReport, selected: selected, handleCreateBillingStatement: handleCreateBillingStatement, setSelected: setSelected, invoices: invoicesDocs, billingStatements: billingStatementDocs, canExportSelectedRows: canExportSelectedRows }), renderSection("DRAFT", "Draft", draft, {
508
+ return (_jsxs(_Fragment, { children: [_jsx(NotificationDialog, { show: notification.show, type: notification.type, title: notification.title, message: notification.message, details: notification.details, onClose: () => setNotification({ ...notification, show: false }) }), _jsxs("div", { className: "contributor-billing-table w-full h-full bg-white rounded-lg p-4 border border-gray-200 shadow-sm mt-4 overflow-x-auto", children: [_jsx(HeaderControls, { statusOptions: statusOptions, selectedStatuses: selectedStatuses, onStatusChange: onStatusChange, onExport: handleCSVExport, onExpenseReportExport: handleExpenseReportExport, createIntegrationsDocument: createIntegrationsDocument, integrationsDoc: integrationsDoc, hasBillingStatements: hasBillingStatements, expenseReportDoc: expenseReportDoc, onCreateOrOpenExpenseReport: handleCreateExpenseReport, selected: selected, handleCreateBillingStatement: handleCreateBillingStatement, setSelected: setSelected, invoices: invoicesDocs, billingStatements: billingStatementDocs, canExportSelectedRows: canExportSelectedRows, onDeleteSelected: handleDeleteSelected }), renderSection("DRAFT", "Draft", draft, {
494
509
  showIssuer: false,
495
510
  showCreateButton: true,
496
511
  }), renderSection("ISSUED", "Issued", issued, {
@@ -5,11 +5,13 @@ interface InvoiceTableContainerProps {
5
5
  monthName?: string;
6
6
  /** The sibling Reporting folder ID where expense reports should be created */
7
7
  reportingFolderId?: string;
8
+ /** Content rendered above the InvoiceTable but inside the drop zone */
9
+ children?: React.ReactNode;
8
10
  }
9
11
  /**
10
12
  * Container that renders the InvoiceTable.
11
13
  * Uses useNodesInSelectedDriveOrFolder pattern to avoid freeze issues.
12
14
  */
13
- export declare function InvoiceTableContainer({ folderId, monthName, reportingFolderId, }: InvoiceTableContainerProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare function InvoiceTableContainer({ folderId, monthName, reportingFolderId, children, }: InvoiceTableContainerProps): import("react/jsx-runtime").JSX.Element;
14
16
  export {};
15
17
  //# sourceMappingURL=InvoiceTableContainer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InvoiceTableContainer.d.ts","sourceRoot":"","sources":["../../../../../editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.tsx"],"names":[],"mappings":"AAmBA,UAAU,0BAA0B;IAClC,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,EAAE,0BAA0B,2CAiT5B"}
1
+ {"version":3,"file":"InvoiceTableContainer.d.ts","sourceRoot":"","sources":["../../../../../editors/contributor-billing/components/InvoiceTable/InvoiceTableContainer.tsx"],"names":[],"mappings":"AAmBA,UAAU,0BAA0B;IAClC,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,QAAQ,GACT,EAAE,0BAA0B,2CAoT5B"}
@@ -1,14 +1,14 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useCallback, useRef, useMemo, useEffect } from "react";
3
3
  import { isFileNodeKind, useDocumentModelModules, useDocumentsInSelectedDrive, useSelectedDrive, useOnDropFile, dispatchActions, addDocument, setSelectedNode, } from "@powerhousedao/reactor-browser";
4
- import { toast } from "@powerhousedao/design-system/connect";
5
4
  import { moveNode } from "document-drive";
5
+ import { cbToast } from "../cbToast.js";
6
6
  import { InvoiceTable } from "./InvoiceTable.js";
7
7
  /**
8
8
  * Container that renders the InvoiceTable.
9
9
  * Uses useNodesInSelectedDriveOrFolder pattern to avoid freeze issues.
10
10
  */
11
- export function InvoiceTableContainer({ folderId, monthName, reportingFolderId, }) {
11
+ export function InvoiceTableContainer({ folderId, monthName, reportingFolderId, children, }) {
12
12
  const [selected, setSelected] = useState({});
13
13
  const [selectedStatuses, setSelectedStatuses] = useState([]);
14
14
  const containerRef = useRef(null);
@@ -92,7 +92,7 @@ export function InvoiceTableContainer({ folderId, monthName, reportingFolderId,
92
92
  // Show error for rejected files
93
93
  if (rejectedFiles.length > 0) {
94
94
  const rejectedNames = rejectedFiles.map((f) => f.name).join(", ");
95
- toast(`Only .phd files (Powerhouse documents) can be dropped here. Rejected: ${rejectedNames}`, { type: "error" });
95
+ cbToast(`Only .phd files (Powerhouse documents) can be dropped here. Rejected: ${rejectedNames}`, { type: "error" });
96
96
  }
97
97
  if (phdFiles.length === 0)
98
98
  return;
@@ -149,14 +149,16 @@ export function InvoiceTableContainer({ folderId, monthName, reportingFolderId,
149
149
  });
150
150
  await Promise.allSettled(filePromises);
151
151
  }, [onDropFile, driveId, folderId]);
152
+ // Don't stopPropagation on dragOver/dragEnter — these must bubble to
153
+ // DocumentDropZone so it can show the full-screen overlay.
154
+ // Only handleDrop uses stopPropagation to prevent DocumentDropZone
155
+ // from also processing the files.
152
156
  const handleDragOver = useCallback((event) => {
153
157
  event.preventDefault();
154
- event.stopPropagation();
155
158
  event.dataTransfer.dropEffect = "copy";
156
159
  }, []);
157
160
  const handleDragEnter = useCallback((event) => {
158
161
  event.preventDefault();
159
- event.stopPropagation();
160
162
  }, []);
161
163
  // Handler for status filter changes
162
164
  const handleStatusChange = useCallback((value) => {
@@ -176,7 +178,7 @@ export function InvoiceTableContainer({ folderId, monthName, reportingFolderId,
176
178
  // Handle document model selection - create invoice directly in the payments folder
177
179
  const onSelectDocumentModel = useCallback(async (documentModel, name) => {
178
180
  if (!driveId) {
179
- toast("No drive selected", { type: "error" });
181
+ cbToast("No drive selected", { type: "error" });
180
182
  return;
181
183
  }
182
184
  try {
@@ -189,15 +191,15 @@ export function InvoiceTableContainer({ folderId, monthName, reportingFolderId,
189
191
  setTimeout(() => {
190
192
  setSelectedNode(createdNode.id);
191
193
  }, 100);
192
- toast("Invoice created successfully", { type: "success" });
194
+ cbToast("Invoice created successfully", { type: "success" });
193
195
  }
194
196
  else {
195
- toast("Failed to create invoice", { type: "error" });
197
+ cbToast("Failed to create invoice", { type: "error" });
196
198
  }
197
199
  }
198
200
  catch (error) {
199
201
  console.error("Error creating invoice:", error);
200
- toast("Failed to create invoice", { type: "error" });
202
+ cbToast("Failed to create invoice", { type: "error" });
201
203
  }
202
204
  }, [driveId, folderId]);
203
205
  // Determine if CSV export should be enabled based on selected rows
@@ -220,5 +222,5 @@ export function InvoiceTableContainer({ folderId, monthName, reportingFolderId,
220
222
  return selectedRows.every((row) => allowedStatuses.includes(row.state.global
221
223
  .status));
222
224
  }, [selected, allDocuments]);
223
- return (_jsx("div", { ref: containerRef, className: "w-full h-full", onDrop: handleDrop, onDragOver: handleDragOver, onDragEnter: handleDragEnter, children: _jsx(InvoiceTable, { files: fileNodes, selected: selected, setSelected: setSelected, filteredDocumentModels: documentModelModules || [], onSelectDocumentModel: onSelectDocumentModel, getDocDispatcher: getDocDispatcher, selectedStatuses: selectedStatuses, onStatusChange: handleStatusChange, onRowSelection: handleRowSelection, canExportSelectedRows: canExportSelectedRows, monthName: monthName, reportingFolderId: reportingFolderId }) }));
225
+ return (_jsxs("div", { ref: containerRef, className: "w-full h-full", onDrop: handleDrop, onDragOver: handleDragOver, onDragEnter: handleDragEnter, children: [children, _jsx(InvoiceTable, { files: fileNodes, selected: selected, setSelected: setSelected, filteredDocumentModels: documentModelModules || [], onSelectDocumentModel: onSelectDocumentModel, getDocDispatcher: getDocDispatcher, selectedStatuses: selectedStatuses, onStatusChange: handleStatusChange, onRowSelection: handleRowSelection, canExportSelectedRows: canExportSelectedRows, monthName: monthName, reportingFolderId: reportingFolderId })] }));
224
226
  }
@@ -1,13 +1,20 @@
1
1
  import type { MonthReportSet } from "../hooks/useMonthlyReports.js";
2
+ export interface MonthPaymentStats {
3
+ totalInvoices: number;
4
+ pendingCount: number;
5
+ paidCount: number;
6
+ }
2
7
  interface MonthReportCardProps {
3
8
  reportSet: MonthReportSet;
4
9
  defaultExpanded?: boolean;
5
10
  onCreateExpenseReport?: (monthName: string, folderId: string) => void;
6
11
  onCreateSnapshotReport?: (monthName: string, folderId: string) => void;
12
+ onDeleteReport?: (reportId: string, reportName: string) => Promise<void>;
13
+ onViewPayments?: (monthName: string) => void;
14
+ paymentStats?: MonthPaymentStats;
15
+ /** Suggested start date based on previous month's snapshot period end + 1 day */
16
+ suggestedStartDate?: Date;
7
17
  }
8
- /**
9
- * Collapsible month card showing all reports for a month
10
- */
11
- export declare function MonthReportCard({ reportSet, defaultExpanded, onCreateExpenseReport, onCreateSnapshotReport, }: MonthReportCardProps): import("react/jsx-runtime").JSX.Element;
18
+ export declare function MonthReportCard({ reportSet, defaultExpanded, onCreateExpenseReport, onCreateSnapshotReport, onDeleteReport, onViewPayments, paymentStats, suggestedStartDate, }: MonthReportCardProps): import("react/jsx-runtime").JSX.Element;
12
19
  export {};
13
20
  //# sourceMappingURL=MonthReportCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MonthReportCard.d.ts","sourceRoot":"","sources":["../../../../editors/contributor-billing/components/MonthReportCard.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,+BAA+B,CAAC;AAEvC,UAAU,oBAAoB;IAC5B,SAAS,EAAE,cAAc,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtE,sBAAsB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACxE;AA6ED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,eAAuB,EACvB,qBAAqB,EACrB,sBAAsB,GACvB,EAAE,oBAAoB,2CA2GtB"}
1
+ {"version":3,"file":"MonthReportCard.d.ts","sourceRoot":"","sources":["../../../../editors/contributor-billing/components/MonthReportCard.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,+BAA+B,CAAC;AAGvC,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,oBAAoB;IAC5B,SAAS,EAAE,cAAc,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtE,sBAAsB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACvE,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,IAAI,CAAC;CAC3B;AA6HD,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,eAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,kBAAkB,GACnB,EAAE,oBAAoB,2CAoNtB"}
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useCallback } from "react";
3
- import { Calendar, ChevronDown, ChevronRight, Camera, FileText, ArrowRight, Plus, } from "lucide-react";
3
+ import { Calendar, ChevronDown, ChevronRight, Camera, CreditCard, FileText, ArrowRight, Plus, Info, Trash2, } from "lucide-react";
4
4
  import { setSelectedNode } from "@powerhousedao/reactor-browser";
5
+ import { ConfirmationModal } from "./InvoiceTable/ConfirmationModal.js";
5
6
  /**
6
7
  * Get color classes for status badges
7
8
  */
@@ -37,22 +38,64 @@ function getStatusLabel(status) {
37
38
  /**
38
39
  * Individual report row component
39
40
  */
40
- function ReportRow({ report, isSnapshot = false, }) {
41
+ function ReportRow({ report, isSnapshot = false, onDelete, }) {
41
42
  const colors = getStatusColors(report.status);
42
43
  const handleClick = useCallback(() => {
43
44
  setSelectedNode(report.id);
44
45
  }, [report.id]);
45
- return (_jsxs("button", { onClick: handleClick, className: "w-full flex items-center justify-between p-3 hover:bg-gray-50 cursor-pointer transition-colors border-b border-gray-100 last:border-b-0", children: [_jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [isSnapshot ? (_jsx(Camera, { className: "w-4 h-4 text-purple-500 flex-shrink-0" })) : (_jsx(FileText, { className: "w-4 h-4 text-blue-500 flex-shrink-0" })), _jsx("span", { className: "text-sm text-gray-900 truncate", children: report.name })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("span", { className: `px-2 py-0.5 text-xs font-medium rounded-full ${colors.bg} ${colors.text}`, children: getStatusLabel(report.status) }), _jsx(ArrowRight, { className: "w-4 h-4 text-gray-400" })] })] }));
46
+ const handleDelete = useCallback((e) => {
47
+ e.stopPropagation();
48
+ onDelete?.(report.id, report.name);
49
+ }, [onDelete, report.id, report.name]);
50
+ return (_jsxs("div", { className: "flex items-center border-b border-gray-100 last:border-b-0", children: [_jsxs("button", { onClick: handleClick, className: "flex-1 flex items-center justify-between p-3 hover:bg-gray-50 cursor-pointer transition-colors min-w-0", children: [_jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [isSnapshot ? (_jsx(Camera, { className: "w-4 h-4 text-purple-500 flex-shrink-0" })) : (_jsx(FileText, { className: "w-4 h-4 text-blue-500 flex-shrink-0" })), _jsx("span", { className: "text-sm text-gray-900 truncate", children: report.name })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("span", { className: `px-2 py-0.5 text-xs font-medium rounded-full ${colors.bg} ${colors.text}`, children: getStatusLabel(report.status) }), _jsx(ArrowRight, { className: "w-4 h-4 text-gray-400" })] })] }), onDelete && (_jsx("button", { onClick: handleDelete, className: "p-3 text-gray-400 hover:text-red-500 transition-colors flex-shrink-0", title: "Delete report", children: _jsx(Trash2, { className: "w-4 h-4" }) }))] }));
46
51
  }
47
52
  /**
48
53
  * Collapsible month card showing all reports for a month
49
54
  */
50
- export function MonthReportCard({ reportSet, defaultExpanded = false, onCreateExpenseReport, onCreateSnapshotReport, }) {
55
+ /**
56
+ * Format a date as "Mon DD" (e.g., "Dec 24")
57
+ */
58
+ function formatShortDate(date) {
59
+ return date.toLocaleDateString("en-US", {
60
+ month: "short",
61
+ day: "numeric",
62
+ timeZone: "UTC",
63
+ });
64
+ }
65
+ /**
66
+ * Check if a date is the first day of the month parsed from monthName
67
+ */
68
+ function isFirstOfMonth(date, monthName) {
69
+ const monthDate = new Date(monthName + " 1");
70
+ if (isNaN(monthDate.getTime()))
71
+ return false;
72
+ return (date.getUTCFullYear() === monthDate.getFullYear() &&
73
+ date.getUTCMonth() === monthDate.getMonth() &&
74
+ date.getUTCDate() === 1);
75
+ }
76
+ export function MonthReportCard({ reportSet, defaultExpanded = false, onCreateExpenseReport, onCreateSnapshotReport, onDeleteReport, onViewPayments, paymentStats, suggestedStartDate, }) {
51
77
  const [isExpanded, setIsExpanded] = useState(defaultExpanded);
78
+ const [deleteTarget, setDeleteTarget] = useState(null);
79
+ const [isDeleting, setIsDeleting] = useState(false);
52
80
  const overallColors = getStatusColors(reportSet.overallStatus);
53
81
  const toggleExpanded = useCallback(() => {
54
82
  setIsExpanded((prev) => !prev);
55
83
  }, []);
84
+ const handleDeleteRequest = useCallback((reportId, reportName) => {
85
+ setDeleteTarget({ id: reportId, name: reportName });
86
+ }, []);
87
+ const handleConfirmDelete = useCallback(async () => {
88
+ if (!deleteTarget || !onDeleteReport)
89
+ return;
90
+ setIsDeleting(true);
91
+ try {
92
+ await onDeleteReport(deleteTarget.id, deleteTarget.name);
93
+ }
94
+ finally {
95
+ setIsDeleting(false);
96
+ setDeleteTarget(null);
97
+ }
98
+ }, [deleteTarget, onDeleteReport]);
56
99
  const handleCreateExpenseReport = useCallback(() => {
57
100
  if (onCreateExpenseReport && reportSet.reportingFolderId) {
58
101
  onCreateExpenseReport(reportSet.monthName, reportSet.reportingFolderId);
@@ -67,9 +110,15 @@ export function MonthReportCard({ reportSet, defaultExpanded = false, onCreateEx
67
110
  reportSet.monthName,
68
111
  reportSet.reportingFolderId,
69
112
  ]);
113
+ const handleViewPayments = useCallback(() => {
114
+ onViewPayments?.(reportSet.monthName);
115
+ }, [onViewPayments, reportSet.monthName]);
70
116
  const reportCountText = reportSet.reportCount === 1
71
117
  ? "1 Report"
72
118
  : `${reportSet.reportCount} Reports`;
73
- return (_jsxs("div", { className: "bg-white rounded-xl border border-gray-200 overflow-hidden", children: [_jsxs("button", { onClick: toggleExpanded, className: "w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors text-left", children: [_jsxs("div", { className: "flex items-center gap-3", children: [isExpanded ? (_jsx(ChevronDown, { className: "w-5 h-5 text-gray-400" })) : (_jsx(ChevronRight, { className: "w-5 h-5 text-gray-400" })), _jsx(Calendar, { className: "w-5 h-5 text-gray-600" }), _jsx("span", { className: "font-medium text-gray-900", children: reportSet.monthName })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-sm text-gray-500", children: reportCountText }), reportSet.reportCount > 0 && (_jsx("span", { className: `px-2 py-0.5 text-xs font-medium rounded-full ${overallColors.bg} ${overallColors.text}`, children: getStatusLabel(reportSet.overallStatus) }))] })] }), isExpanded && (_jsxs("div", { className: "border-t border-gray-200", children: [reportSet.snapshotReport && (_jsx(ReportRow, { report: reportSet.snapshotReport, isSnapshot: true })), reportSet.expenseReports.map((report) => (_jsx(ReportRow, { report: report }, report.id))), reportSet.reportCount === 0 && (_jsx("div", { className: "p-4 text-center text-sm text-gray-500", children: "No reports created yet" })), (onCreateExpenseReport || onCreateSnapshotReport) &&
74
- reportSet.reportingFolderId && (_jsxs("div", { className: "p-3 border-t border-gray-100 bg-gray-50 flex items-center gap-3", children: [onCreateSnapshotReport && !reportSet.snapshotReport && (_jsxs("button", { onClick: handleCreateSnapshotReport, className: "flex items-center gap-2 text-sm text-purple-600 hover:text-purple-700 font-medium transition-colors", children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Snapshot Report"] })), onCreateExpenseReport && (_jsxs("button", { onClick: handleCreateExpenseReport, className: "flex items-center gap-2 text-sm text-blue-600 hover:text-blue-700 font-medium transition-colors", children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Expense Report"] }))] }))] }))] }));
119
+ return (_jsxs("div", { className: "bg-white rounded-xl border border-gray-200 overflow-hidden", children: [_jsxs("button", { onClick: toggleExpanded, className: "w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors text-left", children: [_jsxs("div", { className: "flex items-center gap-3", children: [isExpanded ? (_jsx(ChevronDown, { className: "w-5 h-5 text-gray-400" })) : (_jsx(ChevronRight, { className: "w-5 h-5 text-gray-400" })), _jsx(Calendar, { className: "w-5 h-5 text-gray-600" }), _jsx("span", { className: "font-medium text-gray-900", children: reportSet.monthName })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-sm text-gray-500", children: reportCountText }), reportSet.reportCount > 0 && (_jsx("span", { className: `px-2 py-0.5 text-xs font-medium rounded-full ${overallColors.bg} ${overallColors.text}`, children: getStatusLabel(reportSet.overallStatus) }))] })] }), isExpanded && (_jsxs("div", { className: "border-t border-gray-200", children: [onViewPayments && (_jsxs("button", { onClick: handleViewPayments, className: "w-full flex items-center justify-between p-3 hover:bg-gray-50 cursor-pointer transition-colors border-b border-gray-100", children: [_jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [_jsx(CreditCard, { className: "w-4 h-4 text-emerald-500 flex-shrink-0" }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: "Payments" }), paymentStats && paymentStats.totalInvoices > 0 && (_jsxs("span", { className: "text-xs text-gray-500", children: [paymentStats.totalInvoices, " invoice", paymentStats.totalInvoices !== 1 ? "s" : "", paymentStats.pendingCount > 0 && (_jsxs("span", { className: "text-amber-600", children: [" ", "\u00B7 ", paymentStats.pendingCount, " pending"] })), paymentStats.paidCount > 0 && (_jsxs("span", { className: "text-green-600", children: [" ", "\u00B7 ", paymentStats.paidCount, " paid"] }))] }))] }), _jsx(ArrowRight, { className: "w-4 h-4 text-gray-400 flex-shrink-0" })] })), reportSet.snapshotReport && (_jsx(ReportRow, { report: reportSet.snapshotReport, isSnapshot: true, onDelete: onDeleteReport ? handleDeleteRequest : undefined })), reportSet.expenseReports.map((report) => (_jsx(ReportRow, { report: report, onDelete: onDeleteReport ? handleDeleteRequest : undefined }, report.id))), reportSet.reportCount === 0 && (_jsx("div", { className: "p-4 text-center text-sm text-gray-500", children: "No reports created yet" })), (onCreateExpenseReport || onCreateSnapshotReport) &&
120
+ reportSet.reportingFolderId && (_jsxs("div", { className: "p-3 border-t border-gray-100 bg-gray-50", children: [_jsxs("div", { className: "flex items-center gap-3", children: [onCreateSnapshotReport && !reportSet.snapshotReport && (_jsxs("button", { onClick: handleCreateSnapshotReport, className: "flex items-center gap-2 text-sm text-purple-600 hover:text-purple-700 font-medium transition-colors", children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Snapshot Report"] })), onCreateExpenseReport && (_jsxs("button", { onClick: handleCreateExpenseReport, className: "flex items-center gap-2 text-sm text-blue-600 hover:text-blue-700 font-medium transition-colors", children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Expense Report"] }))] }), onCreateSnapshotReport &&
121
+ !reportSet.snapshotReport &&
122
+ suggestedStartDate &&
123
+ !isFirstOfMonth(suggestedStartDate, reportSet.monthName) && (_jsxs("div", { className: "flex items-center gap-1.5 mt-2 text-xs text-indigo-600", children: [_jsx(Info, { className: "w-3.5 h-3.5 flex-shrink-0" }), _jsxs("span", { children: ["Transaction period will start", " ", formatShortDate(suggestedStartDate), " (day after previous snapshot period ends)"] })] }))] }))] })), _jsxs(ConfirmationModal, { open: !!deleteTarget, header: "Delete Report", onCancel: () => setDeleteTarget(null), onContinue: () => void handleConfirmDelete(), cancelLabel: "Cancel", continueLabel: isDeleting ? "Deleting..." : "Delete", continueDisabled: isDeleting, children: [_jsx("p", { className: "text-red-600 text-sm mb-2 font-medium", children: "This will permanently delete this report from the drive. This action cannot be undone." }), deleteTarget && (_jsx("p", { className: "text-gray-700 text-sm font-medium", children: deleteTarget.name }))] })] }));
75
124
  }
@@ -10,6 +10,6 @@ interface MonthlyReportsOverviewProps {
10
10
  * Monthly Reports Overview component for the billing page
11
11
  * Shows collapsible month cards with reports and status
12
12
  */
13
- export declare function MonthlyReportsOverview({ monthFolders, onCreateMonth, onActiveNodeIdChange, }: MonthlyReportsOverviewProps): import("react/jsx-runtime").JSX.Element;
13
+ export declare function MonthlyReportsOverview({ onFolderSelect, monthFolders, onCreateMonth, onActiveNodeIdChange, }: MonthlyReportsOverviewProps): import("react/jsx-runtime").JSX.Element;
14
14
  export {};
15
15
  //# sourceMappingURL=MonthlyReportsOverview.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MonthlyReportsOverview.d.ts","sourceRoot":"","sources":["../../../../editors/contributor-billing/components/MonthlyReportsOverview.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAa7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,UAAU,2BAA2B;IACnC,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAsCD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,aAAa,EACb,oBAAoB,GACrB,EAAE,2BAA2B,2CA4U7B"}
1
+ {"version":3,"file":"MonthlyReportsOverview.d.ts","sourceRoot":"","sources":["../../../../editors/contributor-billing/components/MonthlyReportsOverview.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAkB7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,UAAU,2BAA2B;IACnC,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAuED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,cAAc,EACd,YAAY,EACZ,aAAa,EACb,oBAAoB,GACrB,EAAE,2BAA2B,2CA0b7B"}
@@ -2,10 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useState, useMemo, useRef, useEffect } from "react";
3
3
  import { createPortal } from "react-dom";
4
4
  import { BarChart3, Plus, ChevronDown } from "lucide-react";
5
- import { useSelectedDrive, addDocument, dispatchActions, setSelectedNode, } from "@powerhousedao/reactor-browser";
5
+ import { useSelectedDrive, useDocumentsInSelectedDrive, addDocument, dispatchActions, setSelectedNode, isFileNodeKind, } from "@powerhousedao/reactor-browser";
6
6
  import { setName } from "document-model";
7
- import { moveNode } from "document-drive";
8
- import { useMonthlyReports } from "../hooks/useMonthlyReports.js";
7
+ import { moveNode, deleteNode } from "document-drive";
8
+ import { useMonthlyReports, } from "../hooks/useMonthlyReports.js";
9
9
  import { MonthReportCard } from "./MonthReportCard.js";
10
10
  import { actions as expenseReportActions } from "../../../document-models/expense-report/index.js";
11
11
  import { actions as snapshotReportActions } from "../../../document-models/snapshot-report/index.js";
@@ -38,18 +38,97 @@ function parseMonthDates(monthName) {
38
38
  const end = new Date(Date.UTC(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999));
39
39
  return { start, end };
40
40
  }
41
+ /**
42
+ * Get the suggested start date for a new snapshot report based on the previous
43
+ * month's snapshot period end date. Returns the day after the previous period
44
+ * ends, or the first day of the month if there's no previous snapshot.
45
+ */
46
+ function getSuggestedSnapshotStartDate(monthName, monthReportSets) {
47
+ const monthDates = parseMonthDates(monthName);
48
+ if (!monthDates)
49
+ return null;
50
+ // Find the current month's index in the sorted (descending) list
51
+ const currentIndex = monthReportSets.findIndex((s) => s.monthName === monthName);
52
+ if (currentIndex === -1)
53
+ return null;
54
+ // The previous month is the next item in the descending-sorted array
55
+ const previousMonth = monthReportSets[currentIndex + 1];
56
+ if (!previousMonth?.snapshotEndDate)
57
+ return null;
58
+ const previousEnd = new Date(previousMonth.snapshotEndDate);
59
+ if (isNaN(previousEnd.getTime()))
60
+ return null;
61
+ // Suggested start = previous period end + 1 day
62
+ const suggestedStart = new Date(previousEnd);
63
+ suggestedStart.setUTCDate(suggestedStart.getUTCDate() + 1);
64
+ suggestedStart.setUTCHours(0, 0, 0, 0);
65
+ return suggestedStart;
66
+ }
41
67
  /**
42
68
  * Monthly Reports Overview component for the billing page
43
69
  * Shows collapsible month cards with reports and status
44
70
  */
45
- export function MonthlyReportsOverview({ monthFolders, onCreateMonth, onActiveNodeIdChange, }) {
71
+ export function MonthlyReportsOverview({ onFolderSelect, monthFolders, onCreateMonth, onActiveNodeIdChange, }) {
46
72
  const { monthReportSets, isLoading } = useMonthlyReports();
47
73
  const [selectedDrive] = useSelectedDrive();
74
+ const documentsInDrive = useDocumentsInSelectedDrive();
48
75
  const [isCreating, setIsCreating] = useState(false);
49
76
  const [isAddingMonth, setIsAddingMonth] = useState(false);
50
77
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
51
78
  const dropdownRef = useRef(null);
52
79
  const driveId = selectedDrive?.header.id;
80
+ // Per-month payment stats for the Payments row in each card
81
+ const monthPaymentStatsMap = useMemo(() => {
82
+ const map = new Map();
83
+ if (!selectedDrive || !documentsInDrive || !monthFolders)
84
+ return map;
85
+ const nodes = selectedDrive.state.global.nodes;
86
+ for (const [monthName, folderInfo] of monthFolders.entries()) {
87
+ const paymentsFolderId = folderInfo.paymentsFolder?.id;
88
+ if (!paymentsFolderId)
89
+ continue;
90
+ const invoiceIds = new Set(nodes
91
+ .filter((n) => isFileNodeKind(n) &&
92
+ n.parentFolder === paymentsFolderId &&
93
+ n.documentType === "powerhouse/invoice")
94
+ .map((n) => n.id));
95
+ const invoices = documentsInDrive.filter((doc) => doc.header.documentType === "powerhouse/invoice" &&
96
+ invoiceIds.has(doc.header.id));
97
+ let pendingCount = 0;
98
+ let paidCount = 0;
99
+ for (const invoice of invoices) {
100
+ const status = (invoice.state.global?.status ??
101
+ "").toUpperCase();
102
+ if (status === "PAYMENTSENT" ||
103
+ status === "PAYMENTRECEIVED" ||
104
+ status === "PAYMENTCLOSED") {
105
+ paidCount++;
106
+ }
107
+ else if (status !== "REJECTED" && status !== "CANCELLED") {
108
+ pendingCount++;
109
+ }
110
+ }
111
+ map.set(monthName, {
112
+ totalInvoices: invoices.length,
113
+ pendingCount,
114
+ paidCount,
115
+ });
116
+ }
117
+ return map;
118
+ }, [selectedDrive, documentsInDrive, monthFolders]);
119
+ const handleViewPayments = useCallback((monthName) => {
120
+ if (!onFolderSelect || !monthFolders)
121
+ return;
122
+ const info = monthFolders.get(monthName);
123
+ if (!info?.paymentsFolder)
124
+ return;
125
+ onFolderSelect({
126
+ folderId: info.paymentsFolder.id,
127
+ folderType: "payments",
128
+ monthName,
129
+ reportingFolderId: info.reportingFolder?.id,
130
+ });
131
+ }, [onFolderSelect, monthFolders]);
53
132
  const buttonRef = useRef(null);
54
133
  const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 });
55
134
  // Update dropdown position when opening
@@ -165,9 +244,12 @@ export function MonthlyReportsOverview({ monthFolders, onCreateMonth, onActiveNo
165
244
  }
166
245
  // Set the document name
167
246
  await dispatchActions(setName(reportName), createdNode.id);
168
- // Set period dates based on month
247
+ // Set reporting period to calendar month boundaries
169
248
  const dates = parseMonthDates(monthName);
170
249
  if (dates) {
250
+ const suggestedStart = getSuggestedSnapshotStartDate(monthName, monthReportSets);
251
+ // Transaction filtering start: previous period end + 1 day, or month start
252
+ const txStartDate = suggestedStart || dates.start;
171
253
  await dispatchActions([
172
254
  snapshotReportActions.setPeriodStart({
173
255
  periodStart: dates.start.toISOString(),
@@ -176,6 +258,11 @@ export function MonthlyReportsOverview({ monthFolders, onCreateMonth, onActiveNo
176
258
  periodEnd: dates.end.toISOString(),
177
259
  }),
178
260
  ], createdNode.id);
261
+ // Set the transaction filtering range (snapshot period) separately
262
+ await dispatchActions(snapshotReportActions.setReportConfig({
263
+ startDate: txStartDate.toISOString(),
264
+ endDate: dates.end.toISOString(),
265
+ }), createdNode.id);
179
266
  }
180
267
  // Open the created report
181
268
  setSelectedNode(createdNode.id);
@@ -185,7 +272,17 @@ export function MonthlyReportsOverview({ monthFolders, onCreateMonth, onActiveNo
185
272
  finally {
186
273
  setIsCreating(false);
187
274
  }
188
- }, [driveId, isCreating, onActiveNodeIdChange]);
275
+ }, [driveId, isCreating, monthReportSets, onActiveNodeIdChange]);
276
+ const handleDeleteReport = useCallback(async (reportId) => {
277
+ if (!driveId)
278
+ return;
279
+ try {
280
+ await dispatchActions(deleteNode({ id: reportId }), driveId);
281
+ }
282
+ catch (error) {
283
+ console.error("Failed to delete report:", error);
284
+ }
285
+ }, [driveId]);
189
286
  // Add Month button component (reused across states)
190
287
  const addMonthButton = onCreateMonth && (_jsxs("div", { className: "relative", children: [_jsxs("button", { ref: buttonRef, onClick: () => setIsDropdownOpen(!isDropdownOpen), disabled: isAddingMonth, className: "flex items-center gap-1.5 px-3 py-1.5 text-sm bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: [_jsx(Plus, { className: "w-4 h-4" }), isAddingMonth ? "Adding..." : "Add Month", _jsx(ChevronDown, { className: "w-3 h-3" })] }), isDropdownOpen &&
191
288
  createPortal(_jsxs("div", { ref: dropdownRef, className: "fixed w-56 bg-white rounded-lg shadow-lg border border-gray-200 py-1 z-[9999]", style: {
@@ -200,5 +297,5 @@ export function MonthlyReportsOverview({ monthFolders, onCreateMonth, onActiveNo
200
297
  if (monthReportSets.length === 0) {
201
298
  return (_jsxs("div", { className: "bg-white rounded-xl border border-gray-200 p-6 overflow-visible", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 mb-5", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 bg-indigo-100 rounded-lg", children: _jsx(BarChart3, { className: "w-5 h-5 text-indigo-600" }) }), _jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Monthly Reports" }), _jsx("p", { className: "text-sm text-gray-600", children: "Quick access to expense and snapshot reports" })] })] }), addMonthButton] }), _jsx("p", { className: "text-gray-500 text-sm text-center py-4", children: "No months configured yet. Click \"Add Month\" to get started." })] }));
202
299
  }
203
- return (_jsxs("div", { className: "bg-white rounded-xl border border-gray-200 p-6 overflow-visible", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 mb-5", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 bg-indigo-100 rounded-lg", children: _jsx(BarChart3, { className: "w-5 h-5 text-indigo-600" }) }), _jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Monthly Reports" }), _jsx("p", { className: "text-sm text-gray-600", children: "Quick access to expense and snapshot reports" })] })] }), addMonthButton] }), _jsx("div", { className: "space-y-3", children: monthReportSets.map((reportSet, index) => (_jsx(MonthReportCard, { reportSet: reportSet, defaultExpanded: index === 0, onCreateExpenseReport: handleCreateExpenseReport, onCreateSnapshotReport: handleCreateSnapshotReport }, reportSet.monthName))) })] }));
300
+ return (_jsxs("div", { className: "bg-white rounded-xl border border-gray-200 p-6 overflow-visible", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 mb-5", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 bg-indigo-100 rounded-lg", children: _jsx(BarChart3, { className: "w-5 h-5 text-indigo-600" }) }), _jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Monthly Reports" }), _jsx("p", { className: "text-sm text-gray-600", children: "Quick access to expense and snapshot reports" })] })] }), addMonthButton] }), _jsx("div", { className: "space-y-3", children: monthReportSets.map((reportSet, index) => (_jsx(MonthReportCard, { reportSet: reportSet, defaultExpanded: index === 0, onCreateExpenseReport: handleCreateExpenseReport, onCreateSnapshotReport: handleCreateSnapshotReport, onDeleteReport: handleDeleteReport, onViewPayments: onFolderSelect ? handleViewPayments : undefined, paymentStats: monthPaymentStatsMap.get(reportSet.monthName), suggestedStartDate: getSuggestedSnapshotStartDate(reportSet.monthName, monthReportSets) || undefined }, reportSet.monthName))) })] }));
204
301
  }
@@ -2,9 +2,6 @@ interface ReportingViewProps {
2
2
  folderId: string;
3
3
  monthName?: string;
4
4
  }
5
- /**
6
- * View for the Reporting folder showing Expense Reports and Snapshot Reports
7
- */
8
5
  export declare function ReportingView({ folderId, monthName }: ReportingViewProps): import("react/jsx-runtime").JSX.Element;
9
6
  export {};
10
7
  //# sourceMappingURL=ReportingView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReportingView.d.ts","sourceRoot":"","sources":["../../../../editors/contributor-billing/components/ReportingView.tsx"],"names":[],"mappings":"AAeA,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4BD;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,kBAAkB,2CAmSxE"}
1
+ {"version":3,"file":"ReportingView.d.ts","sourceRoot":"","sources":["../../../../editors/contributor-billing/components/ReportingView.tsx"],"names":[],"mappings":"AAiBA,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+DD,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,kBAAkB,2CA2XxE"}