@layerfi/components 0.1.106-alpha → 0.1.106-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5570,7 +5570,7 @@ import { useState as useState5 } from "react";
5570
5570
  import { useReducer, useEffect as useEffect2 } from "react";
5571
5571
 
5572
5572
  // package.json
5573
- var version = "0.1.106-alpha";
5573
+ var version = "0.1.106-alpha.1";
5574
5574
 
5575
5575
  // src/models/APIError.ts
5576
5576
  var APIError = class _APIError extends Error {
@@ -7045,19 +7045,12 @@ import { SWRConfig } from "swr";
7045
7045
 
7046
7046
  // src/providers/GlobalDateStore/GlobalDateStoreProvider.tsx
7047
7047
  import {
7048
- addDays,
7049
- differenceInDays as differenceInDays2,
7050
- differenceInMonths,
7051
7048
  endOfDay,
7052
7049
  endOfMonth,
7053
7050
  endOfYear,
7054
7051
  min,
7055
- startOfDay,
7056
7052
  startOfMonth,
7057
- startOfYear,
7058
- subDays,
7059
- subMonths,
7060
- subYears
7053
+ startOfYear
7061
7054
  } from "date-fns";
7062
7055
  import { useState as useState4, createContext as createContext5, useContext as useContext6 } from "react";
7063
7056
  import { createStore, useStore } from "zustand";
@@ -7099,48 +7092,28 @@ var _RANGE_PICKER_MODES = [
7099
7092
  var isDateRangePickerMode = (mode) => {
7100
7093
  return _RANGE_PICKER_MODES.includes(mode);
7101
7094
  };
7102
- function startOfNextDay(date) {
7103
- return startOfDay(addDays(date, 1));
7104
- }
7105
7095
  function clampToPresentOrPast(date, cutoff = endOfDay(/* @__PURE__ */ new Date())) {
7106
7096
  return min([date, cutoff]);
7107
7097
  }
7108
- function withShiftedEnd(fn) {
7109
- return ({ currentStart, currentEnd, newEnd }) => {
7110
- const shiftedCurrentEnd = startOfNextDay(currentEnd);
7111
- const shiftedNewEnd = clampToPresentOrPast(startOfNextDay(newEnd), startOfNextDay(/* @__PURE__ */ new Date()));
7112
- return fn({ currentStart, shiftedCurrentEnd, shiftedNewEnd });
7113
- };
7114
- }
7115
7098
  var RANGE_MODE_LOOKUP = {
7099
+ dayPicker: {
7100
+ getStart: ({ start }) => start,
7101
+ getEnd: ({ end }) => clampToPresentOrPast(endOfDay(end))
7102
+ },
7116
7103
  dayRangePicker: {
7117
7104
  getStart: ({ start }) => start,
7118
- getShiftedStart: withShiftedEnd(({ currentStart, shiftedCurrentEnd, shiftedNewEnd }) => {
7119
- const fullDayCount = differenceInDays2(shiftedCurrentEnd, currentStart);
7120
- return subDays(shiftedNewEnd, fullDayCount);
7121
- }),
7122
7105
  getEnd: ({ end }) => clampToPresentOrPast(endOfDay(end))
7123
7106
  },
7124
7107
  monthPicker: {
7125
7108
  getStart: ({ start }) => startOfMonth(start),
7126
- getShiftedStart: withShiftedEnd(({ shiftedNewEnd }) => {
7127
- return subMonths(shiftedNewEnd, 1);
7128
- }),
7129
7109
  getEnd: ({ end }) => clampToPresentOrPast(endOfMonth(end))
7130
7110
  },
7131
7111
  monthRangePicker: {
7132
7112
  getStart: ({ start }) => startOfMonth(start),
7133
- getShiftedStart: withShiftedEnd(({ currentStart, shiftedCurrentEnd, shiftedNewEnd }) => {
7134
- const fullMonthCount = differenceInMonths(shiftedCurrentEnd, currentStart);
7135
- return subMonths(shiftedNewEnd, fullMonthCount);
7136
- }),
7137
7113
  getEnd: ({ end }) => clampToPresentOrPast(endOfMonth(end))
7138
7114
  },
7139
7115
  yearPicker: {
7140
7116
  getStart: ({ start }) => startOfYear(start),
7141
- getShiftedStart: withShiftedEnd(({ shiftedNewEnd }) => {
7142
- return subYears(shiftedNewEnd, 1);
7143
- }),
7144
7117
  getEnd: ({ end }) => clampToPresentOrPast(endOfYear(end))
7145
7118
  }
7146
7119
  };
@@ -7156,6 +7129,12 @@ function withCorrectedRange(fn) {
7156
7129
  function buildStore() {
7157
7130
  const now = /* @__PURE__ */ new Date();
7158
7131
  return createStore((set2) => {
7132
+ const setDate = ({ date }) => {
7133
+ set2({
7134
+ start: RANGE_MODE_LOOKUP.dayPicker.getStart({ start: date }),
7135
+ end: RANGE_MODE_LOOKUP.dayPicker.getEnd({ end: date })
7136
+ });
7137
+ };
7159
7138
  const setDateRange = withCorrectedRange(({ start, end }) => {
7160
7139
  set2({
7161
7140
  start: RANGE_MODE_LOOKUP.dayRangePicker.getStart({ start }),
@@ -7183,9 +7162,12 @@ function buildStore() {
7183
7162
  const setRangeWithExplicitDisplayMode = ({
7184
7163
  start,
7185
7164
  end,
7186
- rangeDisplayMode
7165
+ displayMode
7187
7166
  }) => {
7188
- switch (rangeDisplayMode) {
7167
+ switch (displayMode) {
7168
+ case "dayPicker":
7169
+ setDate({ date: end });
7170
+ break;
7189
7171
  case "dayRangePicker":
7190
7172
  setDateRange({ start, end });
7191
7173
  break;
@@ -7200,8 +7182,8 @@ function buildStore() {
7200
7182
  break;
7201
7183
  default:
7202
7184
  safeAssertUnreachable({
7203
- value: rangeDisplayMode,
7204
- message: "Invalid `rangeDisplayMode`"
7185
+ value: displayMode,
7186
+ message: "Invalid `displayMode`"
7205
7187
  });
7206
7188
  }
7207
7189
  };
@@ -7209,22 +7191,7 @@ function buildStore() {
7209
7191
  start: startOfMonth(now),
7210
7192
  end: clampToPresentOrPast(endOfMonth(now)),
7211
7193
  actions: {
7212
- setDate: ({ date }) => {
7213
- set2(({
7214
- start: currentStart,
7215
- end: currentEnd
7216
- }) => {
7217
- const newEnd = RANGE_MODE_LOOKUP.dayRangePicker.getEnd({ end: date });
7218
- return {
7219
- start: RANGE_MODE_LOOKUP.dayRangePicker.getShiftedStart({
7220
- currentStart,
7221
- currentEnd,
7222
- newEnd
7223
- }),
7224
- end: newEnd
7225
- };
7226
- });
7227
- },
7194
+ setDate,
7228
7195
  setRangeWithExplicitDisplayMode,
7229
7196
  setDateRange,
7230
7197
  setMonth,
@@ -12317,8 +12284,7 @@ var LinkedAccountsContent = ({
12317
12284
  asWidget,
12318
12285
  showLedgerBalance,
12319
12286
  showUnlinkItem,
12320
- showBreakConnection,
12321
- showAddAccount
12287
+ showBreakConnection
12322
12288
  }) => {
12323
12289
  const { data, addConnection } = useContext13(LinkedAccountsContext);
12324
12290
  const linkedAccountsNewAccountClassName = classNames25(
@@ -12341,7 +12307,7 @@ var LinkedAccountsContent = ({
12341
12307
  },
12342
12308
  index
12343
12309
  )),
12344
- showAddAccount && /* @__PURE__ */ jsx78(
12310
+ /* @__PURE__ */ jsx78(
12345
12311
  "div",
12346
12312
  {
12347
12313
  role: "button",
@@ -12818,9 +12784,9 @@ import {
12818
12784
  startOfMonth as startOfMonth4,
12819
12785
  startOfQuarter,
12820
12786
  startOfYear as startOfYear2,
12821
- subMonths as subMonths2,
12787
+ subMonths,
12822
12788
  subQuarters,
12823
- subYears as subYears2
12789
+ subYears
12824
12790
  } from "date-fns";
12825
12791
  import { Fragment as Fragment13, jsx as jsx89 } from "react/jsx-runtime";
12826
12792
  var DatePickerOptions = ({
@@ -12832,8 +12798,8 @@ var DatePickerOptions = ({
12832
12798
  },
12833
12799
  {
12834
12800
  label: "Last month",
12835
- startDate: startOfMonth4(subMonths2(/* @__PURE__ */ new Date(), 1)),
12836
- endDate: endOfMonth3(subMonths2(/* @__PURE__ */ new Date(), 1))
12801
+ startDate: startOfMonth4(subMonths(/* @__PURE__ */ new Date(), 1)),
12802
+ endDate: endOfMonth3(subMonths(/* @__PURE__ */ new Date(), 1))
12837
12803
  },
12838
12804
  {
12839
12805
  label: "This quarter",
@@ -12852,8 +12818,8 @@ var DatePickerOptions = ({
12852
12818
  },
12853
12819
  {
12854
12820
  label: "Last year",
12855
- startDate: startOfYear2(subYears2(/* @__PURE__ */ new Date(), 1)),
12856
- endDate: endOfYear2(subYears2(/* @__PURE__ */ new Date(), 1))
12821
+ startDate: startOfYear2(subYears(/* @__PURE__ */ new Date(), 1)),
12822
+ endDate: endOfYear2(subYears(/* @__PURE__ */ new Date(), 1))
12857
12823
  }
12858
12824
  ],
12859
12825
  setSelectedDate
@@ -12916,6 +12882,25 @@ var highlightNextArrow = ({
12916
12882
  }
12917
12883
  return false;
12918
12884
  };
12885
+ var getDateFormat = (mode) => {
12886
+ switch (mode) {
12887
+ case "dayPicker":
12888
+ case "dayRangePicker":
12889
+ return "MMM d, yyyy";
12890
+ case "monthPicker":
12891
+ case "monthRangePicker":
12892
+ return "MMM yyyy";
12893
+ case "yearPicker":
12894
+ return "yyyy";
12895
+ case "timePicker":
12896
+ return "h:mm aa";
12897
+ default:
12898
+ unsafeAssertUnreachable({
12899
+ value: mode,
12900
+ message: "Invalid datepicker mode"
12901
+ });
12902
+ }
12903
+ };
12919
12904
  var DatePicker = (_a) => {
12920
12905
  var _b = _a, {
12921
12906
  selected,
@@ -12923,7 +12908,7 @@ var DatePicker = (_a) => {
12923
12908
  disabled,
12924
12909
  displayMode = "dayPicker",
12925
12910
  allowedModes,
12926
- dateFormat = displayMode === "monthPicker" || displayMode === "monthRangePicker" ? "MMM, yyyy" : displayMode === "timePicker" ? "h:mm aa" : "MMM d, yyyy",
12911
+ dateFormat = getDateFormat(displayMode),
12927
12912
  timeIntervals = 15,
12928
12913
  timeCaption,
12929
12914
  placeholderText: _placeholderText,
@@ -13228,7 +13213,7 @@ var DatePicker = (_a) => {
13228
13213
  };
13229
13214
 
13230
13215
  // src/components/LinkedAccounts/AccountFormBox/AccountFormBox.tsx
13231
- import { isEqual, startOfDay as startOfDay2 } from "date-fns";
13216
+ import { isEqual, startOfDay } from "date-fns";
13232
13217
  import { jsx as jsx91, jsxs as jsxs54 } from "react/jsx-runtime";
13233
13218
  var CLASS_NAME5 = "Layer__caobfb";
13234
13219
  var AccountFormBox = ({
@@ -13289,7 +13274,7 @@ var AccountFormBox = ({
13289
13274
  onChange(__spreadProps(__spreadValues({}, value), { openingDate: v }));
13290
13275
  }
13291
13276
  },
13292
- selected: (_e = value.openingDate) != null ? _e : startOfDay2(/* @__PURE__ */ new Date()),
13277
+ selected: (_e = value.openingDate) != null ? _e : startOfDay(/* @__PURE__ */ new Date()),
13293
13278
  currentDateOption: false,
13294
13279
  disabled: !disableConfirmExclude && !value.isConfirmed
13295
13280
  }
@@ -13647,11 +13632,10 @@ var LinkedAccounts = (props) => {
13647
13632
  };
13648
13633
  var LinkedAccountsComponent = ({
13649
13634
  asWidget,
13650
- elevated,
13635
+ elevated = false,
13651
13636
  showLedgerBalance = true,
13652
13637
  showUnlinkItem = false,
13653
13638
  showBreakConnection = false,
13654
- showAddAccount = true,
13655
13639
  stringOverrides
13656
13640
  }) => {
13657
13641
  const {
@@ -13686,8 +13670,7 @@ var LinkedAccountsComponent = ({
13686
13670
  asWidget,
13687
13671
  showLedgerBalance,
13688
13672
  showUnlinkItem,
13689
- showBreakConnection,
13690
- showAddAccount
13673
+ showBreakConnection
13691
13674
  }
13692
13675
  ) : null,
13693
13676
  /* @__PURE__ */ jsx93(OpeningBalanceModal, {})
@@ -16492,6 +16475,7 @@ function buildCustomPlaceholder({ placeholder }) {
16492
16475
  } = _b, restProps = __objRest(_b, [
16493
16476
  "children"
16494
16477
  ]);
16478
+ if (!placeholder) return null;
16495
16479
  return /* @__PURE__ */ jsx118(
16496
16480
  components4.Placeholder,
16497
16481
  __spreadProps(__spreadValues({}, restProps), {
@@ -21632,7 +21616,7 @@ var HEADER_HEIGHT = 41;
21632
21616
  var CONTAINER_HEIGHT = ROW_HEIGHT * MAX_NUM_ROWS + HEADER_HEIGHT - 1;
21633
21617
  var CSS_PREFIX = "Layer__csv-upload__validate-csv-table";
21634
21618
  function ValidateCsvTable({ data, headers, formatters: formatters2, className }) {
21635
- const columns2 = useMemo30(
21619
+ const columns = useMemo30(
21636
21620
  () => {
21637
21621
  const columnDefs = [{
21638
21622
  id: "row",
@@ -21686,7 +21670,7 @@ function ValidateCsvTable({ data, headers, formatters: formatters2, className })
21686
21670
  }), []);
21687
21671
  const table = useReactTable({
21688
21672
  data,
21689
- columns: columns2,
21673
+ columns,
21690
21674
  state,
21691
21675
  getCoreRowModel: getCoreRowModel(),
21692
21676
  getSortedRowModel: getSortedRowModel()
@@ -22945,12 +22929,11 @@ var Integrations = (props) => {
22945
22929
  return /* @__PURE__ */ jsx189(QuickbooksContextProvider, { children: /* @__PURE__ */ jsx189(IntegrationsComponent, __spreadValues({}, props)) });
22946
22930
  };
22947
22931
  var IntegrationsComponent = ({
22948
- elevated,
22949
22932
  stringOverrides
22950
22933
  }) => {
22951
22934
  const { quickbooksConnectionStatus } = useContext30(QuickbooksContext);
22952
22935
  const isLoading = quickbooksConnectionStatus === void 0;
22953
- return /* @__PURE__ */ jsxs122(Container, { name: COMPONENT_NAME3, elevated, children: [
22936
+ return /* @__PURE__ */ jsxs122(Container, { name: COMPONENT_NAME3, children: [
22954
22937
  /* @__PURE__ */ jsxs122(Header, { className: "Layer__linked-accounts__header", children: [
22955
22938
  /* @__PURE__ */ jsx189(
22956
22939
  Heading,
@@ -23282,6 +23265,7 @@ var defaultModeByReport = {
23282
23265
  };
23283
23266
  var ReportsModeStoreContext = createContext18(
23284
23267
  createStore3(() => ({
23268
+ resetPnLModeToDefaultOnMount: true,
23285
23269
  modeByReport: {},
23286
23270
  actions: {
23287
23271
  setModeForReport: () => {
@@ -23289,6 +23273,10 @@ var ReportsModeStoreContext = createContext18(
23289
23273
  }
23290
23274
  }))
23291
23275
  );
23276
+ function useReportModeStore() {
23277
+ const store = useContext31(ReportsModeStoreContext);
23278
+ return useStore4(store);
23279
+ }
23292
23280
  function useReportMode(report) {
23293
23281
  const store = useContext31(ReportsModeStoreContext);
23294
23282
  return useStore4(store, (state) => state.modeByReport[report]);
@@ -23304,11 +23292,13 @@ function useReportModeWithFallback(report, fallback) {
23304
23292
  }
23305
23293
  function ReportsModeStoreProvider({
23306
23294
  children,
23307
- initialModes
23295
+ initialModes,
23296
+ resetPnLModeToDefaultOnMount = true
23308
23297
  }) {
23309
23298
  const [store] = useState50(
23310
23299
  () => createStore3((set2) => ({
23311
23300
  modeByReport: __spreadValues(__spreadValues({}, defaultModeByReport), initialModes),
23301
+ resetPnLModeToDefaultOnMount,
23312
23302
  actions: {
23313
23303
  setModeForReport: (report, mode) => set2((state) => ({
23314
23304
  modeByReport: __spreadProps(__spreadValues({}, state.modeByReport), {
@@ -23488,7 +23478,7 @@ var useProfitAndLoss = ({
23488
23478
  import { useMemo as useMemo36, useState as useState52 } from "react";
23489
23479
 
23490
23480
  // src/hooks/useProfitAndLossComparison/utils.ts
23491
- import { getMonth, getYear as getYear2, startOfMonth as startOfMonth9, startOfYear as startOfYear4, subMonths as subMonths3, subYears as subYears3 } from "date-fns";
23481
+ import { getMonth, getYear as getYear2, startOfMonth as startOfMonth9, startOfYear as startOfYear4, subMonths as subMonths2, subYears as subYears2 } from "date-fns";
23492
23482
 
23493
23483
  // src/utils/array/range.ts
23494
23484
  function range2(start, end) {
@@ -23548,7 +23538,7 @@ function prepareFiltersBody(compareOptions) {
23548
23538
  function preparePeriodsBodyForMonths(dateRange, comparePeriods) {
23549
23539
  const adjustedStartDate = startOfMonth9(dateRange.startDate);
23550
23540
  const rawPeriods = range2(0, comparePeriods).map((index) => {
23551
- const currentPeriod = subMonths3(adjustedStartDate, index);
23541
+ const currentPeriod = subMonths2(adjustedStartDate, index);
23552
23542
  return {
23553
23543
  year: getYear2(currentPeriod),
23554
23544
  month: getMonth(currentPeriod) + 1
@@ -23571,7 +23561,7 @@ function preparePeriodsBodyForMonths(dateRange, comparePeriods) {
23571
23561
  function preparePeriodsBodyForYears(dateRange, comparePeriods) {
23572
23562
  const adjustedStartDate = startOfYear4(dateRange.startDate);
23573
23563
  const rawPeriods = range2(0, comparePeriods).map((index) => {
23574
- const currentPeriod = subYears3(adjustedStartDate, index);
23564
+ const currentPeriod = subYears2(adjustedStartDate, index);
23575
23565
  return {
23576
23566
  year: getYear2(currentPeriod)
23577
23567
  };
@@ -23833,7 +23823,7 @@ var Indicator = ({
23833
23823
  import classNames61 from "classnames";
23834
23824
  import {
23835
23825
  add,
23836
- differenceInMonths as differenceInMonths2,
23826
+ differenceInMonths,
23837
23827
  endOfMonth as endOfMonth8,
23838
23828
  format as format3,
23839
23829
  startOfMonth as startOfMonth10,
@@ -23863,22 +23853,22 @@ var getChartWindow = ({
23863
23853
  const today = startOfMonth10(Date.now());
23864
23854
  const yearAgo = sub2(today, { months: 11 });
23865
23855
  const current = startOfMonth10(new Date(currentYear, currentMonth - 1, 1));
23866
- if (differenceInMonths2(startOfMonth10(chartWindow.start), current) < 0 && differenceInMonths2(startOfMonth10(chartWindow.end), current) > 1) {
23856
+ if (differenceInMonths(startOfMonth10(chartWindow.start), current) < 0 && differenceInMonths(startOfMonth10(chartWindow.end), current) > 1) {
23867
23857
  return chartWindow;
23868
23858
  }
23869
- if (differenceInMonths2(startOfMonth10(chartWindow.start), current) === 0) {
23859
+ if (differenceInMonths(startOfMonth10(chartWindow.start), current) === 0) {
23870
23860
  return {
23871
23861
  start: startOfMonth10(sub2(current, { months: 1 })),
23872
23862
  end: endOfMonth8(add(current, { months: 11 }))
23873
23863
  };
23874
23864
  }
23875
- if (differenceInMonths2(endOfMonth8(chartWindow.end), endOfMonth8(current)) === 1 && differenceInMonths2(today, current) >= 1) {
23865
+ if (differenceInMonths(endOfMonth8(chartWindow.end), endOfMonth8(current)) === 1 && differenceInMonths(today, current) >= 1) {
23876
23866
  return {
23877
23867
  start: startOfMonth10(sub2(current, { months: 10 })),
23878
23868
  end: endOfMonth8(add(current, { months: 2 }))
23879
23869
  };
23880
23870
  }
23881
- if (differenceInMonths2(current, startOfMonth10(chartWindow.end)) === 0 && differenceInMonths2(current, startOfMonth10(today)) > 0) {
23871
+ if (differenceInMonths(current, startOfMonth10(chartWindow.end)) === 0 && differenceInMonths(current, startOfMonth10(today)) > 0) {
23882
23872
  return {
23883
23873
  start: startOfMonth10(sub2(current, { months: 11 })),
23884
23874
  end: endOfMonth8(add(current, { months: 1 }))
@@ -23896,7 +23886,7 @@ var getChartWindow = ({
23896
23886
  end: endOfMonth8(current)
23897
23887
  };
23898
23888
  }
23899
- if (differenceInMonths2(current, startOfMonth10(chartWindow.start)) < 0) {
23889
+ if (differenceInMonths(current, startOfMonth10(chartWindow.start)) < 0) {
23900
23890
  return {
23901
23891
  start: startOfMonth10(current),
23902
23892
  end: endOfMonth8(add(current, { months: 11 }))
@@ -24069,16 +24059,16 @@ var ProfitAndLossChart = ({
24069
24059
  }
24070
24060
  return x;
24071
24061
  })) == null ? void 0 : _a.filter(
24072
- (x) => differenceInMonths2(
24062
+ (x) => differenceInMonths(
24073
24063
  startOfMonth10(new Date(x.year, x.month - 1, 1)),
24074
24064
  chartWindow.start
24075
- ) >= 0 && differenceInMonths2(
24065
+ ) >= 0 && differenceInMonths(
24076
24066
  startOfMonth10(new Date(x.year, x.month - 1, 1)),
24077
24067
  chartWindow.start
24078
- ) < 12 && differenceInMonths2(
24068
+ ) < 12 && differenceInMonths(
24079
24069
  chartWindow.end,
24080
24070
  startOfMonth10(new Date(x.year, x.month - 1, 1))
24081
- ) >= 0 && differenceInMonths2(
24071
+ ) >= 0 && differenceInMonths(
24082
24072
  chartWindow.end,
24083
24073
  startOfMonth10(new Date(x.year, x.month - 1, 1))
24084
24074
  ) <= 12
@@ -24724,21 +24714,11 @@ function useGlobalDateRangePicker({ displayMode, setDisplayMode }) {
24724
24714
  setDisplayMode(newMode);
24725
24715
  }
24726
24716
  }, [setDisplayMode]);
24727
- const { dateFormat, dateOrDateRange } = useMemo39(() => {
24717
+ const dateOrDateRange = useMemo39(() => {
24728
24718
  if (displayMode === "monthPicker") {
24729
- return {
24730
- dateOrDateRange: start,
24731
- dateFormat: void 0
24732
- };
24719
+ return start;
24733
24720
  }
24734
- return {
24735
- /*
24736
- * This intentionally needs to be cast to a mutable array. The `DatePicker`
24737
- * component should accept a readonly array, but that refactor is out of scope.
24738
- */
24739
- dateOrDateRange: [start, end],
24740
- dateFormat: "MMM d"
24741
- };
24721
+ return [start, end];
24742
24722
  }, [
24743
24723
  start,
24744
24724
  end,
@@ -24747,10 +24727,9 @@ function useGlobalDateRangePicker({ displayMode, setDisplayMode }) {
24747
24727
  const onChangeDateOrDateRange = useCallback32((dates) => {
24748
24728
  var _a;
24749
24729
  const dateProps = dates instanceof Date ? { start: dates, end: dates } : { start: dates[0], end: (_a = dates[1]) != null ? _a : dates[0] };
24750
- setRangeWithExplicitDisplayMode(__spreadProps(__spreadValues({}, dateProps), { rangeDisplayMode: displayMode }));
24730
+ setRangeWithExplicitDisplayMode(__spreadProps(__spreadValues({}, dateProps), { displayMode }));
24751
24731
  }, [displayMode, setRangeWithExplicitDisplayMode]);
24752
24732
  return {
24753
- dateFormat,
24754
24733
  rangeDisplayMode: displayMode,
24755
24734
  onChangeMode,
24756
24735
  dateOrDateRange,
@@ -24768,24 +24747,24 @@ var ProfitAndLossDatePicker = ({
24768
24747
  const isMounted = useRef25(false);
24769
24748
  const { business } = useLayerContext();
24770
24749
  const displayMode = useReportModeWithFallback("ProfitAndLoss" /* ProfitAndLoss */, "monthPicker");
24750
+ const { resetPnLModeToDefaultOnMount } = useReportModeStore();
24771
24751
  const { setModeForReport } = useReportModeActions();
24772
24752
  const setDisplayMode = useCallback33((mode) => {
24773
24753
  setModeForReport("ProfitAndLoss" /* ProfitAndLoss */, mode);
24774
24754
  }, [setModeForReport]);
24775
24755
  useEffect27(() => {
24776
24756
  const initialDatePickerMode = getInitialDateRangePickerMode({ allowedDatePickerModes, defaultDatePickerMode });
24777
- if (!isMounted.current && displayMode !== initialDatePickerMode) {
24757
+ if (!isMounted.current && resetPnLModeToDefaultOnMount && displayMode !== initialDatePickerMode) {
24778
24758
  setDisplayMode(initialDatePickerMode);
24779
24759
  }
24780
24760
  isMounted.current = true;
24781
- }, [allowedDatePickerModes, defaultDatePickerMode, displayMode, setDisplayMode]);
24761
+ }, [resetPnLModeToDefaultOnMount, allowedDatePickerModes, defaultDatePickerMode, displayMode, setDisplayMode]);
24782
24762
  const cleanedAllowedModes = getAllowedDateRangePickerModes({ allowedDatePickerModes, defaultDatePickerMode });
24783
24763
  const {
24784
24764
  rangeDisplayMode,
24785
24765
  onChangeMode,
24786
24766
  dateOrDateRange,
24787
- onChangeDateOrDateRange,
24788
- dateFormat
24767
+ onChangeDateOrDateRange
24789
24768
  } = useGlobalDateRangePicker({ displayMode, setDisplayMode });
24790
24769
  const minDate = getEarliestDateToBrowse(business);
24791
24770
  return /* @__PURE__ */ jsx197(
@@ -24799,7 +24778,6 @@ var ProfitAndLossDatePicker = ({
24799
24778
  slots: {
24800
24779
  ModeSelector: DatePickerModeSelector
24801
24780
  },
24802
- dateFormat,
24803
24781
  customDateRanges,
24804
24782
  minDate
24805
24783
  }
@@ -26329,7 +26307,7 @@ var useTableExpandRow = () => {
26329
26307
  };
26330
26308
 
26331
26309
  // src/utils/profitAndLossComparisonUtils.ts
26332
- import { format as format5, subMonths as subMonths4, subYears as subYears4 } from "date-fns";
26310
+ import { format as format5, subMonths as subMonths3, subYears as subYears3 } from "date-fns";
26333
26311
  var generateComparisonPeriods = (startDate, numberOfPeriods, rangeDisplayMode) => {
26334
26312
  switch (rangeDisplayMode) {
26335
26313
  case "yearPicker":
@@ -26340,13 +26318,13 @@ var generateComparisonPeriods = (startDate, numberOfPeriods, rangeDisplayMode) =
26340
26318
  };
26341
26319
  var generateComparisonMonths = (startDate, numberOfMonths) => {
26342
26320
  return Array.from({ length: numberOfMonths }, (_, index) => {
26343
- const currentMonth = subMonths4(startDate, numberOfMonths - index - 1);
26321
+ const currentMonth = subMonths3(startDate, numberOfMonths - index - 1);
26344
26322
  return { date: currentMonth, label: format5(currentMonth, "MMM") };
26345
26323
  });
26346
26324
  };
26347
26325
  var generateComparisonYears = (startDate, numberOfYears) => {
26348
26326
  return Array.from({ length: numberOfYears }, (_, index) => {
26349
- const currentMonth = subYears4(startDate, numberOfYears - index - 1);
26327
+ const currentMonth = subYears3(startDate, numberOfYears - index - 1);
26350
26328
  return { date: currentMonth, label: format5(currentMonth, "yyyy") };
26351
26329
  });
26352
26330
  };
@@ -27550,7 +27528,6 @@ function StatementOfCashFlowDatePicker({
27550
27528
  setModeForReport("StatementOfCashFlows" /* StatementOfCashFlows */, mode);
27551
27529
  }, [setModeForReport]);
27552
27530
  const {
27553
- dateFormat,
27554
27531
  rangeDisplayMode,
27555
27532
  onChangeMode,
27556
27533
  dateOrDateRange,
@@ -27569,7 +27546,6 @@ function StatementOfCashFlowDatePicker({
27569
27546
  slots: {
27570
27547
  ModeSelector: DatePickerModeSelector
27571
27548
  },
27572
- dateFormat,
27573
27549
  customDateRanges,
27574
27550
  minDate
27575
27551
  }
@@ -29614,7 +29590,7 @@ var DetailsListItem = ({
29614
29590
  }) => {
29615
29591
  return /* @__PURE__ */ jsxs157("li", { className: "Layer__details-list-item", children: [
29616
29592
  /* @__PURE__ */ jsx249("label", { className: "Layer__details-list-item__label", children: label }),
29617
- /* @__PURE__ */ jsx249("span", { className: "Layer__details-list-item__value", children: isLoading ? /* @__PURE__ */ jsx249(SkeletonLoader, {}) : renderValue(children) })
29593
+ /* @__PURE__ */ jsx249("div", { className: "Layer__details-list-item__value", children: isLoading ? /* @__PURE__ */ jsx249(SkeletonLoader, {}) : renderValue(children) })
29618
29594
  ] });
29619
29595
  };
29620
29596
 
@@ -30734,7 +30710,10 @@ var JournalEntryDetails = () => {
30734
30710
  /* @__PURE__ */ jsxs161(
30735
30711
  DetailsList,
30736
30712
  {
30737
- title: `Journal Entry ${entry ? entryNumber(entry) : ""}`,
30713
+ title: /* @__PURE__ */ jsxs161(VStack, { children: [
30714
+ /* @__PURE__ */ jsx254(Span, { children: "Journal Entry" }),
30715
+ entry && /* @__PURE__ */ jsx254(Span, { variant: "subtle", size: "xs", children: `Journal ID #${entryNumber(entry)}` })
30716
+ ] }),
30738
30717
  className: "Layer__border-top",
30739
30718
  children: [
30740
30719
  /* @__PURE__ */ jsx254(DetailsListItem, { label: "Entry type", isLoading: isLoadingEntry, children: humanizeEnum((_c = entry == null ? void 0 : entry.entry_type) != null ? _c : "") }),
@@ -34548,7 +34527,6 @@ var BookkeepingOverview = ({
34548
34527
  {
34549
34528
  name: "bookkeeping-overview-profit-and-loss",
34550
34529
  asWidget: true,
34551
- elevated: true,
34552
34530
  style: {
34553
34531
  position: "relative",
34554
34532
  zIndex: 2
@@ -34686,7 +34664,6 @@ var AccountingOverview = ({
34686
34664
  {
34687
34665
  name: "accounting-overview-profit-and-loss",
34688
34666
  asWidget: true,
34689
- elevated: true,
34690
34667
  children: [
34691
34668
  /* @__PURE__ */ jsx301(
34692
34669
  ProfitAndLoss.Header,
@@ -34773,7 +34750,7 @@ var BankTransactionsWithLinkedAccounts = ({
34773
34750
  title,
34774
34751
  // deprecated
34775
34752
  showTitle = true,
34776
- elevatedLinkedAccounts = true,
34753
+ elevatedLinkedAccounts = false,
34777
34754
  mode,
34778
34755
  showBreakConnection = false,
34779
34756
  showCustomerVendor = false,
@@ -34784,7 +34761,6 @@ var BankTransactionsWithLinkedAccounts = ({
34784
34761
  showTooltips = false,
34785
34762
  showUnlinkItem = false,
34786
34763
  showUploadOptions = false,
34787
- showAddAccount = true,
34788
34764
  mobileComponent,
34789
34765
  stringOverrides
34790
34766
  }) => {
@@ -34801,7 +34777,6 @@ var BankTransactionsWithLinkedAccounts = ({
34801
34777
  showLedgerBalance,
34802
34778
  showUnlinkItem,
34803
34779
  showBreakConnection,
34804
- showAddAccount,
34805
34780
  stringOverrides: stringOverrides == null ? void 0 : stringOverrides.linkedAccounts
34806
34781
  }
34807
34782
  ),
@@ -36085,7 +36060,7 @@ var BillSummaryPaid = ({ bill }) => {
36085
36060
 
36086
36061
  // src/components/Bills/BillSummaryUnpaid.tsx
36087
36062
  import { useMemo as useMemo68 } from "react";
36088
- import { differenceInDays as differenceInDays3, parseISO as parseISO17 } from "date-fns";
36063
+ import { differenceInDays as differenceInDays2, parseISO as parseISO17 } from "date-fns";
36089
36064
  import { jsx as jsx313, jsxs as jsxs202 } from "react/jsx-runtime";
36090
36065
  function buildDifference(due_at) {
36091
36066
  const d = parseISO17(due_at).setHours(0, 0, 0, 0);
@@ -36093,7 +36068,7 @@ function buildDifference(due_at) {
36093
36068
  return { text: "" };
36094
36069
  }
36095
36070
  const today = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0);
36096
- const daysDiff = differenceInDays3(today, d);
36071
+ const daysDiff = differenceInDays2(today, d);
36097
36072
  if (daysDiff === 0) {
36098
36073
  return {
36099
36074
  text: "Due today",
@@ -36512,7 +36487,7 @@ import { Fragment as Fragment53 } from "react";
36512
36487
 
36513
36488
  // src/components/DueStatus/DueStatus.tsx
36514
36489
  import { useMemo as useMemo69 } from "react";
36515
- import { parseISO as parseISO19, differenceInDays as differenceInDays4 } from "date-fns";
36490
+ import { parseISO as parseISO19, differenceInDays as differenceInDays3 } from "date-fns";
36516
36491
  import { jsx as jsx316, jsxs as jsxs204 } from "react/jsx-runtime";
36517
36492
  var dueStatusTitle = (daysDiff, paid) => {
36518
36493
  if (paid && daysDiff > 0) {
@@ -36573,7 +36548,7 @@ var getDiff = (refDate) => {
36573
36548
  return null;
36574
36549
  }
36575
36550
  const today = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0);
36576
- return differenceInDays4(today, d);
36551
+ return differenceInDays3(today, d);
36577
36552
  };
36578
36553
  var DueStatus = ({ dueDate, paidAt, size = "md" }) => {
36579
36554
  const date = useMemo69(() => {
@@ -37156,7 +37131,7 @@ var Reports = ({
37156
37131
  onChange: (opt) => setActiveTab(opt.target.value)
37157
37132
  }
37158
37133
  ) }),
37159
- /* @__PURE__ */ jsx324(Container, { name: "reports", ref: containerRef, children: /* @__PURE__ */ jsx324(ReportsModeStoreProvider, { initialModes, children: /* @__PURE__ */ jsx324(ProfitAndLoss, { asContainer: false, comparisonConfig, withReportsModeProvider: false, children: /* @__PURE__ */ jsx324(
37134
+ /* @__PURE__ */ jsx324(Container, { name: "reports", ref: containerRef, children: /* @__PURE__ */ jsx324(ReportsModeStoreProvider, { initialModes, resetPnLModeToDefaultOnMount: false, children: /* @__PURE__ */ jsx324(ProfitAndLoss, { asContainer: false, comparisonConfig, withReportsModeProvider: false, children: /* @__PURE__ */ jsx324(
37160
37135
  ReportsPanel,
37161
37136
  {
37162
37137
  openReport: activeTab,
@@ -37292,31 +37267,345 @@ var Components = ({
37292
37267
  ] });
37293
37268
  };
37294
37269
 
37295
- // src/components/Invoices/InvoicesTable.tsx
37296
- import { useCallback as useCallback50, useMemo as useMemo74, useState as useState83 } from "react";
37270
+ // src/components/Invoices/Invoices.tsx
37271
+ import { useCallback as useCallback58, useState as useState87 } from "react";
37272
+
37273
+ // src/components/Invoices/InvoiceDetail/InvoiceDetail.tsx
37274
+ import { useCallback as useCallback54 } from "react";
37275
+
37276
+ // src/components/BaseDetailView/BaseDetailView.tsx
37277
+ import { jsx as jsx326, jsxs as jsxs210 } from "react/jsx-runtime";
37278
+ var BaseDetailView = ({ name, onGoBack, slots, children }) => {
37279
+ const { Header: Header6 } = slots;
37280
+ return /* @__PURE__ */ jsxs210(Container, { name, className: "Layer__BaseDetailView", children: [
37281
+ /* @__PURE__ */ jsxs210(HStack, { align: "center", gap: "md", className: "Layer__BaseDetailView__Header", children: [
37282
+ /* @__PURE__ */ jsx326(Button2, { variant: "outlined", icon: true, onPress: onGoBack, children: /* @__PURE__ */ jsx326(BackArrow_default, {}) }),
37283
+ /* @__PURE__ */ jsx326(Header6, {})
37284
+ ] }),
37285
+ children
37286
+ ] });
37287
+ };
37297
37288
 
37298
- // src/features/invoices/api/useListInvoices.tsx
37299
- import useSWRInfinite7 from "swr/infinite";
37300
- var import_lodash6 = __toESM(require_lodash2());
37301
- import { useCallback as useCallback48, useMemo as useMemo71 } from "react";
37302
- import { Schema as Schema11 } from "effect";
37289
+ // src/components/Invoices/InvoiceForm/useInvoiceForm.ts
37290
+ import { useState as useState84 } from "react";
37291
+ import { useStore as useStore7 } from "@tanstack/react-form";
37303
37292
 
37304
- // src/types/utility/pagination.ts
37305
- import { Schema as Schema9, pipe as pipe5 } from "effect";
37306
- var PaginatedResponseMetaSchema = Schema9.Struct({
37307
- cursor: Schema9.NullOr(Schema9.String),
37308
- hasMore: pipe5(
37309
- Schema9.propertySignature(Schema9.Boolean),
37310
- Schema9.fromKey("has_more")
37311
- ),
37312
- totalCount: pipe5(
37313
- Schema9.propertySignature(Schema9.UndefinedOr(Schema9.Number)),
37314
- Schema9.fromKey("total_count")
37315
- )
37293
+ // src/features/forms/hooks/useForm.tsx
37294
+ import { createFormHookContexts, createFormHook } from "@tanstack/react-form";
37295
+
37296
+ // src/components/ui/Form/Form.tsx
37297
+ import { forwardRef as forwardRef20 } from "react";
37298
+ import {
37299
+ Form as ReactAriaForm,
37300
+ TextField as ReactAriaTextField,
37301
+ FieldError as ReactAriaFieldError
37302
+ } from "react-aria-components";
37303
+ import classNames88 from "classnames";
37304
+ import { jsx as jsx327 } from "react/jsx-runtime";
37305
+ var FORM_CLASS_NAME = "Layer__UI__Form";
37306
+ var Form = forwardRef20(
37307
+ function Form2(_a, ref) {
37308
+ var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37309
+ return /* @__PURE__ */ jsx327(ReactAriaForm, __spreadProps(__spreadValues({}, restProps), { className: classNames88(FORM_CLASS_NAME, className), ref, children }));
37310
+ }
37311
+ );
37312
+ var TEXT_FIELD_CLASS_NAME = "Layer__UI__TextField";
37313
+ var TextField = forwardRef20(
37314
+ function TextField2(_a, ref) {
37315
+ var _b = _a, { children, inline, textarea, className } = _b, restProps = __objRest(_b, ["children", "inline", "textarea", "className"]);
37316
+ const dataProperties = toDataProperties({ inline, textarea });
37317
+ return /* @__PURE__ */ jsx327(ReactAriaTextField, __spreadProps(__spreadValues(__spreadValues({}, restProps), dataProperties), { className: classNames88(TEXT_FIELD_CLASS_NAME, className), ref, children: withRenderProp(children, (node) => node) }));
37318
+ }
37319
+ );
37320
+ var FIELD_ERROR_CLASS_NAME = "Layer__UI__FieldError";
37321
+ var FieldError = forwardRef20(
37322
+ function FieldError2({ children }, ref) {
37323
+ return /* @__PURE__ */ jsx327(ReactAriaFieldError, { className: FIELD_ERROR_CLASS_NAME, ref, children: withRenderProp(children, (node) => node) });
37324
+ }
37325
+ );
37326
+
37327
+ // src/features/forms/components/BaseFormTextField.tsx
37328
+ import { jsx as jsx328, jsxs as jsxs211 } from "react/jsx-runtime";
37329
+ function BaseFormTextField({
37330
+ label,
37331
+ className,
37332
+ inline = false,
37333
+ showLabel = true,
37334
+ showFieldError = true,
37335
+ isTextArea = false,
37336
+ children
37337
+ }) {
37338
+ const field = useFieldContext();
37339
+ const { name, state } = field;
37340
+ const { meta } = state;
37341
+ const { errors, isValid: isValid2 } = meta;
37342
+ const errorMessage = errors.length !== 0 ? errors[0] : void 0;
37343
+ const shouldShowErrorMessage = showFieldError && errorMessage;
37344
+ const additionalAriaProps = !showLabel && { "aria-label": label };
37345
+ return /* @__PURE__ */ jsxs211(TextField, __spreadProps(__spreadValues({ name, isInvalid: !isValid2, inline, className, textarea: isTextArea }, additionalAriaProps), { children: [
37346
+ showLabel && /* @__PURE__ */ jsx328(Label, __spreadProps(__spreadValues({ size: "sm", htmlFor: name }, !inline && { pbe: "3xs" }), { children: label })),
37347
+ children,
37348
+ shouldShowErrorMessage && /* @__PURE__ */ jsx328(FieldError, { children: errorMessage })
37349
+ ] }));
37350
+ }
37351
+
37352
+ // src/features/forms/components/FormBigDecimalField.tsx
37353
+ import { useCallback as useCallback48, useEffect as useEffect41, useMemo as useMemo71, useState as useState82 } from "react";
37354
+
37355
+ // src/components/ui/Input/InputGroup.tsx
37356
+ import { forwardRef as forwardRef21 } from "react";
37357
+ import {
37358
+ Group as ReactAriaGroup
37359
+ } from "react-aria-components";
37360
+ import { jsx as jsx329 } from "react/jsx-runtime";
37361
+ var INPUT_GROUP_CLASS_NAME = "Layer__InputGroup";
37362
+ var InputGroup2 = forwardRef21(
37363
+ function InputGroup3(_a, ref) {
37364
+ var _b = _a, { actionCount } = _b, restProps = __objRest(_b, ["actionCount"]);
37365
+ const dataProperties = toDataProperties({ "action-count": actionCount });
37366
+ return /* @__PURE__ */ jsx329(
37367
+ ReactAriaGroup,
37368
+ __spreadProps(__spreadValues(__spreadValues({}, restProps), dataProperties), {
37369
+ className: INPUT_GROUP_CLASS_NAME,
37370
+ ref
37371
+ })
37372
+ );
37373
+ }
37374
+ );
37375
+
37376
+ // src/features/forms/components/FormBigDecimalField.tsx
37377
+ import { BigDecimal as BD2, Option as Option4 } from "effect";
37378
+
37379
+ // src/components/ui/Input/Input.tsx
37380
+ import { forwardRef as forwardRef22 } from "react";
37381
+ import { Input as ReactAriaInput2 } from "react-aria-components";
37382
+ import { jsx as jsx330 } from "react/jsx-runtime";
37383
+ var INPUT_CLASS_NAME = "Layer__UI__Input";
37384
+ var Input2 = forwardRef22(
37385
+ function Input3(_a, ref) {
37386
+ var _b = _a, { inset, placement } = _b, restProps = __objRest(_b, ["inset", "placement"]);
37387
+ const dataProperties = toDataProperties({ inset, placement });
37388
+ return /* @__PURE__ */ jsx330(
37389
+ ReactAriaInput2,
37390
+ __spreadProps(__spreadValues(__spreadValues({}, restProps), dataProperties), {
37391
+ className: INPUT_CLASS_NAME,
37392
+ ref
37393
+ })
37394
+ );
37395
+ }
37396
+ );
37397
+
37398
+ // src/utils/bigDecimalUtils.ts
37399
+ import { BigDecimal as BD } from "effect";
37400
+ var BIG_DECIMAL_ZERO = BD.fromBigInt(BigInt(0));
37401
+ var BIG_DECIMAL_ONE = BD.fromBigInt(BigInt(1));
37402
+ var BIG_DECIMAL_ONE_HUNDRED = BD.fromBigInt(BigInt(100));
37403
+ var DECIMAL_CHARS_REGEX = /^[\d.,-]+$/;
37404
+ var NON_NEGATIVE_DECIMAL_CHARS_REGEX = /^[\d.,]+$/;
37405
+ var convertBigDecimalToCents = (amount) => {
37406
+ const scaled = BD.multiply(amount, BIG_DECIMAL_ONE_HUNDRED);
37407
+ const rounded = BD.round(scaled, { scale: 0 });
37408
+ return Number(rounded.value);
37409
+ };
37410
+ var convertCentsToBigDecimal = (cents) => {
37411
+ const decimalCents = BD.fromBigInt(BigInt(cents));
37412
+ return BD.unsafeDivide(decimalCents, BIG_DECIMAL_ONE_HUNDRED);
37413
+ };
37414
+ function formatBigDecimalToString(value, maxDecimalPlaces = 10) {
37415
+ const normalizedBigDecimal = BD.normalize(value);
37416
+ const formatter2 = new Intl.NumberFormat(
37417
+ "en-US",
37418
+ {
37419
+ minimumFractionDigits: 0,
37420
+ maximumFractionDigits: maxDecimalPlaces
37421
+ }
37422
+ );
37423
+ let decimalAsNumber = 0;
37424
+ try {
37425
+ decimalAsNumber = BD.unsafeToNumber(normalizedBigDecimal);
37426
+ } catch (e) {
37427
+ }
37428
+ return formatter2.format(decimalAsNumber);
37429
+ }
37430
+
37431
+ // src/features/forms/components/FormBigDecimalField.tsx
37432
+ import { jsx as jsx331 } from "react/jsx-runtime";
37433
+ var DEFAULT_MAX_INPUT_LENGTH = 10;
37434
+ function FormBigDecimalField({
37435
+ slotProps,
37436
+ maxInputLength = DEFAULT_MAX_INPUT_LENGTH,
37437
+ allowNegative = false
37438
+ }) {
37439
+ const field = useFieldContext();
37440
+ const { name, state, handleChange, handleBlur } = field;
37441
+ const { value } = state;
37442
+ const [inputValue, setInputValue] = useState82(formatBigDecimalToString(value, maxInputLength));
37443
+ const onInputChange = useCallback48((e) => {
37444
+ setInputValue(e.target.value);
37445
+ }, []);
37446
+ const onInputBlur = useCallback48(() => {
37447
+ const cleaned = inputValue.replace(/,/g, "");
37448
+ const maybeDecimal = BD2.fromString(cleaned);
37449
+ const decimal = Option4.match(maybeDecimal, {
37450
+ onNone: () => BIG_DECIMAL_ZERO,
37451
+ onSome: (amount) => amount
37452
+ });
37453
+ const normalizedDecimal = BD2.normalize(decimal);
37454
+ handleChange(normalizedDecimal);
37455
+ handleBlur();
37456
+ setInputValue(formatBigDecimalToString(normalizedDecimal, maxInputLength));
37457
+ }, [inputValue, handleBlur, handleChange, maxInputLength]);
37458
+ const allowedChars = useMemo71(
37459
+ () => allowNegative ? DECIMAL_CHARS_REGEX : NON_NEGATIVE_DECIMAL_CHARS_REGEX,
37460
+ [allowNegative]
37461
+ );
37462
+ const onBeforeInput = useCallback48((e) => {
37463
+ if (e.data && !allowedChars.test(e.data)) {
37464
+ e.preventDefault();
37465
+ }
37466
+ }, [allowedChars]);
37467
+ const onPaste = useCallback48((e) => {
37468
+ const pastedText = e.clipboardData.getData("text");
37469
+ if (!allowedChars.test(pastedText)) {
37470
+ e.preventDefault();
37471
+ }
37472
+ }, [allowedChars]);
37473
+ useEffect41(() => {
37474
+ setInputValue(formatBigDecimalToString(value, maxInputLength));
37475
+ }, [value, maxInputLength]);
37476
+ return /* @__PURE__ */ jsx331(BaseFormTextField, __spreadProps(__spreadValues({}, slotProps.BaseFormTextField), { inputMode: "decimal", children: /* @__PURE__ */ jsx331(InputGroup2, { children: /* @__PURE__ */ jsx331(
37477
+ Input2,
37478
+ {
37479
+ inset: true,
37480
+ id: name,
37481
+ name,
37482
+ value: inputValue,
37483
+ onChange: onInputChange,
37484
+ onBlur: onInputBlur,
37485
+ maxLength: maxInputLength,
37486
+ onBeforeInput,
37487
+ onPaste
37488
+ }
37489
+ ) }) }));
37490
+ }
37491
+
37492
+ // src/features/forms/components/FormCurrencyField.tsx
37493
+ import { useCallback as useCallback49, useEffect as useEffect42, useState as useState83 } from "react";
37494
+ import CurrencyInput2 from "react-currency-input-field";
37495
+ import { BigDecimal as BD3, Option as Option5 } from "effect";
37496
+ import { jsx as jsx332 } from "react/jsx-runtime";
37497
+ var ZERO_CENTS_INPUT_VALUE = "0.00";
37498
+ var getCurrencyInputValueFromCents = (cents) => !Number.isNaN(cents) ? centsToDollarsWithoutCommas(cents) : ZERO_CENTS_INPUT_VALUE;
37499
+ function FormCurrencyField({ slotProps }) {
37500
+ const field = useFieldContext();
37501
+ const label = slotProps.BaseFormTextField.label;
37502
+ const { name, state, handleChange, handleBlur } = field;
37503
+ const { value } = state;
37504
+ const [inputValue, setInputValue] = useState83(getCurrencyInputValueFromCents(value));
37505
+ const onInputChange = useCallback49((newValue) => {
37506
+ setInputValue(newValue != null ? newValue : ZERO_CENTS_INPUT_VALUE);
37507
+ }, []);
37508
+ const onInputBlur = useCallback49(() => {
37509
+ const maybeAmount = BD3.fromString(inputValue);
37510
+ const cents = Option5.match(maybeAmount, {
37511
+ onNone: () => 0,
37512
+ onSome: (amount) => convertBigDecimalToCents(amount)
37513
+ });
37514
+ handleChange(cents);
37515
+ handleBlur();
37516
+ setInputValue(getCurrencyInputValueFromCents(cents));
37517
+ }, [inputValue, handleChange, handleBlur]);
37518
+ useEffect42(() => {
37519
+ setInputValue(getCurrencyInputValueFromCents(value));
37520
+ }, [value]);
37521
+ return /* @__PURE__ */ jsx332(BaseFormTextField, __spreadProps(__spreadValues({}, slotProps.BaseFormTextField), { children: /* @__PURE__ */ jsx332(InputGroup2, { children: /* @__PURE__ */ jsx332(
37522
+ CurrencyInput2,
37523
+ {
37524
+ name,
37525
+ intlConfig: {
37526
+ locale: "en-US",
37527
+ currency: "USD"
37528
+ },
37529
+ prefix: "$",
37530
+ decimalScale: 2,
37531
+ decimalsLimit: 2,
37532
+ disableAbbreviations: true,
37533
+ value: inputValue,
37534
+ onValueChange: onInputChange,
37535
+ onBlur: onInputBlur,
37536
+ className: "Layer__UI__Input",
37537
+ "data-inset": "true",
37538
+ "aria-label": label
37539
+ }
37540
+ ) }) }));
37541
+ }
37542
+
37543
+ // src/features/forms/components/FormTextAreaField.tsx
37544
+ import { useCallback as useCallback50 } from "react";
37545
+
37546
+ // src/components/ui/Input/TextArea.tsx
37547
+ import { forwardRef as forwardRef23 } from "react";
37548
+ import { TextArea as ReactAriaTextArea } from "react-aria-components";
37549
+ import { jsx as jsx333 } from "react/jsx-runtime";
37550
+ var TEXTAREA_CLASS_NAME = "Layer__UI__TextArea";
37551
+ var TextArea = forwardRef23(
37552
+ function TextArea2(_a, ref) {
37553
+ var _b = _a, { resize = "none" } = _b, restProps = __objRest(_b, ["resize"]);
37554
+ const dataProperties = toDataProperties({ resize });
37555
+ return /* @__PURE__ */ jsx333(
37556
+ ReactAriaTextArea,
37557
+ __spreadProps(__spreadValues(__spreadValues({}, restProps), dataProperties), {
37558
+ className: TEXTAREA_CLASS_NAME,
37559
+ ref
37560
+ })
37561
+ );
37562
+ }
37563
+ );
37564
+
37565
+ // src/features/forms/components/FormTextAreaField.tsx
37566
+ import { jsx as jsx334 } from "react/jsx-runtime";
37567
+ function FormTextAreaField({ slotProps }) {
37568
+ const field = useFieldContext();
37569
+ const { name, state, handleChange, handleBlur } = field;
37570
+ const { value } = state;
37571
+ const onChange = useCallback50((e) => {
37572
+ handleChange(e.target.value);
37573
+ }, [handleChange]);
37574
+ return /* @__PURE__ */ jsx334(BaseFormTextField, __spreadProps(__spreadValues({}, slotProps.BaseFormTextField), { children: /* @__PURE__ */ jsx334(TextArea, { id: name, name, value, onChange, onBlur: handleBlur }) }));
37575
+ }
37576
+
37577
+ // src/features/forms/components/FormTextField.tsx
37578
+ import { useCallback as useCallback51 } from "react";
37579
+ import { jsx as jsx335 } from "react/jsx-runtime";
37580
+ function FormTextField({ slotProps }) {
37581
+ const field = useFieldContext();
37582
+ const { name, state, handleChange, handleBlur } = field;
37583
+ const { value } = state;
37584
+ const onChange = useCallback51((e) => {
37585
+ handleChange(e.target.value);
37586
+ }, [handleChange]);
37587
+ return /* @__PURE__ */ jsx335(BaseFormTextField, __spreadProps(__spreadValues({}, slotProps.BaseFormTextField), { children: /* @__PURE__ */ jsx335(InputGroup2, { children: /* @__PURE__ */ jsx335(Input2, { inset: true, id: name, name, value, onChange, onBlur: handleBlur }) }) }));
37588
+ }
37589
+
37590
+ // src/features/forms/hooks/useForm.tsx
37591
+ var { fieldContext, useFieldContext, formContext, useFormContext } = createFormHookContexts();
37592
+ var { useAppForm, withForm } = createFormHook({
37593
+ fieldComponents: {
37594
+ BaseFormTextField,
37595
+ FormBigDecimalField,
37596
+ FormCurrencyField,
37597
+ FormTextAreaField,
37598
+ FormTextField
37599
+ },
37600
+ formComponents: {
37601
+ // TODO: define a submit button component
37602
+ },
37603
+ fieldContext,
37604
+ formContext
37316
37605
  });
37317
37606
 
37318
37607
  // src/features/invoices/invoiceSchemas.ts
37319
- import { Schema as Schema10, pipe as pipe6 } from "effect";
37608
+ import { Schema as Schema9, pipe as pipe5 } from "effect";
37320
37609
  var InvoiceStatus = /* @__PURE__ */ ((InvoiceStatus3) => {
37321
37610
  InvoiceStatus3["Voided"] = "VOIDED";
37322
37611
  InvoiceStatus3["Paid"] = "PAID";
@@ -37326,10 +37615,10 @@ var InvoiceStatus = /* @__PURE__ */ ((InvoiceStatus3) => {
37326
37615
  InvoiceStatus3["Sent"] = "SENT";
37327
37616
  return InvoiceStatus3;
37328
37617
  })(InvoiceStatus || {});
37329
- var InvoiceStatusSchema = Schema10.Enums(InvoiceStatus);
37330
- var TransformedInvoiceStatusSchema = Schema10.transform(
37331
- Schema10.NonEmptyTrimmedString,
37332
- Schema10.typeSchema(InvoiceStatusSchema),
37618
+ var InvoiceStatusSchema = Schema9.Enums(InvoiceStatus);
37619
+ var TransformedInvoiceStatusSchema = Schema9.transform(
37620
+ Schema9.NonEmptyTrimmedString,
37621
+ Schema9.typeSchema(InvoiceStatusSchema),
37333
37622
  {
37334
37623
  decode: (input) => {
37335
37624
  if (Object.values(InvoiceStatusSchema.enums).includes(input)) {
@@ -37340,163 +37629,685 @@ var TransformedInvoiceStatusSchema = Schema10.transform(
37340
37629
  encode: (input) => input
37341
37630
  }
37342
37631
  );
37343
- var InvoiceLineItemSchema = Schema10.Struct({
37344
- id: Schema10.UUID,
37345
- externalId: pipe6(
37346
- Schema10.propertySignature(Schema10.NullOr(Schema10.String)),
37347
- Schema10.fromKey("external_id")
37632
+ var InvoiceLineItemSchema = Schema9.Struct({
37633
+ id: Schema9.UUID,
37634
+ externalId: pipe5(
37635
+ Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
37636
+ Schema9.fromKey("external_id")
37348
37637
  ),
37349
- invoiceId: pipe6(
37350
- Schema10.propertySignature(Schema10.UUID),
37351
- Schema10.fromKey("invoice_id")
37638
+ invoiceId: pipe5(
37639
+ Schema9.propertySignature(Schema9.UUID),
37640
+ Schema9.fromKey("invoice_id")
37352
37641
  ),
37353
- description: Schema10.NullOr(Schema10.String),
37354
- product: Schema10.NullOr(Schema10.String),
37355
- unitPrice: pipe6(
37356
- Schema10.propertySignature(Schema10.Number),
37357
- Schema10.fromKey("unit_price")
37642
+ description: Schema9.NullOr(Schema9.String),
37643
+ product: Schema9.NullOr(Schema9.String),
37644
+ unitPrice: pipe5(
37645
+ Schema9.propertySignature(Schema9.Number),
37646
+ Schema9.fromKey("unit_price")
37358
37647
  ),
37359
- quantity: Schema10.BigDecimal,
37360
- subtotal: Schema10.Number,
37361
- discountAmount: pipe6(
37362
- Schema10.propertySignature(Schema10.Number),
37363
- Schema10.fromKey("discount_amount")
37648
+ quantity: Schema9.BigDecimal,
37649
+ subtotal: Schema9.Number,
37650
+ discountAmount: pipe5(
37651
+ Schema9.propertySignature(Schema9.Number),
37652
+ Schema9.fromKey("discount_amount")
37364
37653
  ),
37365
- salesTaxTotal: pipe6(
37366
- Schema10.propertySignature(Schema10.Number),
37367
- Schema10.fromKey("sales_taxes_total")
37654
+ salesTaxTotal: pipe5(
37655
+ Schema9.propertySignature(Schema9.Number),
37656
+ Schema9.fromKey("sales_taxes_total")
37368
37657
  ),
37369
- totalAmount: pipe6(
37370
- Schema10.propertySignature(Schema10.Number),
37371
- Schema10.fromKey("total_amount")
37658
+ totalAmount: pipe5(
37659
+ Schema9.propertySignature(Schema9.Number),
37660
+ Schema9.fromKey("total_amount")
37372
37661
  ),
37373
- memo: Schema10.NullOr(Schema10.String)
37662
+ memo: Schema9.NullOr(Schema9.String)
37374
37663
  });
37375
- var InvoiceSchema = Schema10.Struct({
37376
- id: Schema10.UUID,
37377
- businessId: pipe6(
37378
- Schema10.propertySignature(Schema10.UUID),
37379
- Schema10.fromKey("business_id")
37664
+ var InvoiceSchema = Schema9.Struct({
37665
+ id: Schema9.UUID,
37666
+ businessId: pipe5(
37667
+ Schema9.propertySignature(Schema9.UUID),
37668
+ Schema9.fromKey("business_id")
37380
37669
  ),
37381
- externalId: pipe6(
37382
- Schema10.propertySignature(Schema10.NullOr(Schema10.String)),
37383
- Schema10.fromKey("external_id")
37670
+ externalId: pipe5(
37671
+ Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
37672
+ Schema9.fromKey("external_id")
37384
37673
  ),
37385
37674
  status: TransformedInvoiceStatusSchema,
37386
- sentAt: pipe6(
37387
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37388
- Schema10.fromKey("sent_at")
37675
+ sentAt: pipe5(
37676
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37677
+ Schema9.fromKey("sent_at")
37389
37678
  ),
37390
- dueAt: pipe6(
37391
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37392
- Schema10.fromKey("due_at")
37679
+ dueAt: pipe5(
37680
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37681
+ Schema9.fromKey("due_at")
37393
37682
  ),
37394
- paidAt: pipe6(
37395
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37396
- Schema10.fromKey("paid_at")
37683
+ paidAt: pipe5(
37684
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37685
+ Schema9.fromKey("paid_at")
37397
37686
  ),
37398
- voidedAt: pipe6(
37399
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37400
- Schema10.fromKey("voided_at")
37687
+ voidedAt: pipe5(
37688
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37689
+ Schema9.fromKey("voided_at")
37401
37690
  ),
37402
- invoiceNumber: pipe6(
37403
- Schema10.propertySignature(Schema10.NullOr(Schema10.String)),
37404
- Schema10.fromKey("invoice_number")
37691
+ invoiceNumber: pipe5(
37692
+ Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
37693
+ Schema9.fromKey("invoice_number")
37405
37694
  ),
37406
- recipientName: pipe6(
37407
- Schema10.propertySignature(Schema10.NullOr(Schema10.String)),
37408
- Schema10.fromKey("recipient_name")
37695
+ recipientName: pipe5(
37696
+ Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
37697
+ Schema9.fromKey("recipient_name")
37409
37698
  ),
37410
- customer: Schema10.NullOr(CustomerSchema),
37411
- lineItems: pipe6(
37412
- Schema10.propertySignature(Schema10.Array(InvoiceLineItemSchema)),
37413
- Schema10.fromKey("line_items")
37699
+ customer: Schema9.NullOr(CustomerSchema),
37700
+ lineItems: pipe5(
37701
+ Schema9.propertySignature(Schema9.Array(InvoiceLineItemSchema)),
37702
+ Schema9.fromKey("line_items")
37414
37703
  ),
37415
- subtotal: Schema10.Number,
37416
- additionalDiscount: pipe6(
37417
- Schema10.propertySignature(Schema10.Number),
37418
- Schema10.fromKey("additional_discount")
37704
+ subtotal: Schema9.Number,
37705
+ additionalDiscount: pipe5(
37706
+ Schema9.propertySignature(Schema9.Number),
37707
+ Schema9.fromKey("additional_discount")
37419
37708
  ),
37420
- additionalSalesTaxesTotal: pipe6(
37421
- Schema10.propertySignature(Schema10.Number),
37422
- Schema10.fromKey("additional_sales_taxes_total")
37709
+ additionalSalesTaxesTotal: pipe5(
37710
+ Schema9.propertySignature(Schema9.Number),
37711
+ Schema9.fromKey("additional_sales_taxes_total")
37423
37712
  ),
37424
- totalAmount: pipe6(
37425
- Schema10.propertySignature(Schema10.Number),
37426
- Schema10.fromKey("total_amount")
37713
+ totalAmount: pipe5(
37714
+ Schema9.propertySignature(Schema9.Number),
37715
+ Schema9.fromKey("total_amount")
37427
37716
  ),
37428
- outstandingBalance: pipe6(
37429
- Schema10.propertySignature(Schema10.Number),
37430
- Schema10.fromKey("outstanding_balance")
37717
+ outstandingBalance: pipe5(
37718
+ Schema9.propertySignature(Schema9.Number),
37719
+ Schema9.fromKey("outstanding_balance")
37431
37720
  ),
37432
- importedAt: pipe6(
37433
- Schema10.propertySignature(Schema10.Date),
37434
- Schema10.fromKey("imported_at")
37721
+ importedAt: pipe5(
37722
+ Schema9.propertySignature(Schema9.Date),
37723
+ Schema9.fromKey("imported_at")
37435
37724
  ),
37436
- updatedAt: pipe6(
37437
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37438
- Schema10.fromKey("updated_at")
37725
+ updatedAt: pipe5(
37726
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37727
+ Schema9.fromKey("updated_at")
37439
37728
  ),
37440
- memo: Schema10.NullOr(Schema10.String)
37729
+ memo: Schema9.NullOr(Schema9.String)
37441
37730
  });
37442
- var UpsertInvoiceTaxLineItemSchema = Schema10.Struct({
37443
- amount: Schema10.NumberFromString.pipe(Schema10.int())
37731
+ var UpsertInvoiceTaxLineItemSchema = Schema9.Struct({
37732
+ amount: Schema9.Number
37444
37733
  });
37445
- var UpsertInvoiceLineItemSchema = Schema10.Struct({
37446
- description: pipe6(
37447
- Schema10.propertySignature(Schema10.UndefinedOr(Schema10.String)),
37448
- Schema10.fromKey("description")
37449
- ),
37450
- product: pipe6(
37451
- Schema10.propertySignature(Schema10.String),
37452
- Schema10.fromKey("product")
37453
- ),
37454
- unitPrice: pipe6(
37455
- Schema10.propertySignature(Schema10.NumberFromString.pipe(Schema10.int())),
37456
- Schema10.fromKey("unit_price")
37734
+ var UpsertInvoiceLineItemSchema = Schema9.Struct({
37735
+ description: Schema9.String,
37736
+ product: Schema9.String,
37737
+ unitPrice: pipe5(
37738
+ Schema9.propertySignature(Schema9.Number),
37739
+ Schema9.fromKey("unit_price")
37457
37740
  ),
37458
- quantity: pipe6(
37459
- Schema10.propertySignature(Schema10.BigDecimal),
37460
- Schema10.fromKey("quantity")
37461
- )
37741
+ quantity: Schema9.BigDecimal
37462
37742
  });
37463
- var UpsertInvoiceSchema = Schema10.Struct({
37464
- sentAt: pipe6(
37465
- Schema10.propertySignature(Schema10.Date),
37466
- Schema10.fromKey("sent_at")
37743
+ var UpsertInvoiceSchema = Schema9.Struct({
37744
+ sentAt: pipe5(
37745
+ Schema9.propertySignature(Schema9.Date),
37746
+ Schema9.fromKey("sent_at")
37747
+ ),
37748
+ dueAt: pipe5(
37749
+ Schema9.propertySignature(Schema9.Date),
37750
+ Schema9.fromKey("due_at")
37467
37751
  ),
37468
- dueAt: pipe6(
37469
- Schema10.propertySignature(Schema10.Date),
37470
- Schema10.fromKey("due_at")
37752
+ invoiceNumber: pipe5(
37753
+ Schema9.propertySignature(Schema9.UndefinedOr(Schema9.String)),
37754
+ Schema9.fromKey("invoice_number")
37471
37755
  ),
37472
- invoiceNumber: pipe6(
37473
- Schema10.propertySignature(Schema10.UndefinedOr(Schema10.String)),
37474
- Schema10.fromKey("invoice_number")
37756
+ customerId: pipe5(
37757
+ Schema9.propertySignature(Schema9.UUID),
37758
+ Schema9.fromKey("customer_id")
37475
37759
  ),
37476
- customerId: pipe6(
37477
- Schema10.propertySignature(Schema10.UUID),
37478
- Schema10.fromKey("customer_id")
37760
+ memo: Schema9.NullOr(Schema9.String),
37761
+ lineItems: pipe5(
37762
+ Schema9.propertySignature(Schema9.Array(UpsertInvoiceLineItemSchema)),
37763
+ Schema9.fromKey("line_items")
37479
37764
  ),
37480
- memo: Schema10.NullOr(Schema10.String),
37481
- lineItems: pipe6(
37482
- Schema10.propertySignature(Schema10.Array(UpsertInvoiceLineItemSchema)),
37483
- Schema10.fromKey("line_items")
37765
+ additionalDiscount: pipe5(
37766
+ Schema9.propertySignature(Schema9.UndefinedOr(Schema9.Number)),
37767
+ Schema9.fromKey("additional_discount")
37484
37768
  ),
37485
- additionalDiscount: pipe6(
37486
- Schema10.propertySignature(Schema10.UndefinedOr(Schema10.NumberFromString.pipe(Schema10.int()))),
37487
- Schema10.fromKey("additional_discount")
37769
+ additionalSalesTaxes: pipe5(
37770
+ Schema9.propertySignature(Schema9.UndefinedOr(Schema9.Array(UpsertInvoiceTaxLineItemSchema))),
37771
+ Schema9.fromKey("additional_sales_taxes")
37772
+ )
37773
+ });
37774
+
37775
+ // src/features/invoices/api/useUpsertInvoice.tsx
37776
+ import { useCallback as useCallback52 } from "react";
37777
+ import useSWRMutation26 from "swr/mutation";
37778
+ import { Schema as Schema10, Effect } from "effect";
37779
+ var UPSERT_INVOICES_TAG_KEY = "#upsert-invoice";
37780
+ var createInvoice = post(({ businessId }) => `/v1/businesses/${businessId}/invoices`);
37781
+ var updateInvoice = put(({ businessId, invoiceId }) => `/v1/businesses/${businessId}/invoices/${invoiceId}`);
37782
+ function buildKey39({
37783
+ access_token: accessToken,
37784
+ apiUrl,
37785
+ businessId,
37786
+ invoiceId = void 0
37787
+ }) {
37788
+ if (accessToken && apiUrl) {
37789
+ return {
37790
+ accessToken,
37791
+ apiUrl,
37792
+ businessId,
37793
+ invoiceId,
37794
+ tags: [UPSERT_INVOICES_TAG_KEY]
37795
+ };
37796
+ }
37797
+ }
37798
+ var UpsertInvoiceReturnSchema = Schema10.Struct({
37799
+ data: InvoiceSchema
37800
+ });
37801
+ var UpsertInvoiceSWRResponse = class {
37802
+ constructor(swrResponse) {
37803
+ __publicField(this, "swrResponse");
37804
+ this.swrResponse = swrResponse;
37805
+ }
37806
+ get data() {
37807
+ return this.swrResponse.data;
37808
+ }
37809
+ get trigger() {
37810
+ return this.swrResponse.trigger;
37811
+ }
37812
+ get isMutating() {
37813
+ return this.swrResponse.isMutating;
37814
+ }
37815
+ get isError() {
37816
+ return this.swrResponse.error !== void 0;
37817
+ }
37818
+ };
37819
+ var CreateParamsSchema = Schema10.Struct({
37820
+ businessId: Schema10.String
37821
+ });
37822
+ var UpdateParamsSchema = Schema10.Struct({
37823
+ businessId: Schema10.String,
37824
+ invoiceId: Schema10.String
37825
+ });
37826
+ var isParamsValidForMode = (mode, params) => {
37827
+ if (mode === "Update" /* Update */) {
37828
+ return Effect.runSync(Effect.either(Schema10.decodeUnknown(UpdateParamsSchema)(params)))._tag === "Right";
37829
+ }
37830
+ if (mode === "Create" /* Create */) {
37831
+ return Effect.runSync(Effect.either(Schema10.decodeUnknown(CreateParamsSchema)(params)))._tag === "Right";
37832
+ }
37833
+ return false;
37834
+ };
37835
+ function getRequestFn(mode, params) {
37836
+ if (mode === "Update" /* Update */) {
37837
+ if (!isParamsValidForMode("Update" /* Update */, params)) {
37838
+ throw new Error("Invalid params for upsert mode");
37839
+ }
37840
+ return ({ apiUrl, accessToken, body }) => updateInvoice(apiUrl, accessToken, { params, body });
37841
+ } else {
37842
+ if (!isParamsValidForMode("Create" /* Create */, params)) {
37843
+ throw new Error("Invalid params for create mode");
37844
+ }
37845
+ return ({ apiUrl, accessToken, body }) => createInvoice(apiUrl, accessToken, { params, body });
37846
+ }
37847
+ }
37848
+ var useUpsertInvoice = (props) => {
37849
+ const { data } = useAuth();
37850
+ const { businessId } = useLayerContext();
37851
+ const { mode } = props;
37852
+ const invoiceId = mode === "Update" /* Update */ ? props.invoiceId : void 0;
37853
+ const rawMutationResponse = useSWRMutation26(
37854
+ () => buildKey39(__spreadProps(__spreadValues({}, data), {
37855
+ businessId,
37856
+ invoiceId
37857
+ })),
37858
+ ({ accessToken, apiUrl, businessId: businessId2, invoiceId: invoiceId2 }, { arg: body }) => {
37859
+ const request2 = getRequestFn(mode, { businessId: businessId2, invoiceId: invoiceId2 });
37860
+ return request2({
37861
+ apiUrl,
37862
+ accessToken,
37863
+ body
37864
+ }).then(Schema10.decodeUnknownPromise(UpsertInvoiceReturnSchema));
37865
+ },
37866
+ {
37867
+ revalidate: false
37868
+ }
37869
+ );
37870
+ const mutationResponse = new UpsertInvoiceSWRResponse(rawMutationResponse);
37871
+ const originalTrigger = mutationResponse.trigger;
37872
+ const stableProxiedTrigger = useCallback52(
37873
+ (...triggerParameters) => __async(null, null, function* () {
37874
+ const triggerResult = yield originalTrigger(...triggerParameters);
37875
+ return triggerResult;
37876
+ }),
37877
+ [originalTrigger]
37878
+ );
37879
+ return new Proxy(mutationResponse, {
37880
+ get(target, prop) {
37881
+ if (prop === "trigger") {
37882
+ return stableProxiedTrigger;
37883
+ }
37884
+ return Reflect.get(target, prop);
37885
+ }
37886
+ });
37887
+ };
37888
+
37889
+ // src/components/Invoices/InvoiceForm/useInvoiceForm.ts
37890
+ import { BigDecimal as BD4, Schema as Schema11 } from "effect";
37891
+ var EMPTY_LINE_ITEM = {
37892
+ product: "",
37893
+ description: "",
37894
+ unitPrice: 0,
37895
+ quantity: BIG_DECIMAL_ONE,
37896
+ amount: 0
37897
+ };
37898
+ var DEFAULT_FORM_VALUES = {
37899
+ invoiceNumber: "",
37900
+ customer: null,
37901
+ email: "",
37902
+ address: "",
37903
+ lineItems: [EMPTY_LINE_ITEM]
37904
+ };
37905
+ var getInvoiceLineItemAmount = (lineItem) => {
37906
+ const { unitPrice, quantity } = lineItem;
37907
+ return convertBigDecimalToCents(BD4.multiply(quantity, convertCentsToBigDecimal(unitPrice)));
37908
+ };
37909
+ var getAugmentedInvoiceFormLineItem = (lineItem) => {
37910
+ return __spreadProps(__spreadValues({}, lineItem), {
37911
+ amount: getInvoiceLineItemAmount(lineItem)
37912
+ });
37913
+ };
37914
+ var getInvoiceFormDefaultValues = (invoice) => {
37915
+ var _a, _b;
37916
+ return {
37917
+ invoiceNumber: invoice.invoiceNumber,
37918
+ customer: invoice.customer,
37919
+ email: (_a = invoice.customer) == null ? void 0 : _a.email,
37920
+ address: (_b = invoice.customer) == null ? void 0 : _b.addressString,
37921
+ lineItems: invoice.lineItems.map(getAugmentedInvoiceFormLineItem)
37922
+ };
37923
+ };
37924
+ var useInvoiceForm = (props) => {
37925
+ const [submitError, setSubmitError] = useState84(void 0);
37926
+ const { onSuccess, mode } = props;
37927
+ const upsertInvoiceProps = mode === "Update" /* Update */ ? { mode, invoiceId: props.invoice.id } : { mode };
37928
+ const { trigger: upsertInvoice } = useUpsertInvoice(upsertInvoiceProps);
37929
+ const defaultValues = mode === "Update" /* Update */ ? getInvoiceFormDefaultValues(props.invoice) : DEFAULT_FORM_VALUES;
37930
+ const form = useAppForm({
37931
+ defaultValues,
37932
+ onSubmit: (_0) => __async(null, [_0], function* ({ value }) {
37933
+ var _a;
37934
+ try {
37935
+ const payload = __spreadProps(__spreadValues({}, value), {
37936
+ customerId: (_a = value == null ? void 0 : value.customer) == null ? void 0 : _a.id
37937
+ });
37938
+ const invoiceParams = Schema11.validateSync(UpsertInvoiceSchema)(payload);
37939
+ const { data: invoice } = yield upsertInvoice(invoiceParams);
37940
+ setSubmitError(void 0);
37941
+ onSuccess == null ? void 0 : onSuccess(invoice);
37942
+ } catch (e) {
37943
+ setSubmitError("Something went wrong. Please try again.");
37944
+ }
37945
+ })
37946
+ });
37947
+ const isFormValid = useStore7(form.store, (state) => state.isValid);
37948
+ return { form, submitError, isFormValid };
37949
+ };
37950
+
37951
+ // src/components/Invoices/InvoiceForm/InvoiceForm.tsx
37952
+ import { Plus as Plus2, Trash as Trash2 } from "lucide-react";
37953
+ import { BigDecimal as BD5 } from "effect";
37954
+
37955
+ // src/features/customers/components/CustomerSelector.tsx
37956
+ import { useCallback as useCallback53, useId as useId5, useMemo as useMemo72 } from "react";
37957
+ import classNames89 from "classnames";
37958
+ import { jsx as jsx336, jsxs as jsxs212 } from "react/jsx-runtime";
37959
+ function getCustomerName(customer) {
37960
+ var _a, _b, _c;
37961
+ return (_c = (_b = (_a = customer.individualName) != null ? _a : customer.companyName) != null ? _b : customer.externalId) != null ? _c : "Unknown Customer";
37962
+ }
37963
+ var CustomerAsOption = class {
37964
+ constructor(customer) {
37965
+ __publicField(this, "internalCustomer");
37966
+ this.internalCustomer = customer;
37967
+ }
37968
+ get original() {
37969
+ return this.internalCustomer;
37970
+ }
37971
+ get label() {
37972
+ return getCustomerName(this.internalCustomer);
37973
+ }
37974
+ get id() {
37975
+ return this.internalCustomer.id;
37976
+ }
37977
+ get value() {
37978
+ return this.internalCustomer.id;
37979
+ }
37980
+ };
37981
+ function CustomerSelector({
37982
+ selectedCustomer,
37983
+ onSelectedCustomerChange,
37984
+ placeholder,
37985
+ isReadOnly,
37986
+ inline,
37987
+ className
37988
+ }) {
37989
+ const combinedClassName = classNames89(
37990
+ "Layer__CustomerSelector",
37991
+ inline && "Layer__CustomerSelector--inline",
37992
+ className
37993
+ );
37994
+ const { searchQuery, handleInputChange } = useDebouncedSearchInput({
37995
+ initialInputState: () => ""
37996
+ });
37997
+ const effectiveSearchQuery = searchQuery === "" ? void 0 : searchQuery;
37998
+ const { data, isLoading, isError } = useListCustomers({ query: effectiveSearchQuery });
37999
+ const options = useMemo72(
38000
+ () => (data == null ? void 0 : data.flatMap(({ data: data2 }) => data2).map((customer) => new CustomerAsOption(customer))) || [],
38001
+ [data]
38002
+ );
38003
+ const selectedCustomerId = selectedCustomer == null ? void 0 : selectedCustomer.id;
38004
+ const handleSelectionChange = useCallback53(
38005
+ (selectedOption) => {
38006
+ if (selectedOption === null) {
38007
+ handleInputChange("");
38008
+ if (selectedCustomerId) {
38009
+ onSelectedCustomerChange(null);
38010
+ }
38011
+ return;
38012
+ }
38013
+ const selectedCustomer2 = options.find(({ id }) => id === selectedOption.value);
38014
+ if (selectedCustomer2) {
38015
+ const selectedCustomerWithType = selectedCustomer2.original;
38016
+ if (selectedCustomer2.id !== selectedCustomerId) {
38017
+ onSelectedCustomerChange(selectedCustomerWithType);
38018
+ }
38019
+ handleInputChange("");
38020
+ return;
38021
+ }
38022
+ },
38023
+ [options, handleInputChange, selectedCustomerId, onSelectedCustomerChange]
38024
+ );
38025
+ const selectedCustomerForComboBox = useMemo72(
38026
+ () => {
38027
+ if (selectedCustomer === null) {
38028
+ return null;
38029
+ }
38030
+ return {
38031
+ label: getCustomerName(selectedCustomer),
38032
+ value: selectedCustomer.id
38033
+ };
38034
+ },
38035
+ [selectedCustomer]
38036
+ );
38037
+ const EmptyMessage = useMemo72(
38038
+ () => /* @__PURE__ */ jsx336(P, { variant: "subtle", children: "No matching customer" }),
38039
+ []
38040
+ );
38041
+ const ErrorMessage = useMemo72(
38042
+ () => /* @__PURE__ */ jsx336(
38043
+ P,
38044
+ {
38045
+ size: "xs",
38046
+ status: "error",
38047
+ children: "An error occurred while loading customers."
38048
+ }
38049
+ ),
38050
+ []
38051
+ );
38052
+ const inputId = useId5();
38053
+ const isFiltered = effectiveSearchQuery !== void 0;
38054
+ const noCustomersExist = !isLoading && !isFiltered && data !== void 0 && data.every(({ data: data2 }) => data2.length === 0);
38055
+ const shouldHideComponent = noCustomersExist || isReadOnly && selectedCustomer === null;
38056
+ if (shouldHideComponent) {
38057
+ return null;
38058
+ }
38059
+ const isLoadingWithoutFallback = isLoading && !data;
38060
+ const shouldDisableComboBox = isLoadingWithoutFallback || isError;
38061
+ return /* @__PURE__ */ jsxs212(VStack, { className: combinedClassName, children: [
38062
+ /* @__PURE__ */ jsx336(Label, { htmlFor: inputId, size: "sm", children: "Customer" }),
38063
+ /* @__PURE__ */ jsx336(
38064
+ ComboBox,
38065
+ {
38066
+ selectedValue: selectedCustomerForComboBox,
38067
+ onSelectedValueChange: handleSelectionChange,
38068
+ options,
38069
+ onInputValueChange: handleInputChange,
38070
+ inputId,
38071
+ placeholder,
38072
+ slots: { EmptyMessage, ErrorMessage },
38073
+ isDisabled: isReadOnly || shouldDisableComboBox,
38074
+ isError,
38075
+ isLoading: isLoadingWithoutFallback
38076
+ }
38077
+ )
38078
+ ] });
38079
+ }
38080
+
38081
+ // src/components/Invoices/InvoiceForm/InvoiceForm.tsx
38082
+ import { jsx as jsx337, jsxs as jsxs213 } from "react/jsx-runtime";
38083
+ var INVOICE_FORM_CSS_PREFIX = "Layer__InvoiceForm";
38084
+ var INVOICE_FORM_FIELD_CSS_PREFIX = `${INVOICE_FORM_CSS_PREFIX}__Field`;
38085
+ var InvoiceForm = (props) => {
38086
+ const { onSuccess, mode } = props;
38087
+ const { form } = useInvoiceForm(
38088
+ __spreadValues({ onSuccess }, mode === "Update" /* Update */ ? { mode, invoice: props.invoice } : { mode })
38089
+ );
38090
+ return /* @__PURE__ */ jsxs213(Form, { className: INVOICE_FORM_CSS_PREFIX, children: [
38091
+ /* @__PURE__ */ jsxs213(VStack, { className: `${INVOICE_FORM_CSS_PREFIX}__Metadata`, gap: "xs", children: [
38092
+ /* @__PURE__ */ jsx337(
38093
+ form.Field,
38094
+ {
38095
+ name: "customer",
38096
+ listeners: {
38097
+ onChange: ({ value: customer }) => {
38098
+ form.setFieldValue("email", customer == null ? void 0 : customer.email);
38099
+ form.setFieldValue("address", customer == null ? void 0 : customer.addressString);
38100
+ }
38101
+ },
38102
+ children: (field) => /* @__PURE__ */ jsx337(
38103
+ CustomerSelector,
38104
+ {
38105
+ className: `${INVOICE_FORM_FIELD_CSS_PREFIX}__Customer`,
38106
+ selectedCustomer: field.state.value,
38107
+ onSelectedCustomerChange: field.handleChange,
38108
+ inline: true
38109
+ }
38110
+ )
38111
+ }
38112
+ ),
38113
+ /* @__PURE__ */ jsx337(form.AppField, { name: "email", children: (field) => /* @__PURE__ */ jsx337(field.FormTextField, { slotProps: { BaseFormTextField: { label: "Email", inline: true, className: `${INVOICE_FORM_FIELD_CSS_PREFIX}__Email` } } }) }),
38114
+ /* @__PURE__ */ jsx337(form.AppField, { name: "address", children: (field) => /* @__PURE__ */ jsx337(field.FormTextAreaField, { slotProps: { BaseFormTextField: { label: "Billing address", inline: true, className: `${INVOICE_FORM_FIELD_CSS_PREFIX}__Address` } } }) })
38115
+ ] }),
38116
+ /* @__PURE__ */ jsx337(VStack, { className: `${INVOICE_FORM_CSS_PREFIX}__LineItems`, gap: "xs", children: /* @__PURE__ */ jsx337(form.AppField, { name: "lineItems", mode: "array", children: (field) => /* @__PURE__ */ jsxs213(VStack, { gap: "xs", align: "baseline", children: [
38117
+ field.state.value.map((_, index) => /* @__PURE__ */ jsxs213(HStack, { gap: "xs", align: "end", className: `${INVOICE_FORM_CSS_PREFIX}__LineItem`, children: [
38118
+ /* @__PURE__ */ jsx337(form.AppField, { name: `lineItems[${index}].product`, children: (innerField) => /* @__PURE__ */ jsx337(innerField.FormTextField, { slotProps: { BaseFormTextField: { label: "Product", showLabel: index === 0 } } }) }),
38119
+ /* @__PURE__ */ jsx337(form.AppField, { name: `lineItems[${index}].description`, children: (innerField) => /* @__PURE__ */ jsx337(innerField.FormTextField, { slotProps: { BaseFormTextField: { label: "Description", showLabel: index === 0 } } }) }),
38120
+ /* @__PURE__ */ jsx337(
38121
+ form.AppField,
38122
+ {
38123
+ name: `lineItems[${index}].quantity`,
38124
+ listeners: {
38125
+ onBlur: ({ value: quantity }) => {
38126
+ const unitPrice = form.getFieldValue(`lineItems[${index}].unitPrice`);
38127
+ const nextAmount = BD5.multiply(convertCentsToBigDecimal(unitPrice), quantity);
38128
+ form.setFieldValue(`lineItems[${index}].amount`, convertBigDecimalToCents(nextAmount));
38129
+ }
38130
+ },
38131
+ children: (innerField) => /* @__PURE__ */ jsx337(innerField.FormBigDecimalField, { slotProps: { BaseFormTextField: { label: "Quantity", showLabel: index === 0 } } })
38132
+ }
38133
+ ),
38134
+ /* @__PURE__ */ jsx337(
38135
+ form.AppField,
38136
+ {
38137
+ name: `lineItems[${index}].unitPrice`,
38138
+ listeners: {
38139
+ onBlur: ({ value: unitPrice }) => {
38140
+ const quantity = form.getFieldValue(`lineItems[${index}].quantity`);
38141
+ const nextAmount = BD5.multiply(convertCentsToBigDecimal(unitPrice), quantity);
38142
+ form.setFieldValue(`lineItems[${index}].amount`, convertBigDecimalToCents(nextAmount));
38143
+ }
38144
+ },
38145
+ children: (innerField) => /* @__PURE__ */ jsx337(innerField.FormCurrencyField, { slotProps: { BaseFormTextField: { label: "Rate", showLabel: index === 0 } } })
38146
+ }
38147
+ ),
38148
+ /* @__PURE__ */ jsx337(
38149
+ form.AppField,
38150
+ {
38151
+ name: `lineItems[${index}].amount`,
38152
+ listeners: {
38153
+ onBlur: ({ value: amount }) => {
38154
+ const quantity = form.getFieldValue(`lineItems[${index}].quantity`);
38155
+ let nextUnitPrice = BIG_DECIMAL_ZERO;
38156
+ try {
38157
+ nextUnitPrice = BD5.unsafeDivide(convertCentsToBigDecimal(amount), quantity);
38158
+ } catch (e) {
38159
+ }
38160
+ form.setFieldValue(`lineItems[${index}].unitPrice`, convertBigDecimalToCents(nextUnitPrice));
38161
+ }
38162
+ },
38163
+ children: (innerField) => /* @__PURE__ */ jsx337(innerField.FormCurrencyField, { slotProps: { BaseFormTextField: { label: "Amount", showLabel: index === 0 } } })
38164
+ }
38165
+ ),
38166
+ /* @__PURE__ */ jsx337(Button2, { variant: "outlined", icon: true, "aria-label": "Delete line item", onClick: () => field.removeValue(index), children: /* @__PURE__ */ jsx337(Trash2, { size: 16 }) })
38167
+ ] }, `lineItems[${index}]`)),
38168
+ /* @__PURE__ */ jsxs213(Button2, { variant: "outlined", onClick: () => field.pushValue(EMPTY_LINE_ITEM), children: [
38169
+ "Add line item",
38170
+ /* @__PURE__ */ jsx337(Plus2, { size: 16 })
38171
+ ] })
38172
+ ] }) }) })
38173
+ ] });
38174
+ };
38175
+
38176
+ // src/components/DataPoint/DataPoint.tsx
38177
+ import { jsx as jsx338, jsxs as jsxs214 } from "react/jsx-runtime";
38178
+ var DataPoint = ({ label, children }) => {
38179
+ return /* @__PURE__ */ jsxs214(VStack, { gap: "3xs", children: [
38180
+ /* @__PURE__ */ jsx338(Span, { variant: "subtle", size: "xs", children: label }),
38181
+ children
38182
+ ] });
38183
+ };
38184
+
38185
+ // src/components/Invoices/InvoiceStatusCell/InvoiceStatusCell.tsx
38186
+ import pluralize6 from "pluralize";
38187
+ import { jsx as jsx339, jsxs as jsxs215 } from "react/jsx-runtime";
38188
+ var getDueStatusConfig = (invoice, { inline }) => {
38189
+ const badgeSize = inline ? "xs" /* EXTRA_SMALL */ : "small" /* SMALL */;
38190
+ const iconSize = inline ? 10 : 12;
38191
+ switch (invoice.status) {
38192
+ case "WRITTEN_OFF" /* WrittenOff */: {
38193
+ return { text: "Written Off" };
38194
+ }
38195
+ case "PARTIALLY_WRITTEN_OFF" /* PartiallyWrittenOff */: {
38196
+ return { text: "Partially Written Off" };
38197
+ }
38198
+ case "PAID" /* Paid */: {
38199
+ return {
38200
+ text: "Paid",
38201
+ badge: /* @__PURE__ */ jsx339(Badge, { variant: "success" /* SUCCESS */, size: badgeSize, icon: /* @__PURE__ */ jsx339(CheckCircle_default, { size: iconSize }), iconOnly: true })
38202
+ };
38203
+ }
38204
+ case "VOIDED" /* Voided */: {
38205
+ return { text: "Voided" };
38206
+ }
38207
+ case "SENT" /* Sent */:
38208
+ case "PARTIALLY_PAID" /* PartiallyPaid */: {
38209
+ if (invoice.dueAt === null) {
38210
+ return {
38211
+ text: invoice.status === "PARTIALLY_PAID" /* PartiallyPaid */ ? "Partially Paid" : "Sent"
38212
+ };
38213
+ }
38214
+ const dueDifference = getDueDifference(invoice.dueAt);
38215
+ if (dueDifference === 0) {
38216
+ return {
38217
+ text: "Due Today"
38218
+ };
38219
+ }
38220
+ if (dueDifference < 0) {
38221
+ return {
38222
+ text: "Overdue",
38223
+ subText: `Due ${pluralize6("day", Math.abs(dueDifference), true)} ago`,
38224
+ badge: /* @__PURE__ */ jsx339(Badge, { variant: "warning" /* WARNING */, size: badgeSize, icon: /* @__PURE__ */ jsx339(AlertCircle_default, { size: iconSize }), iconOnly: true })
38225
+ };
38226
+ }
38227
+ return {
38228
+ text: "Sent",
38229
+ subText: `Due in ${pluralize6("day", Math.abs(dueDifference), true)}`
38230
+ };
38231
+ }
38232
+ default: {
38233
+ unsafeAssertUnreachable({
38234
+ value: invoice.status,
38235
+ message: "Unexpected invoice status"
38236
+ });
38237
+ }
38238
+ }
38239
+ };
38240
+ var InvoiceStatusCell = ({ invoice, inline = false }) => {
38241
+ const dueStatus = getDueStatusConfig(invoice, { inline });
38242
+ const Stack3 = inline ? HStack : VStack;
38243
+ const subText = inline && dueStatus.subText ? `(${dueStatus.subText})` : dueStatus.subText;
38244
+ return /* @__PURE__ */ jsxs215(HStack, { gap: "xs", align: "center", children: [
38245
+ dueStatus.badge,
38246
+ /* @__PURE__ */ jsxs215(Stack3, __spreadProps(__spreadValues({}, inline && { gap: "3xs", align: "center" }), { children: [
38247
+ /* @__PURE__ */ jsx339(Span, { children: dueStatus.text }),
38248
+ subText && /* @__PURE__ */ jsx339(Span, { variant: "subtle", size: "sm", children: subText })
38249
+ ] }))
38250
+ ] });
38251
+ };
38252
+
38253
+ // src/components/Invoices/InvoiceDetail/InvoiceDetail.tsx
38254
+ import { jsx as jsx340, jsxs as jsxs216 } from "react/jsx-runtime";
38255
+ var InvoiceDetail = (props) => {
38256
+ const _a = props, { onSuccess: _onSuccess, onGoBack } = _a, restProps = __objRest(_a, ["onSuccess", "onGoBack"]);
38257
+ const Header6 = useCallback54(() => {
38258
+ return /* @__PURE__ */ jsx340(InvoiceDetailHeader, __spreadValues({}, restProps));
38259
+ }, [restProps]);
38260
+ return /* @__PURE__ */ jsxs216(BaseDetailView, { slots: { Header: Header6 }, name: "Invoice Detail View", onGoBack, children: [
38261
+ restProps.mode === "Update" /* Update */ && /* @__PURE__ */ jsx340(InvoiceDetailSubHeader, { invoice: restProps.invoice }),
38262
+ /* @__PURE__ */ jsx340(InvoiceForm, __spreadValues({}, props))
38263
+ ] });
38264
+ };
38265
+ var InvoiceDetailHeader = (props) => {
38266
+ const { mode } = props;
38267
+ if (mode === "Create" /* Create */) {
38268
+ return /* @__PURE__ */ jsx340(Heading2, { children: "Create Invoice" });
38269
+ }
38270
+ const invoice = props.invoice;
38271
+ const { invoiceNumber } = invoice;
38272
+ return /* @__PURE__ */ jsx340(Heading2, { children: invoiceNumber ? `Invoice ${invoiceNumber}` : "View Invoice" });
38273
+ };
38274
+ var InvoiceDetailSubHeader = ({ invoice }) => {
38275
+ const { outstandingBalance, totalAmount } = invoice;
38276
+ return /* @__PURE__ */ jsx340(HStack, { className: "Layer__InvoiceDetail__SubHeader", children: /* @__PURE__ */ jsxs216(HStack, { gap: "5xl", children: [
38277
+ /* @__PURE__ */ jsx340(DataPoint, { label: "Balance due", children: /* @__PURE__ */ jsx340(Span, { children: convertCentsToCurrency(outstandingBalance) }) }),
38278
+ /* @__PURE__ */ jsx340(DataPoint, { label: "Open balance", children: /* @__PURE__ */ jsx340(Span, { children: convertCentsToCurrency(totalAmount) }) }),
38279
+ /* @__PURE__ */ jsx340(DataPoint, { label: "Status", children: /* @__PURE__ */ jsx340(InvoiceStatusCell, { invoice, inline: true }) })
38280
+ ] }) });
38281
+ };
38282
+
38283
+ // src/components/Invoices/InvoicesTable/InvoicesTable.tsx
38284
+ import { useCallback as useCallback57, useMemo as useMemo76, useState as useState86 } from "react";
38285
+
38286
+ // src/features/invoices/api/useListInvoices.tsx
38287
+ import useSWRInfinite7 from "swr/infinite";
38288
+ var import_lodash6 = __toESM(require_lodash2());
38289
+ import { useCallback as useCallback55, useMemo as useMemo73 } from "react";
38290
+ import { Schema as Schema13 } from "effect";
38291
+
38292
+ // src/types/utility/pagination.ts
38293
+ import { Schema as Schema12, pipe as pipe6 } from "effect";
38294
+ var PaginatedResponseMetaSchema = Schema12.Struct({
38295
+ cursor: Schema12.NullOr(Schema12.String),
38296
+ hasMore: pipe6(
38297
+ Schema12.propertySignature(Schema12.Boolean),
38298
+ Schema12.fromKey("has_more")
37488
38299
  ),
37489
- additionalSalesTaxes: pipe6(
37490
- Schema10.propertySignature(Schema10.UndefinedOr(Schema10.Array(UpsertInvoiceTaxLineItemSchema))),
37491
- Schema10.fromKey("additional_sales_taxes")
38300
+ totalCount: pipe6(
38301
+ Schema12.propertySignature(Schema12.UndefinedOr(Schema12.Number)),
38302
+ Schema12.fromKey("total_count")
37492
38303
  )
37493
38304
  });
37494
38305
 
37495
38306
  // src/features/invoices/api/useListInvoices.tsx
37496
38307
  var LIST_INVOICES_TAG_KEY = "#list-invoices";
37497
- var ListInvoicesReturnSchema = Schema11.Struct({
37498
- data: Schema11.Array(InvoiceSchema),
37499
- meta: Schema11.Struct({
38308
+ var ListInvoicesReturnSchema = Schema13.Struct({
38309
+ data: Schema13.Array(InvoiceSchema),
38310
+ meta: Schema13.Struct({
37500
38311
  pagination: PaginatedResponseMetaSchema
37501
38312
  })
37502
38313
  });
@@ -37624,7 +38435,7 @@ function useListInvoices({
37624
38435
  showTotalCount: showTotalCount2
37625
38436
  }
37626
38437
  }
37627
- )().then(Schema11.decodeUnknownPromise(ListInvoicesReturnSchema)),
38438
+ )().then(Schema13.decodeUnknownPromise(ListInvoicesReturnSchema)),
37628
38439
  {
37629
38440
  keepPreviousData: true,
37630
38441
  revalidateFirstPage: false,
@@ -37643,10 +38454,10 @@ import {
37643
38454
  } from "@tanstack/react-table";
37644
38455
 
37645
38456
  // src/components/DataTable/DataTable.tsx
37646
- import { useMemo as useMemo72 } from "react";
38457
+ import { useMemo as useMemo74 } from "react";
37647
38458
 
37648
38459
  // src/components/ui/Table/Table.tsx
37649
- import { forwardRef as forwardRef20 } from "react";
38460
+ import { forwardRef as forwardRef24 } from "react";
37650
38461
  import {
37651
38462
  Cell as ReactAriaCell,
37652
38463
  Column as ReactAriaColumn,
@@ -37655,14 +38466,14 @@ import {
37655
38466
  TableBody as ReactAriaTableBody,
37656
38467
  TableHeader as ReactAriaTableHeader
37657
38468
  } from "react-aria-components";
37658
- import classNames88 from "classnames";
37659
- import { jsx as jsx326 } from "react/jsx-runtime";
38469
+ import classNames90 from "classnames";
38470
+ import { jsx as jsx341 } from "react/jsx-runtime";
37660
38471
  var CSS_PREFIX2 = "Layer__UI__Table";
37661
- var getClassName = (component, additionalClassNames) => classNames88(`${CSS_PREFIX2}-${component}`, additionalClassNames);
37662
- var Table2 = forwardRef20(
38472
+ var getClassName = (component, additionalClassNames) => classNames90(`${CSS_PREFIX2}-${component}`, additionalClassNames);
38473
+ var Table2 = forwardRef24(
37663
38474
  (_a, ref) => {
37664
38475
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37665
- return /* @__PURE__ */ jsx326(
38476
+ return /* @__PURE__ */ jsx341(
37666
38477
  ReactAriaTable,
37667
38478
  __spreadProps(__spreadValues({
37668
38479
  className: getClassName("Table" /* Table */, className)
@@ -37676,7 +38487,7 @@ var Table2 = forwardRef20(
37676
38487
  Table2.displayName = "Table" /* Table */;
37677
38488
  var TableHeaderInner = (_a, ref) => {
37678
38489
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37679
- return /* @__PURE__ */ jsx326(
38490
+ return /* @__PURE__ */ jsx341(
37680
38491
  ReactAriaTableHeader,
37681
38492
  __spreadProps(__spreadValues({
37682
38493
  className: getClassName("TableHeader" /* TableHeader */, className)
@@ -37686,11 +38497,11 @@ var TableHeaderInner = (_a, ref) => {
37686
38497
  })
37687
38498
  );
37688
38499
  };
37689
- var TableHeader = forwardRef20(TableHeaderInner);
38500
+ var TableHeader = forwardRef24(TableHeaderInner);
37690
38501
  TableHeader.displayName = "TableHeader" /* TableHeader */;
37691
38502
  var TableBodyInner = (_a, ref) => {
37692
38503
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37693
- return /* @__PURE__ */ jsx326(
38504
+ return /* @__PURE__ */ jsx341(
37694
38505
  ReactAriaTableBody,
37695
38506
  __spreadProps(__spreadValues({
37696
38507
  className: getClassName("TableBody" /* TableBody */, className)
@@ -37700,11 +38511,11 @@ var TableBodyInner = (_a, ref) => {
37700
38511
  })
37701
38512
  );
37702
38513
  };
37703
- var TableBody2 = forwardRef20(TableBodyInner);
38514
+ var TableBody2 = forwardRef24(TableBodyInner);
37704
38515
  TableBody2.displayName = "TableBody" /* TableBody */;
37705
38516
  var RowInner = (_a, ref) => {
37706
38517
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37707
- return /* @__PURE__ */ jsx326(
38518
+ return /* @__PURE__ */ jsx341(
37708
38519
  ReactAriaTableRow,
37709
38520
  __spreadProps(__spreadValues({
37710
38521
  className: getClassName("Row" /* Row */, className)
@@ -37714,13 +38525,13 @@ var RowInner = (_a, ref) => {
37714
38525
  })
37715
38526
  );
37716
38527
  };
37717
- var Row2 = forwardRef20(RowInner);
38528
+ var Row2 = forwardRef24(RowInner);
37718
38529
  Row2.displayName = "Row" /* Row */;
37719
- var Column = forwardRef20(
38530
+ var Column = forwardRef24(
37720
38531
  (_a, ref) => {
37721
38532
  var _b = _a, { children, className, textAlign = "left" } = _b, restProps = __objRest(_b, ["children", "className", "textAlign"]);
37722
38533
  const dataProperties = toDataProperties({ "text-align": textAlign });
37723
- return /* @__PURE__ */ jsx326(
38534
+ return /* @__PURE__ */ jsx341(
37724
38535
  ReactAriaColumn,
37725
38536
  __spreadProps(__spreadValues(__spreadValues({
37726
38537
  className: getClassName("Column" /* Column */, className)
@@ -37732,10 +38543,10 @@ var Column = forwardRef20(
37732
38543
  }
37733
38544
  );
37734
38545
  Column.displayName = "Column" /* Column */;
37735
- var Cell5 = forwardRef20(
38546
+ var Cell5 = forwardRef24(
37736
38547
  (_a, ref) => {
37737
38548
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37738
- return /* @__PURE__ */ jsx326(
38549
+ return /* @__PURE__ */ jsx341(
37739
38550
  ReactAriaCell,
37740
38551
  __spreadProps(__spreadValues({
37741
38552
  className: getClassName("Cell" /* Cell */, className)
@@ -37749,7 +38560,7 @@ var Cell5 = forwardRef20(
37749
38560
  Cell5.displayName = "Cell" /* Cell */;
37750
38561
 
37751
38562
  // src/components/DataTable/DataTable.tsx
37752
- import { jsx as jsx327, jsxs as jsxs210 } from "react/jsx-runtime";
38563
+ import { jsx as jsx342, jsxs as jsxs217 } from "react/jsx-runtime";
37753
38564
  var DataTable = ({
37754
38565
  columnConfig,
37755
38566
  data,
@@ -37759,19 +38570,20 @@ var DataTable = ({
37759
38570
  ariaLabel,
37760
38571
  slots
37761
38572
  }) => {
37762
- const columns2 = Object.values(columnConfig);
38573
+ const columns = Object.values(columnConfig);
37763
38574
  const { EmptyState, ErrorState } = slots;
37764
- const renderTableBody = useMemo72(() => {
38575
+ const isEmptyTable = (data == null ? void 0 : data.length) === 0;
38576
+ const renderTableBody = useMemo74(() => {
37765
38577
  if (isError) {
37766
- return /* @__PURE__ */ jsx327(Row2, { children: /* @__PURE__ */ jsx327(Cell5, { colSpan: columns2.length, children: /* @__PURE__ */ jsx327(ErrorState, {}) }) });
38578
+ return /* @__PURE__ */ jsx342(Row2, { children: /* @__PURE__ */ jsx342(Cell5, { colSpan: columns.length, children: /* @__PURE__ */ jsx342(ErrorState, {}) }) });
37767
38579
  }
37768
38580
  if (isLoading) {
37769
- return /* @__PURE__ */ jsx327(Row2, { children: /* @__PURE__ */ jsx327(Cell5, { colSpan: columns2.length, children: /* @__PURE__ */ jsx327(Loader2, {}) }) });
38581
+ return /* @__PURE__ */ jsx342(Row2, { children: /* @__PURE__ */ jsx342(Cell5, { colSpan: columns.length, children: /* @__PURE__ */ jsx342(Loader2, {}) }) });
37770
38582
  }
37771
- if ((data == null ? void 0 : data.length) === 0) {
37772
- return /* @__PURE__ */ jsx327(Row2, { children: /* @__PURE__ */ jsx327(Cell5, { colSpan: columns2.length, children: /* @__PURE__ */ jsx327(EmptyState, {}) }) });
38583
+ if (isEmptyTable) {
38584
+ return /* @__PURE__ */ jsx342(Row2, { children: /* @__PURE__ */ jsx342(Cell5, { colSpan: columns.length, children: /* @__PURE__ */ jsx342(EmptyState, {}) }) });
37773
38585
  }
37774
- const RowRenderer = (row) => /* @__PURE__ */ jsx327(Row2, { children: columns2.map((col) => /* @__PURE__ */ jsx327(
38586
+ const RowRenderer = (row) => /* @__PURE__ */ jsx342(Row2, { children: columns.map((col) => /* @__PURE__ */ jsx342(
37775
38587
  Cell5,
37776
38588
  {
37777
38589
  className: `Layer__UI__Table-Cell__${componentName}--${col.id}`,
@@ -37781,16 +38593,16 @@ var DataTable = ({
37781
38593
  )) }, row.id);
37782
38594
  RowRenderer.displayName = "Row";
37783
38595
  return RowRenderer;
37784
- }, [isLoading, data, columns2, EmptyState, componentName]);
37785
- return /* @__PURE__ */ jsxs210(Table2, { "aria-label": ariaLabel, className: `Layer__UI__Table__${componentName}`, children: [
37786
- /* @__PURE__ */ jsx327(TableHeader, { columns: columns2, children: ({ id, header, isRowHeader }) => /* @__PURE__ */ jsx327(Column, { isRowHeader, className: `Layer__UI__Table-Column__${componentName}--${id}`, children: header }, id) }),
37787
- /* @__PURE__ */ jsx327(TableBody2, { items: data, children: renderTableBody })
38596
+ }, [isError, isLoading, isEmptyTable, columns, ErrorState, EmptyState, componentName]);
38597
+ return /* @__PURE__ */ jsxs217(Table2, { "aria-label": ariaLabel, className: `Layer__UI__Table__${componentName}`, children: [
38598
+ /* @__PURE__ */ jsx342(TableHeader, { columns, children: ({ id, header, isRowHeader }) => /* @__PURE__ */ jsx342(Column, { isRowHeader, className: `Layer__UI__Table-Column__${componentName}--${id}`, children: header }, id) }),
38599
+ /* @__PURE__ */ jsx342(TableBody2, { items: data, children: renderTableBody })
37788
38600
  ] });
37789
38601
  };
37790
38602
 
37791
38603
  // src/components/DataTable/PaginatedTable.tsx
37792
- import { useCallback as useCallback49, useMemo as useMemo73, useState as useState82 } from "react";
37793
- import { jsx as jsx328, jsxs as jsxs211 } from "react/jsx-runtime";
38604
+ import { useCallback as useCallback56, useMemo as useMemo75, useState as useState85 } from "react";
38605
+ import { jsx as jsx343, jsxs as jsxs218 } from "react/jsx-runtime";
37794
38606
  var EMPTY_ARRAY = [];
37795
38607
  function PaginatedTable({
37796
38608
  data,
@@ -37803,10 +38615,10 @@ function PaginatedTable({
37803
38615
  slots
37804
38616
  }) {
37805
38617
  const { pageSize = 20, hasMore, fetchMore } = paginationProps;
37806
- const [pagination, setPagination] = useState82({ pageIndex: 0, pageSize });
38618
+ const [pagination, setPagination] = useState85({ pageIndex: 0, pageSize });
37807
38619
  const columnHelper = createColumnHelper();
37808
- const columns2 = Object.values(columnConfig);
37809
- const columnDefs = columns2.map((col) => {
38620
+ const columns = Object.values(columnConfig);
38621
+ const columnDefs = columns.map((col) => {
37810
38622
  return columnHelper.display({
37811
38623
  id: col.id,
37812
38624
  header: () => col.header,
@@ -37823,12 +38635,12 @@ function PaginatedTable({
37823
38635
  autoResetPageIndex: false
37824
38636
  });
37825
38637
  const { rows } = table.getRowModel();
37826
- const rowData = useMemo73(() => rows.map((r) => r.original), [rows]);
37827
- const onPageChange = useCallback49((page) => {
38638
+ const rowData = useMemo75(() => rows.map((r) => r.original), [rows]);
38639
+ const onPageChange = useCallback56((page) => {
37828
38640
  table.setPageIndex(page - 1);
37829
38641
  }, [table]);
37830
- return /* @__PURE__ */ jsxs211(VStack, { children: [
37831
- /* @__PURE__ */ jsx328(
38642
+ return /* @__PURE__ */ jsxs218(VStack, { children: [
38643
+ /* @__PURE__ */ jsx343(
37832
38644
  DataTable,
37833
38645
  {
37834
38646
  ariaLabel,
@@ -37840,7 +38652,7 @@ function PaginatedTable({
37840
38652
  slots
37841
38653
  }
37842
38654
  ),
37843
- !isError && !isLoading && /* @__PURE__ */ jsx328(
38655
+ !isError && !isLoading && /* @__PURE__ */ jsx343(
37844
38656
  Pagination,
37845
38657
  {
37846
38658
  currentPage: table.getState().pagination.pageIndex + 1,
@@ -37854,14 +38666,11 @@ function PaginatedTable({
37854
38666
  ] });
37855
38667
  }
37856
38668
 
37857
- // src/components/Invoices/InvoicesTable.tsx
37858
- import pluralize6 from "pluralize";
37859
-
37860
38669
  // src/icons/ChevronRightFill.tsx
37861
- import { jsx as jsx329, jsxs as jsxs212 } from "react/jsx-runtime";
38670
+ import { jsx as jsx344, jsxs as jsxs219 } from "react/jsx-runtime";
37862
38671
  var ChevronRightFill = (_a) => {
37863
38672
  var _b = _a, { size = 18 } = _b, props = __objRest(_b, ["size"]);
37864
- return /* @__PURE__ */ jsxs212(
38673
+ return /* @__PURE__ */ jsxs219(
37865
38674
  "svg",
37866
38675
  __spreadProps(__spreadValues({
37867
38676
  xmlns: "http://www.w3.org/2000/svg",
@@ -37871,8 +38680,8 @@ var ChevronRightFill = (_a) => {
37871
38680
  width: size,
37872
38681
  height: size,
37873
38682
  children: [
37874
- /* @__PURE__ */ jsx329("path", { d: "M6.75 4.5L11.25 9L6.75 13.5", fill: "currentColor" }),
37875
- /* @__PURE__ */ jsx329(
38683
+ /* @__PURE__ */ jsx344("path", { d: "M6.75 4.5L11.25 9L6.75 13.5", fill: "currentColor" }),
38684
+ /* @__PURE__ */ jsx344(
37876
38685
  "path",
37877
38686
  {
37878
38687
  d: "M6.75 4.5L11.25 9L6.75 13.5Z",
@@ -37887,38 +38696,38 @@ var ChevronRightFill = (_a) => {
37887
38696
  };
37888
38697
  var ChevronRightFill_default = ChevronRightFill;
37889
38698
 
37890
- // src/components/Invoices/InvoicesTable.tsx
37891
- import { HandCoins, Search as Search2, Plus as Plus2 } from "lucide-react";
38699
+ // src/components/Invoices/InvoicesTable/InvoicesTable.tsx
38700
+ import { HandCoins, Search as Search2, Plus as Plus3 } from "lucide-react";
37892
38701
 
37893
38702
  // src/components/DataTable/DataTableHeader.tsx
37894
- import { jsx as jsx330, jsxs as jsxs213 } from "react/jsx-runtime";
38703
+ import { jsx as jsx345, jsxs as jsxs220 } from "react/jsx-runtime";
37895
38704
  var DataTableHeader = ({ name, count, slotProps = {}, slots = {} }) => {
37896
38705
  const { showCount, totalCount } = count != null ? count : {};
37897
38706
  const { Filters: Filters2, HeaderActions, HeaderFilters } = slots;
37898
- return /* @__PURE__ */ jsxs213(VStack, { children: [
37899
- /* @__PURE__ */ jsxs213(HStack, { justify: "space-between", align: "center", className: "Layer__DataTableHeader__Header", children: [
37900
- /* @__PURE__ */ jsxs213(HStack, { pis: "md", align: "center", gap: "xl", children: [
37901
- /* @__PURE__ */ jsxs213(HStack, { align: "center", gap: "sm", children: [
37902
- /* @__PURE__ */ jsx330(Span, { weight: "bold", size: "lg", children: name }),
37903
- showCount && (totalCount ? /* @__PURE__ */ jsx330(Badge, { variant: "default" /* DEFAULT */, size: "medium" /* MEDIUM */, children: totalCount }) : /* @__PURE__ */ jsx330(BadgeLoader, {}))
38707
+ return /* @__PURE__ */ jsxs220(VStack, { children: [
38708
+ /* @__PURE__ */ jsxs220(HStack, { justify: "space-between", align: "center", className: "Layer__DataTableHeader__Header", children: [
38709
+ /* @__PURE__ */ jsxs220(HStack, { pis: "md", align: "center", gap: "xl", children: [
38710
+ /* @__PURE__ */ jsxs220(HStack, { align: "center", gap: "sm", children: [
38711
+ /* @__PURE__ */ jsx345(Span, { weight: "bold", size: "lg", children: name }),
38712
+ showCount && (totalCount ? /* @__PURE__ */ jsx345(Badge, { variant: "default" /* DEFAULT */, size: "medium" /* MEDIUM */, children: totalCount }) : /* @__PURE__ */ jsx345(BadgeLoader, {}))
37904
38713
  ] }),
37905
- HeaderFilters && /* @__PURE__ */ jsx330(HeaderFilters, {})
38714
+ HeaderFilters && /* @__PURE__ */ jsx345(HeaderFilters, {})
37906
38715
  ] }),
37907
- /* @__PURE__ */ jsxs213(HStack, { pie: "md", align: "center", gap: "3xs", children: [
37908
- slotProps.SearchField && /* @__PURE__ */ jsx330(SearchField, __spreadValues({}, slotProps.SearchField)),
37909
- HeaderActions && /* @__PURE__ */ jsx330(HeaderActions, {})
38716
+ /* @__PURE__ */ jsxs220(HStack, { pie: "md", align: "center", gap: "3xs", children: [
38717
+ slotProps.SearchField && /* @__PURE__ */ jsx345(SearchField, __spreadValues({}, slotProps.SearchField)),
38718
+ HeaderActions && /* @__PURE__ */ jsx345(HeaderActions, {})
37910
38719
  ] })
37911
38720
  ] }),
37912
- Filters2 && /* @__PURE__ */ jsxs213(HStack, { pis: "md", pie: "md", justify: "space-between", align: "center", className: "Layer__DataTableHeader__Filters", children: [
37913
- /* @__PURE__ */ jsx330(Filters2, {}),
37914
- slotProps.ClearFiltersButton && /* @__PURE__ */ jsx330(Button2, __spreadProps(__spreadValues({ variant: "outlined" }, slotProps.ClearFiltersButton), { children: "Clear All Filters" }))
38721
+ Filters2 && /* @__PURE__ */ jsxs220(HStack, { pis: "md", pie: "md", justify: "space-between", align: "center", className: "Layer__DataTableHeader__Filters", children: [
38722
+ /* @__PURE__ */ jsx345(Filters2, {}),
38723
+ slotProps.ClearFiltersButton && /* @__PURE__ */ jsx345(Button2, __spreadProps(__spreadValues({ variant: "outlined" }, slotProps.ClearFiltersButton), { children: "Clear All Filters" }))
37915
38724
  ] })
37916
38725
  ] });
37917
38726
  };
37918
38727
 
37919
- // src/components/Invoices/InvoicesTable.tsx
38728
+ // src/components/Invoices/InvoicesTable/InvoicesTable.tsx
37920
38729
  import { startOfToday, endOfYesterday } from "date-fns";
37921
- import { jsx as jsx331, jsxs as jsxs214 } from "react/jsx-runtime";
38730
+ import { jsx as jsx346, jsxs as jsxs221 } from "react/jsx-runtime";
37922
38731
  var COMPONENT_NAME10 = "InvoicesTable";
37923
38732
  var InvoiceStatusOptionConfig = {
37924
38733
  ["All" /* All */]: { label: "All", value: "All" /* All */ },
@@ -37939,12 +38748,12 @@ var AmountCell = ({ invoice }) => {
37939
38748
  case "WRITTEN_OFF" /* WrittenOff */:
37940
38749
  case "VOIDED" /* Voided */:
37941
38750
  case "SENT" /* Sent */: {
37942
- return /* @__PURE__ */ jsx331(VStack, { children: /* @__PURE__ */ jsx331(Span, { align: "right", children: totalAmount }) });
38751
+ return /* @__PURE__ */ jsx346(VStack, { children: /* @__PURE__ */ jsx346(Span, { align: "right", children: totalAmount }) });
37943
38752
  }
37944
38753
  case "PARTIALLY_PAID" /* PartiallyPaid */: {
37945
- return /* @__PURE__ */ jsxs214(VStack, { children: [
37946
- /* @__PURE__ */ jsx331(Span, { align: "right", children: totalAmount }),
37947
- /* @__PURE__ */ jsxs214(Span, { align: "right", variant: "subtle", size: "sm", children: [
38754
+ return /* @__PURE__ */ jsxs221(VStack, { children: [
38755
+ /* @__PURE__ */ jsx346(Span, { align: "right", children: totalAmount }),
38756
+ /* @__PURE__ */ jsxs221(Span, { align: "right", variant: "subtle", size: "sm", children: [
37948
38757
  outstandingBalance,
37949
38758
  " ",
37950
38759
  "outstanding"
@@ -37959,71 +38768,11 @@ var AmountCell = ({ invoice }) => {
37959
38768
  }
37960
38769
  }
37961
38770
  };
37962
- var getDueStatusConfig = (invoice) => {
37963
- switch (invoice.status) {
37964
- case "WRITTEN_OFF" /* WrittenOff */: {
37965
- return { text: "Written Off" };
37966
- }
37967
- case "PARTIALLY_WRITTEN_OFF" /* PartiallyWrittenOff */: {
37968
- return { text: "Partially Written Off" };
37969
- }
37970
- case "PAID" /* Paid */: {
37971
- return {
37972
- text: "Paid",
37973
- badge: /* @__PURE__ */ jsx331(Badge, { variant: "success" /* SUCCESS */, size: "small" /* SMALL */, icon: /* @__PURE__ */ jsx331(CheckCircle_default, { size: 12 }), iconOnly: true })
37974
- };
37975
- }
37976
- case "VOIDED" /* Voided */: {
37977
- return { text: "Voided" };
37978
- }
37979
- case "SENT" /* Sent */:
37980
- case "PARTIALLY_PAID" /* PartiallyPaid */: {
37981
- if (invoice.dueAt === null) {
37982
- return {
37983
- text: invoice.status === "PARTIALLY_PAID" /* PartiallyPaid */ ? "Partially Paid" : "Sent"
37984
- };
37985
- }
37986
- const dueDifference = getDueDifference(invoice.dueAt);
37987
- if (dueDifference === 0) {
37988
- return {
37989
- text: "Due Today"
37990
- };
37991
- }
37992
- if (dueDifference < 0) {
37993
- return {
37994
- text: "Overdue",
37995
- subText: `Due ${pluralize6("day", Math.abs(dueDifference), true)} ago`,
37996
- badge: /* @__PURE__ */ jsx331(Badge, { variant: "warning" /* WARNING */, size: "small" /* SMALL */, icon: /* @__PURE__ */ jsx331(AlertCircle_default, { size: 12 }), iconOnly: true })
37997
- };
37998
- }
37999
- return {
38000
- text: "Sent",
38001
- subText: `Due in ${pluralize6("day", Math.abs(dueDifference), true)}`
38002
- };
38003
- }
38004
- default: {
38005
- unsafeAssertUnreachable({
38006
- value: invoice.status,
38007
- message: "Unexpected invoice status"
38008
- });
38009
- }
38010
- }
38011
- };
38012
- var StatusCell = ({ invoice }) => {
38013
- const dueStatus = getDueStatusConfig(invoice);
38014
- return /* @__PURE__ */ jsxs214(HStack, { gap: "xs", align: "center", children: [
38015
- dueStatus.badge,
38016
- /* @__PURE__ */ jsxs214(VStack, { children: [
38017
- /* @__PURE__ */ jsx331(Span, { children: dueStatus.text }),
38018
- /* @__PURE__ */ jsx331(Span, { variant: "subtle", size: "sm", children: dueStatus.subText })
38019
- ] })
38020
- ] });
38021
- };
38022
- var getCustomerName = (invoice) => {
38771
+ var getCustomerName2 = (invoice) => {
38023
38772
  const { recipientName, customer } = invoice;
38024
38773
  return recipientName || (customer == null ? void 0 : customer.individualName) || (customer == null ? void 0 : customer.companyName);
38025
38774
  };
38026
- var columns = {
38775
+ var getColumnConfig = (onSelectInvoice) => ({
38027
38776
  ["SentAt" /* SentAt */]: {
38028
38777
  id: "SentAt" /* SentAt */,
38029
38778
  header: "Sent Date",
@@ -38038,35 +38787,35 @@ var columns = {
38038
38787
  ["Customer" /* Customer */]: {
38039
38788
  id: "Customer" /* Customer */,
38040
38789
  header: "Customer",
38041
- cell: (row) => getCustomerName(row)
38790
+ cell: (row) => getCustomerName2(row)
38042
38791
  },
38043
38792
  ["Total" /* Total */]: {
38044
38793
  id: "Total" /* Total */,
38045
38794
  header: "Amount",
38046
- cell: (row) => /* @__PURE__ */ jsx331(AmountCell, { invoice: row })
38795
+ cell: (row) => /* @__PURE__ */ jsx346(AmountCell, { invoice: row })
38047
38796
  },
38048
38797
  ["Status" /* Status */]: {
38049
38798
  id: "Status" /* Status */,
38050
38799
  header: "Status",
38051
- cell: (row) => /* @__PURE__ */ jsx331(StatusCell, { invoice: row })
38800
+ cell: (row) => /* @__PURE__ */ jsx346(InvoiceStatusCell, { invoice: row })
38052
38801
  },
38053
38802
  ["Expand" /* Expand */]: {
38054
38803
  id: "Expand" /* Expand */,
38055
- cell: (_row) => /* @__PURE__ */ jsx331(Button2, { inset: true, icon: true, "aria-label": "View invoice", variant: "ghost", children: /* @__PURE__ */ jsx331(ChevronRightFill_default, {}) })
38804
+ cell: (row) => /* @__PURE__ */ jsx346(Button2, { inset: true, icon: true, onPress: () => onSelectInvoice(row), "aria-label": "View invoice", variant: "ghost", children: /* @__PURE__ */ jsx346(ChevronRightFill_default, {}) })
38056
38805
  }
38057
- };
38058
- var unpaidStatuses = ["SENT" /* Sent */, "PARTIALLY_PAID" /* PartiallyPaid */];
38806
+ });
38807
+ var UNPAID_STATUSES2 = ["SENT" /* Sent */, "PARTIALLY_PAID" /* PartiallyPaid */];
38059
38808
  var getListInvoiceParams = ({ statusFilter }) => {
38060
38809
  if (!statusFilter) return {};
38061
38810
  switch (statusFilter) {
38062
38811
  case "All" /* All */:
38063
38812
  return {};
38064
38813
  case "Unpaid" /* Unpaid */:
38065
- return { status: unpaidStatuses };
38814
+ return { status: UNPAID_STATUSES2 };
38066
38815
  case "Overdue" /* Overdue */:
38067
- return { status: unpaidStatuses, dueAtEnd: endOfYesterday() };
38816
+ return { status: UNPAID_STATUSES2, dueAtEnd: endOfYesterday() };
38068
38817
  case "Sent" /* Sent */:
38069
- return { status: unpaidStatuses, dueAtStart: startOfToday() };
38818
+ return { status: UNPAID_STATUSES2, dueAtStart: startOfToday() };
38070
38819
  case "Paid" /* Paid */:
38071
38820
  return { status: ["PAID" /* Paid */, "PARTIALLY_WRITTEN_OFF" /* PartiallyWrittenOff */] };
38072
38821
  case "Written Off" /* WrittenOff */:
@@ -38080,9 +38829,9 @@ var getListInvoiceParams = ({ statusFilter }) => {
38080
38829
  });
38081
38830
  }
38082
38831
  };
38083
- var InvoicesTable = () => {
38084
- const [selectedInvoiceStatusOption, setSelectedInvoiceStatusOption] = useState83(ALL_OPTION);
38085
- const listInvoiceParams = useMemo74(
38832
+ var InvoicesTable = ({ onCreateInvoice, onSelectInvoice }) => {
38833
+ const [selectedInvoiceStatusOption, setSelectedInvoiceStatusOption] = useState86(ALL_OPTION);
38834
+ const listInvoiceParams = useMemo76(
38086
38835
  () => getListInvoiceParams({ statusFilter: selectedInvoiceStatusOption == null ? void 0 : selectedInvoiceStatusOption.value }),
38087
38836
  [selectedInvoiceStatusOption == null ? void 0 : selectedInvoiceStatusOption.value]
38088
38837
  );
@@ -38090,25 +38839,25 @@ var InvoicesTable = () => {
38090
38839
  const invoices = data == null ? void 0 : data.flatMap(({ data: data2 }) => data2);
38091
38840
  const paginationMeta = data == null ? void 0 : data[data.length - 1].meta.pagination;
38092
38841
  const hasMore = paginationMeta == null ? void 0 : paginationMeta.hasMore;
38093
- const fetchMore = useCallback50(() => {
38842
+ const fetchMore = useCallback57(() => {
38094
38843
  if (hasMore) {
38095
38844
  void setSize(size + 1);
38096
38845
  }
38097
38846
  }, [hasMore, setSize, size]);
38098
- const paginationProps = useMemo74(() => {
38847
+ const paginationProps = useMemo76(() => {
38099
38848
  return {
38100
38849
  pageSize: 10,
38101
38850
  hasMore,
38102
38851
  fetchMore
38103
38852
  };
38104
38853
  }, [fetchMore, hasMore]);
38105
- const options = useMemo74(() => Object.values(InvoiceStatusOptionConfig), []);
38106
- const SelectedValue = useMemo74(() => {
38854
+ const options = useMemo76(() => Object.values(InvoiceStatusOptionConfig), []);
38855
+ const SelectedValue = useMemo76(() => {
38107
38856
  const label = selectedInvoiceStatusOption == null ? void 0 : selectedInvoiceStatusOption.label;
38108
38857
  return label ? `Status: ${label}` : "Status";
38109
38858
  }, [selectedInvoiceStatusOption == null ? void 0 : selectedInvoiceStatusOption.label]);
38110
- const StatusFilter = useCallback50(
38111
- () => /* @__PURE__ */ jsx331(
38859
+ const StatusFilter = useCallback57(
38860
+ () => /* @__PURE__ */ jsx346(
38112
38861
  ComboBox,
38113
38862
  {
38114
38863
  className: "Layer__InvoicesTable__StatusFilter",
@@ -38124,27 +38873,27 @@ var InvoicesTable = () => {
38124
38873
  ),
38125
38874
  [SelectedValue, options, selectedInvoiceStatusOption]
38126
38875
  );
38127
- const CreateInvoiceButton = useCallback50(
38128
- () => /* @__PURE__ */ jsxs214(Button2, { children: [
38876
+ const CreateInvoiceButton = useCallback57(
38877
+ () => /* @__PURE__ */ jsxs221(Button2, { onPress: onCreateInvoice, children: [
38129
38878
  "Create Invoice",
38130
- /* @__PURE__ */ jsx331(Plus2, { size: 16 })
38879
+ /* @__PURE__ */ jsx346(Plus3, { size: 16 })
38131
38880
  ] }),
38132
- []
38881
+ [onCreateInvoice]
38133
38882
  );
38134
- const InvoicesTableEmptyState = useCallback50(() => {
38883
+ const InvoicesTableEmptyState = useCallback57(() => {
38135
38884
  const isFiltered = selectedInvoiceStatusOption && selectedInvoiceStatusOption !== ALL_OPTION;
38136
- return /* @__PURE__ */ jsx331(
38885
+ return /* @__PURE__ */ jsx346(
38137
38886
  DataState,
38138
38887
  {
38139
38888
  status: "allDone" /* allDone */,
38140
38889
  title: isFiltered ? "No results found" : "No invoices yet",
38141
38890
  description: isFiltered ? "We couldn\u2019t find any invoices with the current filters. Try changing or clearing them to see more results." : "Add your first invoice to start tracking what your customers owe you.",
38142
- icon: isFiltered ? /* @__PURE__ */ jsx331(Search2, {}) : /* @__PURE__ */ jsx331(HandCoins, {}),
38891
+ icon: isFiltered ? /* @__PURE__ */ jsx346(Search2, {}) : /* @__PURE__ */ jsx346(HandCoins, {}),
38143
38892
  spacing: true
38144
38893
  }
38145
38894
  );
38146
38895
  }, [selectedInvoiceStatusOption]);
38147
- const InvoicesTableErrorState = useCallback50(() => /* @__PURE__ */ jsx331(
38896
+ const InvoicesTableErrorState = useCallback57(() => /* @__PURE__ */ jsx346(
38148
38897
  DataState,
38149
38898
  {
38150
38899
  status: "failed" /* failed */,
@@ -38156,8 +38905,9 @@ var InvoicesTable = () => {
38156
38905
  spacing: true
38157
38906
  }
38158
38907
  ), [refetch]);
38159
- return /* @__PURE__ */ jsxs214(Container, { name: "InvoicesTable", children: [
38160
- /* @__PURE__ */ jsx331(
38908
+ const columnConfig = useMemo76(() => getColumnConfig(onSelectInvoice), [onSelectInvoice]);
38909
+ return /* @__PURE__ */ jsxs221(Container, { name: "InvoicesTable", children: [
38910
+ /* @__PURE__ */ jsx346(
38161
38911
  DataTableHeader,
38162
38912
  {
38163
38913
  name: "Invoices",
@@ -38167,14 +38917,14 @@ var InvoicesTable = () => {
38167
38917
  }
38168
38918
  }
38169
38919
  ),
38170
- /* @__PURE__ */ jsx331(
38920
+ /* @__PURE__ */ jsx346(
38171
38921
  PaginatedTable,
38172
38922
  {
38173
38923
  ariaLabel: "Invoices",
38174
38924
  data: invoices,
38175
38925
  isLoading: data === void 0 || isLoading,
38176
38926
  isError,
38177
- columnConfig: columns,
38927
+ columnConfig,
38178
38928
  paginationProps,
38179
38929
  componentName: COMPONENT_NAME10,
38180
38930
  slots: {
@@ -38187,28 +38937,38 @@ var InvoicesTable = () => {
38187
38937
  };
38188
38938
 
38189
38939
  // src/components/Invoices/Invoices.tsx
38190
- import { jsx as jsx332 } from "react/jsx-runtime";
38940
+ import { jsx as jsx347 } from "react/jsx-runtime";
38191
38941
  var unstable_Invoices = ({
38192
38942
  showTitle = true,
38193
38943
  stringOverrides
38194
38944
  }) => {
38195
- return /* @__PURE__ */ jsx332(
38945
+ const [invoiceFormMode, setInvoiceFormMode] = useState87(null);
38946
+ const goBackToInvoicesTable = useCallback58(() => {
38947
+ setInvoiceFormMode(null);
38948
+ }, []);
38949
+ const onCreateInvoice = useCallback58(() => {
38950
+ setInvoiceFormMode({ mode: "Create" /* Create */ });
38951
+ }, []);
38952
+ const onSelectInvoice = useCallback58((invoice) => {
38953
+ setInvoiceFormMode({ mode: "Update" /* Update */, invoice });
38954
+ }, []);
38955
+ return /* @__PURE__ */ jsx347(
38196
38956
  View,
38197
38957
  {
38198
38958
  title: (stringOverrides == null ? void 0 : stringOverrides.title) || "Invoices",
38199
38959
  showHeader: showTitle,
38200
- children: /* @__PURE__ */ jsx332(InvoicesTable, {})
38960
+ children: invoiceFormMode !== null ? /* @__PURE__ */ jsx347(InvoiceDetail, __spreadProps(__spreadValues({}, invoiceFormMode), { onGoBack: goBackToInvoicesTable })) : /* @__PURE__ */ jsx347(InvoicesTable, { onCreateInvoice, onSelectInvoice })
38201
38961
  }
38202
38962
  );
38203
38963
  };
38204
38964
 
38205
38965
  // src/providers/BankTransactionsProvider/BankTransactionsProvider.tsx
38206
- import { jsx as jsx333 } from "react/jsx-runtime";
38966
+ import { jsx as jsx348 } from "react/jsx-runtime";
38207
38967
  var BankTransactionsProvider = ({
38208
38968
  children
38209
38969
  }) => {
38210
38970
  const bankTransactionsContextData = useAugmentedBankTransactions();
38211
- return /* @__PURE__ */ jsx333(BankTransactionsContext.Provider, { value: bankTransactionsContextData, children });
38971
+ return /* @__PURE__ */ jsx348(BankTransactionsContext.Provider, { value: bankTransactionsContextData, children });
38212
38972
  };
38213
38973
  export {
38214
38974
  AccountingOverview,