@layerfi/components 0.1.106-alpha → 0.1.106

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";
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 }) => startOfMonth(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,393 @@ 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 useCallback59, useState as useState87 } from "react";
37272
+
37273
+ // src/components/Invoices/InvoiceDetail/InvoiceDetail.tsx
37274
+ import { useCallback as useCallback55 } 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
+ };
37288
+
37289
+ // src/components/Invoices/InvoiceForm/useInvoiceForm.ts
37290
+ import { useState as useState84 } from "react";
37291
+ import { useStore as useStore7 } from "@tanstack/react-form";
37297
37292
 
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";
37293
+ // src/features/forms/hooks/useForm.tsx
37294
+ import { createFormHookContexts, createFormHook } from "@tanstack/react-form";
37303
37295
 
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
- )
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(_a) {
37435
+ var _b = _a, {
37436
+ maxInputLength = DEFAULT_MAX_INPUT_LENGTH,
37437
+ allowNegative = false
37438
+ } = _b, restProps = __objRest(_b, [
37439
+ "maxInputLength",
37440
+ "allowNegative"
37441
+ ]);
37442
+ const field = useFieldContext();
37443
+ const { name, state, handleChange, handleBlur } = field;
37444
+ const { value } = state;
37445
+ const [inputValue, setInputValue] = useState82(formatBigDecimalToString(value, maxInputLength));
37446
+ const onInputChange = useCallback48((e) => {
37447
+ setInputValue(e.target.value);
37448
+ }, []);
37449
+ const onInputBlur = useCallback48(() => {
37450
+ const cleaned = inputValue.replace(/,/g, "");
37451
+ const maybeDecimal = BD2.fromString(cleaned);
37452
+ const decimal = Option4.match(maybeDecimal, {
37453
+ onNone: () => BIG_DECIMAL_ZERO,
37454
+ onSome: (amount) => amount
37455
+ });
37456
+ const normalizedDecimal = BD2.normalize(decimal);
37457
+ handleChange(normalizedDecimal);
37458
+ handleBlur();
37459
+ setInputValue(formatBigDecimalToString(normalizedDecimal, maxInputLength));
37460
+ }, [inputValue, handleBlur, handleChange, maxInputLength]);
37461
+ const allowedChars = useMemo71(
37462
+ () => allowNegative ? DECIMAL_CHARS_REGEX : NON_NEGATIVE_DECIMAL_CHARS_REGEX,
37463
+ [allowNegative]
37464
+ );
37465
+ const onBeforeInput = useCallback48((e) => {
37466
+ if (e.data && !allowedChars.test(e.data)) {
37467
+ e.preventDefault();
37468
+ }
37469
+ }, [allowedChars]);
37470
+ const onPaste = useCallback48((e) => {
37471
+ const pastedText = e.clipboardData.getData("text");
37472
+ if (!allowedChars.test(pastedText)) {
37473
+ e.preventDefault();
37474
+ }
37475
+ }, [allowedChars]);
37476
+ useEffect41(() => {
37477
+ setInputValue(formatBigDecimalToString(value, maxInputLength));
37478
+ }, [value, maxInputLength]);
37479
+ return /* @__PURE__ */ jsx331(BaseFormTextField, __spreadProps(__spreadValues({}, restProps), { inputMode: "decimal", children: /* @__PURE__ */ jsx331(InputGroup2, { children: /* @__PURE__ */ jsx331(
37480
+ Input2,
37481
+ {
37482
+ inset: true,
37483
+ id: name,
37484
+ name,
37485
+ value: inputValue,
37486
+ onChange: onInputChange,
37487
+ onBlur: onInputBlur,
37488
+ maxLength: maxInputLength,
37489
+ onBeforeInput,
37490
+ onPaste
37491
+ }
37492
+ ) }) }));
37493
+ }
37494
+
37495
+ // src/features/forms/components/FormCheckboxField.tsx
37496
+ import { useCallback as useCallback49 } from "react";
37497
+ import classNames89 from "classnames";
37498
+ import { jsx as jsx332 } from "react/jsx-runtime";
37499
+ var FORM_CHECKBOX_FIELD_CLASSNAME = "Layer__FormCheckboxField";
37500
+ function FormCheckboxField({
37501
+ label,
37502
+ className,
37503
+ inline = false,
37504
+ showLabel = true,
37505
+ showErrorInTooltip = true
37506
+ }) {
37507
+ const field = useFieldContext();
37508
+ const { name, state, handleChange, handleBlur } = field;
37509
+ const { meta, value } = state;
37510
+ const { errors, isValid: isValid2 } = meta;
37511
+ const errorMessage = errors.length !== 0 ? errors[0] : void 0;
37512
+ const tooltipProps = showErrorInTooltip ? { tooltip: errorMessage } : {};
37513
+ const additionalAriaProps = !showLabel && { "aria-label": label };
37514
+ const checkboxClassNames = classNames89(
37515
+ FORM_CHECKBOX_FIELD_CLASSNAME,
37516
+ inline && `${FORM_CHECKBOX_FIELD_CLASSNAME}--inline`,
37517
+ className
37518
+ );
37519
+ const onChange = useCallback49((isSelected) => {
37520
+ handleChange(isSelected);
37521
+ }, [handleChange]);
37522
+ return /* @__PURE__ */ jsx332(
37523
+ CheckboxWithTooltip,
37524
+ __spreadProps(__spreadValues(__spreadValues(__spreadValues({
37525
+ className: checkboxClassNames,
37526
+ isSelected: value,
37527
+ isInvalid: !isValid2,
37528
+ onChange,
37529
+ onBlur: handleBlur,
37530
+ name,
37531
+ value: name,
37532
+ size: "lg"
37533
+ }, tooltipProps), additionalAriaProps), !isValid2 && { variant: "error" }), {
37534
+ children: showLabel && /* @__PURE__ */ jsx332(Label, { slot: "label", size: "sm", htmlFor: name, children: label })
37535
+ })
37536
+ );
37537
+ }
37538
+
37539
+ // src/features/forms/components/FormCurrencyField.tsx
37540
+ import { useCallback as useCallback50, useEffect as useEffect42, useState as useState83 } from "react";
37541
+ import CurrencyInput2 from "react-currency-input-field";
37542
+ import { BigDecimal as BD3, Option as Option5 } from "effect";
37543
+ import { jsx as jsx333 } from "react/jsx-runtime";
37544
+ var ZERO_CENTS_INPUT_VALUE = "0.00";
37545
+ var getCurrencyInputValueFromCents = (cents) => !Number.isNaN(cents) ? centsToDollarsWithoutCommas(cents) : ZERO_CENTS_INPUT_VALUE;
37546
+ function FormCurrencyField(props) {
37547
+ const field = useFieldContext();
37548
+ const { label } = props;
37549
+ const { name, state, handleChange, handleBlur } = field;
37550
+ const { value } = state;
37551
+ const [inputValue, setInputValue] = useState83(getCurrencyInputValueFromCents(value));
37552
+ const onInputChange = useCallback50((newValue) => {
37553
+ setInputValue(newValue != null ? newValue : ZERO_CENTS_INPUT_VALUE);
37554
+ }, []);
37555
+ const onInputBlur = useCallback50(() => {
37556
+ const maybeAmount = BD3.fromString(inputValue);
37557
+ const cents = Option5.match(maybeAmount, {
37558
+ onNone: () => 0,
37559
+ onSome: (amount) => convertBigDecimalToCents(amount)
37560
+ });
37561
+ handleChange(cents);
37562
+ handleBlur();
37563
+ setInputValue(getCurrencyInputValueFromCents(cents));
37564
+ }, [inputValue, handleChange, handleBlur]);
37565
+ useEffect42(() => {
37566
+ setInputValue(getCurrencyInputValueFromCents(value));
37567
+ }, [value]);
37568
+ return /* @__PURE__ */ jsx333(BaseFormTextField, __spreadProps(__spreadValues({}, props), { children: /* @__PURE__ */ jsx333(InputGroup2, { children: /* @__PURE__ */ jsx333(
37569
+ CurrencyInput2,
37570
+ {
37571
+ name,
37572
+ intlConfig: {
37573
+ locale: "en-US",
37574
+ currency: "USD"
37575
+ },
37576
+ prefix: "$",
37577
+ decimalScale: 2,
37578
+ decimalsLimit: 2,
37579
+ disableAbbreviations: true,
37580
+ value: inputValue,
37581
+ onValueChange: onInputChange,
37582
+ onBlur: onInputBlur,
37583
+ className: "Layer__UI__Input",
37584
+ "data-inset": "true",
37585
+ "aria-label": label
37586
+ }
37587
+ ) }) }));
37588
+ }
37589
+
37590
+ // src/features/forms/components/FormTextAreaField.tsx
37591
+ import { useCallback as useCallback51 } from "react";
37592
+
37593
+ // src/components/ui/Input/TextArea.tsx
37594
+ import { forwardRef as forwardRef23 } from "react";
37595
+ import { TextArea as ReactAriaTextArea } from "react-aria-components";
37596
+ import { jsx as jsx334 } from "react/jsx-runtime";
37597
+ var TEXTAREA_CLASS_NAME = "Layer__UI__TextArea";
37598
+ var TextArea = forwardRef23(
37599
+ function TextArea2(_a, ref) {
37600
+ var _b = _a, { resize = "none" } = _b, restProps = __objRest(_b, ["resize"]);
37601
+ const dataProperties = toDataProperties({ resize });
37602
+ return /* @__PURE__ */ jsx334(
37603
+ ReactAriaTextArea,
37604
+ __spreadProps(__spreadValues(__spreadValues({}, restProps), dataProperties), {
37605
+ className: TEXTAREA_CLASS_NAME,
37606
+ ref
37607
+ })
37608
+ );
37609
+ }
37610
+ );
37611
+
37612
+ // src/features/forms/components/FormTextAreaField.tsx
37613
+ import { jsx as jsx335 } from "react/jsx-runtime";
37614
+ function FormTextAreaField(props) {
37615
+ const field = useFieldContext();
37616
+ const { name, state, handleChange, handleBlur } = field;
37617
+ const { value } = state;
37618
+ const onChange = useCallback51((e) => {
37619
+ handleChange(e.target.value);
37620
+ }, [handleChange]);
37621
+ return /* @__PURE__ */ jsx335(BaseFormTextField, __spreadProps(__spreadValues({}, props), { isTextArea: true, children: /* @__PURE__ */ jsx335(TextArea, { id: name, name, value, onChange, onBlur: handleBlur }) }));
37622
+ }
37623
+
37624
+ // src/features/forms/components/FormTextField.tsx
37625
+ import { useCallback as useCallback52 } from "react";
37626
+ import { jsx as jsx336 } from "react/jsx-runtime";
37627
+ function FormTextField(props) {
37628
+ const field = useFieldContext();
37629
+ const { name, state, handleChange, handleBlur } = field;
37630
+ const { value } = state;
37631
+ const onChange = useCallback52((e) => {
37632
+ handleChange(e.target.value);
37633
+ }, [handleChange]);
37634
+ return /* @__PURE__ */ jsx336(BaseFormTextField, __spreadProps(__spreadValues({}, props), { children: /* @__PURE__ */ jsx336(InputGroup2, { children: /* @__PURE__ */ jsx336(Input2, { inset: true, id: name, name, value, onChange, onBlur: handleBlur }) }) }));
37635
+ }
37636
+
37637
+ // src/features/forms/hooks/useForm.tsx
37638
+ var { fieldContext, useFieldContext, formContext, useFormContext } = createFormHookContexts();
37639
+ var { useAppForm, withForm } = createFormHook({
37640
+ fieldComponents: {
37641
+ BaseFormTextField,
37642
+ FormBigDecimalField,
37643
+ FormCheckboxField,
37644
+ FormCurrencyField,
37645
+ FormTextAreaField,
37646
+ FormTextField
37647
+ },
37648
+ formComponents: {
37649
+ // TODO: define a submit button component
37650
+ },
37651
+ fieldContext,
37652
+ formContext
37316
37653
  });
37317
37654
 
37318
37655
  // src/features/invoices/invoiceSchemas.ts
37319
- import { Schema as Schema10, pipe as pipe6 } from "effect";
37656
+ import { Schema as Schema9, pipe as pipe5 } from "effect";
37320
37657
  var InvoiceStatus = /* @__PURE__ */ ((InvoiceStatus3) => {
37321
37658
  InvoiceStatus3["Voided"] = "VOIDED";
37322
37659
  InvoiceStatus3["Paid"] = "PAID";
@@ -37326,10 +37663,10 @@ var InvoiceStatus = /* @__PURE__ */ ((InvoiceStatus3) => {
37326
37663
  InvoiceStatus3["Sent"] = "SENT";
37327
37664
  return InvoiceStatus3;
37328
37665
  })(InvoiceStatus || {});
37329
- var InvoiceStatusSchema = Schema10.Enums(InvoiceStatus);
37330
- var TransformedInvoiceStatusSchema = Schema10.transform(
37331
- Schema10.NonEmptyTrimmedString,
37332
- Schema10.typeSchema(InvoiceStatusSchema),
37666
+ var InvoiceStatusSchema = Schema9.Enums(InvoiceStatus);
37667
+ var TransformedInvoiceStatusSchema = Schema9.transform(
37668
+ Schema9.NonEmptyTrimmedString,
37669
+ Schema9.typeSchema(InvoiceStatusSchema),
37333
37670
  {
37334
37671
  decode: (input) => {
37335
37672
  if (Object.values(InvoiceStatusSchema.enums).includes(input)) {
@@ -37340,163 +37677,688 @@ var TransformedInvoiceStatusSchema = Schema10.transform(
37340
37677
  encode: (input) => input
37341
37678
  }
37342
37679
  );
37343
- var InvoiceLineItemSchema = Schema10.Struct({
37344
- id: Schema10.UUID,
37345
- externalId: pipe6(
37346
- Schema10.propertySignature(Schema10.NullOr(Schema10.String)),
37347
- Schema10.fromKey("external_id")
37680
+ var InvoiceLineItemSchema = Schema9.Struct({
37681
+ id: Schema9.UUID,
37682
+ externalId: pipe5(
37683
+ Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
37684
+ Schema9.fromKey("external_id")
37348
37685
  ),
37349
- invoiceId: pipe6(
37350
- Schema10.propertySignature(Schema10.UUID),
37351
- Schema10.fromKey("invoice_id")
37686
+ invoiceId: pipe5(
37687
+ Schema9.propertySignature(Schema9.UUID),
37688
+ Schema9.fromKey("invoice_id")
37352
37689
  ),
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")
37690
+ description: Schema9.NullOr(Schema9.String),
37691
+ product: Schema9.NullOr(Schema9.String),
37692
+ unitPrice: pipe5(
37693
+ Schema9.propertySignature(Schema9.Number),
37694
+ Schema9.fromKey("unit_price")
37358
37695
  ),
37359
- quantity: Schema10.BigDecimal,
37360
- subtotal: Schema10.Number,
37361
- discountAmount: pipe6(
37362
- Schema10.propertySignature(Schema10.Number),
37363
- Schema10.fromKey("discount_amount")
37696
+ quantity: Schema9.BigDecimal,
37697
+ subtotal: Schema9.Number,
37698
+ discountAmount: pipe5(
37699
+ Schema9.propertySignature(Schema9.Number),
37700
+ Schema9.fromKey("discount_amount")
37364
37701
  ),
37365
- salesTaxTotal: pipe6(
37366
- Schema10.propertySignature(Schema10.Number),
37367
- Schema10.fromKey("sales_taxes_total")
37702
+ salesTaxTotal: pipe5(
37703
+ Schema9.propertySignature(Schema9.Number),
37704
+ Schema9.fromKey("sales_taxes_total")
37368
37705
  ),
37369
- totalAmount: pipe6(
37370
- Schema10.propertySignature(Schema10.Number),
37371
- Schema10.fromKey("total_amount")
37706
+ totalAmount: pipe5(
37707
+ Schema9.propertySignature(Schema9.Number),
37708
+ Schema9.fromKey("total_amount")
37372
37709
  ),
37373
- memo: Schema10.NullOr(Schema10.String)
37710
+ memo: Schema9.NullOr(Schema9.String)
37374
37711
  });
37375
- var InvoiceSchema = Schema10.Struct({
37376
- id: Schema10.UUID,
37377
- businessId: pipe6(
37378
- Schema10.propertySignature(Schema10.UUID),
37379
- Schema10.fromKey("business_id")
37712
+ var InvoiceSchema = Schema9.Struct({
37713
+ id: Schema9.UUID,
37714
+ businessId: pipe5(
37715
+ Schema9.propertySignature(Schema9.UUID),
37716
+ Schema9.fromKey("business_id")
37380
37717
  ),
37381
- externalId: pipe6(
37382
- Schema10.propertySignature(Schema10.NullOr(Schema10.String)),
37383
- Schema10.fromKey("external_id")
37718
+ externalId: pipe5(
37719
+ Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
37720
+ Schema9.fromKey("external_id")
37384
37721
  ),
37385
37722
  status: TransformedInvoiceStatusSchema,
37386
- sentAt: pipe6(
37387
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37388
- Schema10.fromKey("sent_at")
37723
+ sentAt: pipe5(
37724
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37725
+ Schema9.fromKey("sent_at")
37389
37726
  ),
37390
- dueAt: pipe6(
37391
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37392
- Schema10.fromKey("due_at")
37727
+ dueAt: pipe5(
37728
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37729
+ Schema9.fromKey("due_at")
37393
37730
  ),
37394
- paidAt: pipe6(
37395
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37396
- Schema10.fromKey("paid_at")
37731
+ paidAt: pipe5(
37732
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37733
+ Schema9.fromKey("paid_at")
37397
37734
  ),
37398
- voidedAt: pipe6(
37399
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37400
- Schema10.fromKey("voided_at")
37735
+ voidedAt: pipe5(
37736
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37737
+ Schema9.fromKey("voided_at")
37401
37738
  ),
37402
- invoiceNumber: pipe6(
37403
- Schema10.propertySignature(Schema10.NullOr(Schema10.String)),
37404
- Schema10.fromKey("invoice_number")
37739
+ invoiceNumber: pipe5(
37740
+ Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
37741
+ Schema9.fromKey("invoice_number")
37405
37742
  ),
37406
- recipientName: pipe6(
37407
- Schema10.propertySignature(Schema10.NullOr(Schema10.String)),
37408
- Schema10.fromKey("recipient_name")
37743
+ recipientName: pipe5(
37744
+ Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
37745
+ Schema9.fromKey("recipient_name")
37409
37746
  ),
37410
- customer: Schema10.NullOr(CustomerSchema),
37411
- lineItems: pipe6(
37412
- Schema10.propertySignature(Schema10.Array(InvoiceLineItemSchema)),
37413
- Schema10.fromKey("line_items")
37747
+ customer: Schema9.NullOr(CustomerSchema),
37748
+ lineItems: pipe5(
37749
+ Schema9.propertySignature(Schema9.Array(InvoiceLineItemSchema)),
37750
+ Schema9.fromKey("line_items")
37414
37751
  ),
37415
- subtotal: Schema10.Number,
37416
- additionalDiscount: pipe6(
37417
- Schema10.propertySignature(Schema10.Number),
37418
- Schema10.fromKey("additional_discount")
37752
+ subtotal: Schema9.Number,
37753
+ additionalDiscount: pipe5(
37754
+ Schema9.propertySignature(Schema9.Number),
37755
+ Schema9.fromKey("additional_discount")
37419
37756
  ),
37420
- additionalSalesTaxesTotal: pipe6(
37421
- Schema10.propertySignature(Schema10.Number),
37422
- Schema10.fromKey("additional_sales_taxes_total")
37757
+ additionalSalesTaxesTotal: pipe5(
37758
+ Schema9.propertySignature(Schema9.Number),
37759
+ Schema9.fromKey("additional_sales_taxes_total")
37423
37760
  ),
37424
- totalAmount: pipe6(
37425
- Schema10.propertySignature(Schema10.Number),
37426
- Schema10.fromKey("total_amount")
37761
+ totalAmount: pipe5(
37762
+ Schema9.propertySignature(Schema9.Number),
37763
+ Schema9.fromKey("total_amount")
37427
37764
  ),
37428
- outstandingBalance: pipe6(
37429
- Schema10.propertySignature(Schema10.Number),
37430
- Schema10.fromKey("outstanding_balance")
37765
+ outstandingBalance: pipe5(
37766
+ Schema9.propertySignature(Schema9.Number),
37767
+ Schema9.fromKey("outstanding_balance")
37431
37768
  ),
37432
- importedAt: pipe6(
37433
- Schema10.propertySignature(Schema10.Date),
37434
- Schema10.fromKey("imported_at")
37769
+ importedAt: pipe5(
37770
+ Schema9.propertySignature(Schema9.Date),
37771
+ Schema9.fromKey("imported_at")
37435
37772
  ),
37436
- updatedAt: pipe6(
37437
- Schema10.propertySignature(Schema10.NullOr(Schema10.Date)),
37438
- Schema10.fromKey("updated_at")
37773
+ updatedAt: pipe5(
37774
+ Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
37775
+ Schema9.fromKey("updated_at")
37439
37776
  ),
37440
- memo: Schema10.NullOr(Schema10.String)
37777
+ memo: Schema9.NullOr(Schema9.String)
37441
37778
  });
37442
- var UpsertInvoiceTaxLineItemSchema = Schema10.Struct({
37443
- amount: Schema10.NumberFromString.pipe(Schema10.int())
37779
+ var UpsertInvoiceTaxLineItemSchema = Schema9.Struct({
37780
+ amount: Schema9.Number
37444
37781
  });
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")
37782
+ var UpsertInvoiceLineItemSchema = Schema9.Struct({
37783
+ description: Schema9.String,
37784
+ product: Schema9.String,
37785
+ unitPrice: pipe5(
37786
+ Schema9.propertySignature(Schema9.Number),
37787
+ Schema9.fromKey("unit_price")
37453
37788
  ),
37454
- unitPrice: pipe6(
37455
- Schema10.propertySignature(Schema10.NumberFromString.pipe(Schema10.int())),
37456
- Schema10.fromKey("unit_price")
37457
- ),
37458
- quantity: pipe6(
37459
- Schema10.propertySignature(Schema10.BigDecimal),
37460
- Schema10.fromKey("quantity")
37461
- )
37789
+ quantity: Schema9.BigDecimal
37462
37790
  });
37463
- var UpsertInvoiceSchema = Schema10.Struct({
37464
- sentAt: pipe6(
37465
- Schema10.propertySignature(Schema10.Date),
37466
- Schema10.fromKey("sent_at")
37791
+ var UpsertInvoiceSchema = Schema9.Struct({
37792
+ sentAt: pipe5(
37793
+ Schema9.propertySignature(Schema9.Date),
37794
+ Schema9.fromKey("sent_at")
37467
37795
  ),
37468
- dueAt: pipe6(
37469
- Schema10.propertySignature(Schema10.Date),
37470
- Schema10.fromKey("due_at")
37796
+ dueAt: pipe5(
37797
+ Schema9.propertySignature(Schema9.Date),
37798
+ Schema9.fromKey("due_at")
37471
37799
  ),
37472
- invoiceNumber: pipe6(
37473
- Schema10.propertySignature(Schema10.UndefinedOr(Schema10.String)),
37474
- Schema10.fromKey("invoice_number")
37800
+ invoiceNumber: pipe5(
37801
+ Schema9.propertySignature(Schema9.UndefinedOr(Schema9.String)),
37802
+ Schema9.fromKey("invoice_number")
37475
37803
  ),
37476
- customerId: pipe6(
37477
- Schema10.propertySignature(Schema10.UUID),
37478
- Schema10.fromKey("customer_id")
37804
+ customerId: pipe5(
37805
+ Schema9.propertySignature(Schema9.UUID),
37806
+ Schema9.fromKey("customer_id")
37479
37807
  ),
37480
- memo: Schema10.NullOr(Schema10.String),
37481
- lineItems: pipe6(
37482
- Schema10.propertySignature(Schema10.Array(UpsertInvoiceLineItemSchema)),
37483
- Schema10.fromKey("line_items")
37808
+ memo: Schema9.NullOr(Schema9.String),
37809
+ lineItems: pipe5(
37810
+ Schema9.propertySignature(Schema9.Array(UpsertInvoiceLineItemSchema)),
37811
+ Schema9.fromKey("line_items")
37484
37812
  ),
37485
- additionalDiscount: pipe6(
37486
- Schema10.propertySignature(Schema10.UndefinedOr(Schema10.NumberFromString.pipe(Schema10.int()))),
37487
- Schema10.fromKey("additional_discount")
37813
+ additionalDiscount: pipe5(
37814
+ Schema9.propertySignature(Schema9.UndefinedOr(Schema9.Number)),
37815
+ Schema9.fromKey("additional_discount")
37816
+ ),
37817
+ additionalSalesTaxes: pipe5(
37818
+ Schema9.propertySignature(Schema9.UndefinedOr(Schema9.Array(UpsertInvoiceTaxLineItemSchema))),
37819
+ Schema9.fromKey("additional_sales_taxes")
37820
+ )
37821
+ });
37822
+
37823
+ // src/features/invoices/api/useUpsertInvoice.tsx
37824
+ import { useCallback as useCallback53 } from "react";
37825
+ import useSWRMutation26 from "swr/mutation";
37826
+ import { Schema as Schema10, Effect } from "effect";
37827
+ var UPSERT_INVOICES_TAG_KEY = "#upsert-invoice";
37828
+ var createInvoice = post(({ businessId }) => `/v1/businesses/${businessId}/invoices`);
37829
+ var updateInvoice = put(({ businessId, invoiceId }) => `/v1/businesses/${businessId}/invoices/${invoiceId}`);
37830
+ function buildKey39({
37831
+ access_token: accessToken,
37832
+ apiUrl,
37833
+ businessId,
37834
+ invoiceId = void 0
37835
+ }) {
37836
+ if (accessToken && apiUrl) {
37837
+ return {
37838
+ accessToken,
37839
+ apiUrl,
37840
+ businessId,
37841
+ invoiceId,
37842
+ tags: [UPSERT_INVOICES_TAG_KEY]
37843
+ };
37844
+ }
37845
+ }
37846
+ var UpsertInvoiceReturnSchema = Schema10.Struct({
37847
+ data: InvoiceSchema
37848
+ });
37849
+ var UpsertInvoiceSWRResponse = class {
37850
+ constructor(swrResponse) {
37851
+ __publicField(this, "swrResponse");
37852
+ this.swrResponse = swrResponse;
37853
+ }
37854
+ get data() {
37855
+ return this.swrResponse.data;
37856
+ }
37857
+ get trigger() {
37858
+ return this.swrResponse.trigger;
37859
+ }
37860
+ get isMutating() {
37861
+ return this.swrResponse.isMutating;
37862
+ }
37863
+ get isError() {
37864
+ return this.swrResponse.error !== void 0;
37865
+ }
37866
+ };
37867
+ var CreateParamsSchema = Schema10.Struct({
37868
+ businessId: Schema10.String
37869
+ });
37870
+ var UpdateParamsSchema = Schema10.Struct({
37871
+ businessId: Schema10.String,
37872
+ invoiceId: Schema10.String
37873
+ });
37874
+ var isParamsValidForMode = (mode, params) => {
37875
+ if (mode === "Update" /* Update */) {
37876
+ return Effect.runSync(Effect.either(Schema10.decodeUnknown(UpdateParamsSchema)(params)))._tag === "Right";
37877
+ }
37878
+ if (mode === "Create" /* Create */) {
37879
+ return Effect.runSync(Effect.either(Schema10.decodeUnknown(CreateParamsSchema)(params)))._tag === "Right";
37880
+ }
37881
+ return false;
37882
+ };
37883
+ function getRequestFn(mode, params) {
37884
+ if (mode === "Update" /* Update */) {
37885
+ if (!isParamsValidForMode("Update" /* Update */, params)) {
37886
+ throw new Error("Invalid params for upsert mode");
37887
+ }
37888
+ return ({ apiUrl, accessToken, body }) => updateInvoice(apiUrl, accessToken, { params, body });
37889
+ } else {
37890
+ if (!isParamsValidForMode("Create" /* Create */, params)) {
37891
+ throw new Error("Invalid params for create mode");
37892
+ }
37893
+ return ({ apiUrl, accessToken, body }) => createInvoice(apiUrl, accessToken, { params, body });
37894
+ }
37895
+ }
37896
+ var useUpsertInvoice = (props) => {
37897
+ const { data } = useAuth();
37898
+ const { businessId } = useLayerContext();
37899
+ const { mode } = props;
37900
+ const invoiceId = mode === "Update" /* Update */ ? props.invoiceId : void 0;
37901
+ const rawMutationResponse = useSWRMutation26(
37902
+ () => buildKey39(__spreadProps(__spreadValues({}, data), {
37903
+ businessId,
37904
+ invoiceId
37905
+ })),
37906
+ ({ accessToken, apiUrl, businessId: businessId2, invoiceId: invoiceId2 }, { arg: body }) => {
37907
+ const request2 = getRequestFn(mode, { businessId: businessId2, invoiceId: invoiceId2 });
37908
+ return request2({
37909
+ apiUrl,
37910
+ accessToken,
37911
+ body
37912
+ }).then(Schema10.decodeUnknownPromise(UpsertInvoiceReturnSchema));
37913
+ },
37914
+ {
37915
+ revalidate: false
37916
+ }
37917
+ );
37918
+ const mutationResponse = new UpsertInvoiceSWRResponse(rawMutationResponse);
37919
+ const originalTrigger = mutationResponse.trigger;
37920
+ const stableProxiedTrigger = useCallback53(
37921
+ (...triggerParameters) => __async(null, null, function* () {
37922
+ const triggerResult = yield originalTrigger(...triggerParameters);
37923
+ return triggerResult;
37924
+ }),
37925
+ [originalTrigger]
37926
+ );
37927
+ return new Proxy(mutationResponse, {
37928
+ get(target, prop) {
37929
+ if (prop === "trigger") {
37930
+ return stableProxiedTrigger;
37931
+ }
37932
+ return Reflect.get(target, prop);
37933
+ }
37934
+ });
37935
+ };
37936
+
37937
+ // src/components/Invoices/InvoiceForm/useInvoiceForm.ts
37938
+ import { BigDecimal as BD4, Schema as Schema11 } from "effect";
37939
+ var EMPTY_LINE_ITEM = {
37940
+ product: "",
37941
+ description: "",
37942
+ unitPrice: 0,
37943
+ quantity: BIG_DECIMAL_ONE,
37944
+ amount: 0,
37945
+ isTaxable: false
37946
+ };
37947
+ var DEFAULT_FORM_VALUES = {
37948
+ invoiceNumber: "",
37949
+ customer: null,
37950
+ email: "",
37951
+ address: "",
37952
+ lineItems: [EMPTY_LINE_ITEM]
37953
+ };
37954
+ var getInvoiceLineItemAmount = (lineItem) => {
37955
+ const { unitPrice, quantity } = lineItem;
37956
+ return convertBigDecimalToCents(BD4.multiply(quantity, convertCentsToBigDecimal(unitPrice)));
37957
+ };
37958
+ var getAugmentedInvoiceFormLineItem = (lineItem) => {
37959
+ return __spreadProps(__spreadValues({}, lineItem), {
37960
+ amount: getInvoiceLineItemAmount(lineItem),
37961
+ isTaxable: lineItem.salesTaxTotal > 0
37962
+ });
37963
+ };
37964
+ var getInvoiceFormDefaultValues = (invoice) => {
37965
+ var _a, _b;
37966
+ return {
37967
+ invoiceNumber: invoice.invoiceNumber,
37968
+ customer: invoice.customer,
37969
+ email: (_a = invoice.customer) == null ? void 0 : _a.email,
37970
+ address: (_b = invoice.customer) == null ? void 0 : _b.addressString,
37971
+ lineItems: invoice.lineItems.map(getAugmentedInvoiceFormLineItem)
37972
+ };
37973
+ };
37974
+ var useInvoiceForm = (props) => {
37975
+ const [submitError, setSubmitError] = useState84(void 0);
37976
+ const { onSuccess, mode } = props;
37977
+ const upsertInvoiceProps = mode === "Update" /* Update */ ? { mode, invoiceId: props.invoice.id } : { mode };
37978
+ const { trigger: upsertInvoice } = useUpsertInvoice(upsertInvoiceProps);
37979
+ const defaultValues = mode === "Update" /* Update */ ? getInvoiceFormDefaultValues(props.invoice) : DEFAULT_FORM_VALUES;
37980
+ const form = useAppForm({
37981
+ defaultValues,
37982
+ onSubmit: (_0) => __async(null, [_0], function* ({ value }) {
37983
+ var _a;
37984
+ try {
37985
+ const payload = __spreadProps(__spreadValues({}, value), {
37986
+ customerId: (_a = value == null ? void 0 : value.customer) == null ? void 0 : _a.id
37987
+ });
37988
+ const invoiceParams = Schema11.validateSync(UpsertInvoiceSchema)(payload);
37989
+ const { data: invoice } = yield upsertInvoice(invoiceParams);
37990
+ setSubmitError(void 0);
37991
+ onSuccess == null ? void 0 : onSuccess(invoice);
37992
+ } catch (e) {
37993
+ setSubmitError("Something went wrong. Please try again.");
37994
+ }
37995
+ })
37996
+ });
37997
+ const isFormValid = useStore7(form.store, (state) => state.isValid);
37998
+ return { form, submitError, isFormValid };
37999
+ };
38000
+
38001
+ // src/components/Invoices/InvoiceForm/InvoiceForm.tsx
38002
+ import { Plus as Plus2, Trash as Trash2 } from "lucide-react";
38003
+ import { BigDecimal as BD5 } from "effect";
38004
+
38005
+ // src/features/customers/components/CustomerSelector.tsx
38006
+ import { useCallback as useCallback54, useId as useId5, useMemo as useMemo72 } from "react";
38007
+ import classNames90 from "classnames";
38008
+ import { jsx as jsx337, jsxs as jsxs212 } from "react/jsx-runtime";
38009
+ function getCustomerName(customer) {
38010
+ var _a, _b, _c;
38011
+ return (_c = (_b = (_a = customer.individualName) != null ? _a : customer.companyName) != null ? _b : customer.externalId) != null ? _c : "Unknown Customer";
38012
+ }
38013
+ var CustomerAsOption = class {
38014
+ constructor(customer) {
38015
+ __publicField(this, "internalCustomer");
38016
+ this.internalCustomer = customer;
38017
+ }
38018
+ get original() {
38019
+ return this.internalCustomer;
38020
+ }
38021
+ get label() {
38022
+ return getCustomerName(this.internalCustomer);
38023
+ }
38024
+ get id() {
38025
+ return this.internalCustomer.id;
38026
+ }
38027
+ get value() {
38028
+ return this.internalCustomer.id;
38029
+ }
38030
+ };
38031
+ function CustomerSelector({
38032
+ selectedCustomer,
38033
+ onSelectedCustomerChange,
38034
+ placeholder,
38035
+ isReadOnly,
38036
+ inline,
38037
+ className
38038
+ }) {
38039
+ const combinedClassName = classNames90(
38040
+ "Layer__CustomerSelector",
38041
+ inline && "Layer__CustomerSelector--inline",
38042
+ className
38043
+ );
38044
+ const { searchQuery, handleInputChange } = useDebouncedSearchInput({
38045
+ initialInputState: () => ""
38046
+ });
38047
+ const effectiveSearchQuery = searchQuery === "" ? void 0 : searchQuery;
38048
+ const { data, isLoading, isError } = useListCustomers({ query: effectiveSearchQuery });
38049
+ const options = useMemo72(
38050
+ () => (data == null ? void 0 : data.flatMap(({ data: data2 }) => data2).map((customer) => new CustomerAsOption(customer))) || [],
38051
+ [data]
38052
+ );
38053
+ const selectedCustomerId = selectedCustomer == null ? void 0 : selectedCustomer.id;
38054
+ const handleSelectionChange = useCallback54(
38055
+ (selectedOption) => {
38056
+ if (selectedOption === null) {
38057
+ handleInputChange("");
38058
+ if (selectedCustomerId) {
38059
+ onSelectedCustomerChange(null);
38060
+ }
38061
+ return;
38062
+ }
38063
+ const selectedCustomer2 = options.find(({ id }) => id === selectedOption.value);
38064
+ if (selectedCustomer2) {
38065
+ const selectedCustomerWithType = selectedCustomer2.original;
38066
+ if (selectedCustomer2.id !== selectedCustomerId) {
38067
+ onSelectedCustomerChange(selectedCustomerWithType);
38068
+ }
38069
+ handleInputChange("");
38070
+ return;
38071
+ }
38072
+ },
38073
+ [options, handleInputChange, selectedCustomerId, onSelectedCustomerChange]
38074
+ );
38075
+ const selectedCustomerForComboBox = useMemo72(
38076
+ () => {
38077
+ if (selectedCustomer === null) {
38078
+ return null;
38079
+ }
38080
+ return {
38081
+ label: getCustomerName(selectedCustomer),
38082
+ value: selectedCustomer.id
38083
+ };
38084
+ },
38085
+ [selectedCustomer]
38086
+ );
38087
+ const EmptyMessage = useMemo72(
38088
+ () => /* @__PURE__ */ jsx337(P, { variant: "subtle", children: "No matching customer" }),
38089
+ []
38090
+ );
38091
+ const ErrorMessage = useMemo72(
38092
+ () => /* @__PURE__ */ jsx337(
38093
+ P,
38094
+ {
38095
+ size: "xs",
38096
+ status: "error",
38097
+ children: "An error occurred while loading customers."
38098
+ }
38099
+ ),
38100
+ []
38101
+ );
38102
+ const inputId = useId5();
38103
+ const isFiltered = effectiveSearchQuery !== void 0;
38104
+ const noCustomersExist = !isLoading && !isFiltered && data !== void 0 && data.every(({ data: data2 }) => data2.length === 0);
38105
+ const shouldHideComponent = noCustomersExist || isReadOnly && selectedCustomer === null;
38106
+ if (shouldHideComponent) {
38107
+ return null;
38108
+ }
38109
+ const isLoadingWithoutFallback = isLoading && !data;
38110
+ const shouldDisableComboBox = isLoadingWithoutFallback || isError;
38111
+ return /* @__PURE__ */ jsxs212(VStack, { className: combinedClassName, children: [
38112
+ /* @__PURE__ */ jsx337(Label, { htmlFor: inputId, size: "sm", children: "Customer" }),
38113
+ /* @__PURE__ */ jsx337(
38114
+ ComboBox,
38115
+ {
38116
+ selectedValue: selectedCustomerForComboBox,
38117
+ onSelectedValueChange: handleSelectionChange,
38118
+ options,
38119
+ onInputValueChange: handleInputChange,
38120
+ inputId,
38121
+ placeholder,
38122
+ slots: { EmptyMessage, ErrorMessage },
38123
+ isDisabled: isReadOnly || shouldDisableComboBox,
38124
+ isError,
38125
+ isLoading: isLoadingWithoutFallback
38126
+ }
38127
+ )
38128
+ ] });
38129
+ }
38130
+
38131
+ // src/components/Invoices/InvoiceForm/InvoiceForm.tsx
38132
+ import { jsx as jsx338, jsxs as jsxs213 } from "react/jsx-runtime";
38133
+ var INVOICE_FORM_CSS_PREFIX = "Layer__InvoiceForm";
38134
+ var INVOICE_FORM_FIELD_CSS_PREFIX = `${INVOICE_FORM_CSS_PREFIX}__Field`;
38135
+ var InvoiceForm = (props) => {
38136
+ const { onSuccess, mode } = props;
38137
+ const { form } = useInvoiceForm(
38138
+ __spreadValues({ onSuccess }, mode === "Update" /* Update */ ? { mode, invoice: props.invoice } : { mode })
38139
+ );
38140
+ return /* @__PURE__ */ jsxs213(Form, { className: INVOICE_FORM_CSS_PREFIX, children: [
38141
+ /* @__PURE__ */ jsxs213(VStack, { className: `${INVOICE_FORM_CSS_PREFIX}__Metadata`, gap: "xs", children: [
38142
+ /* @__PURE__ */ jsx338(
38143
+ form.Field,
38144
+ {
38145
+ name: "customer",
38146
+ listeners: {
38147
+ onChange: ({ value: customer }) => {
38148
+ form.setFieldValue("email", customer == null ? void 0 : customer.email);
38149
+ form.setFieldValue("address", customer == null ? void 0 : customer.addressString);
38150
+ }
38151
+ },
38152
+ children: (field) => /* @__PURE__ */ jsx338(
38153
+ CustomerSelector,
38154
+ {
38155
+ className: `${INVOICE_FORM_FIELD_CSS_PREFIX}__Customer`,
38156
+ selectedCustomer: field.state.value,
38157
+ onSelectedCustomerChange: field.handleChange,
38158
+ inline: true
38159
+ }
38160
+ )
38161
+ }
38162
+ ),
38163
+ /* @__PURE__ */ jsx338(form.AppField, { name: "email", children: (field) => /* @__PURE__ */ jsx338(field.FormTextField, { label: "Email", inline: true, className: `${INVOICE_FORM_FIELD_CSS_PREFIX}__Email` }) }),
38164
+ /* @__PURE__ */ jsx338(form.AppField, { name: "address", children: (field) => /* @__PURE__ */ jsx338(field.FormTextAreaField, { label: "Billing address", inline: true, className: `${INVOICE_FORM_FIELD_CSS_PREFIX}__Address` }) })
38165
+ ] }),
38166
+ /* @__PURE__ */ jsx338(VStack, { className: `${INVOICE_FORM_CSS_PREFIX}__LineItems`, gap: "xs", children: /* @__PURE__ */ jsx338(form.AppField, { name: "lineItems", mode: "array", children: (field) => /* @__PURE__ */ jsxs213(VStack, { gap: "xs", align: "baseline", children: [
38167
+ field.state.value.map((_, index) => /* @__PURE__ */ jsxs213(HStack, { gap: "xs", align: "end", className: `${INVOICE_FORM_CSS_PREFIX}__LineItem`, children: [
38168
+ /* @__PURE__ */ jsx338(form.AppField, { name: `lineItems[${index}].product`, children: (innerField) => /* @__PURE__ */ jsx338(innerField.FormTextField, { label: "Product", showLabel: index === 0 }) }),
38169
+ /* @__PURE__ */ jsx338(form.AppField, { name: `lineItems[${index}].description`, children: (innerField) => /* @__PURE__ */ jsx338(innerField.FormTextField, { label: "Description", showLabel: index === 0 }) }),
38170
+ /* @__PURE__ */ jsx338(
38171
+ form.AppField,
38172
+ {
38173
+ name: `lineItems[${index}].quantity`,
38174
+ listeners: {
38175
+ onBlur: ({ value: quantity }) => {
38176
+ const unitPrice = form.getFieldValue(`lineItems[${index}].unitPrice`);
38177
+ const nextAmount = BD5.multiply(convertCentsToBigDecimal(unitPrice), quantity);
38178
+ form.setFieldValue(`lineItems[${index}].amount`, convertBigDecimalToCents(nextAmount));
38179
+ }
38180
+ },
38181
+ children: (innerField) => /* @__PURE__ */ jsx338(innerField.FormBigDecimalField, { label: "Quantity", showLabel: index === 0 })
38182
+ }
38183
+ ),
38184
+ /* @__PURE__ */ jsx338(
38185
+ form.AppField,
38186
+ {
38187
+ name: `lineItems[${index}].unitPrice`,
38188
+ listeners: {
38189
+ onBlur: ({ value: unitPrice }) => {
38190
+ const quantity = form.getFieldValue(`lineItems[${index}].quantity`);
38191
+ const nextAmount = BD5.multiply(convertCentsToBigDecimal(unitPrice), quantity);
38192
+ form.setFieldValue(`lineItems[${index}].amount`, convertBigDecimalToCents(nextAmount));
38193
+ }
38194
+ },
38195
+ children: (innerField) => /* @__PURE__ */ jsx338(innerField.FormCurrencyField, { label: "Rate", showLabel: index === 0 })
38196
+ }
38197
+ ),
38198
+ /* @__PURE__ */ jsx338(
38199
+ form.AppField,
38200
+ {
38201
+ name: `lineItems[${index}].amount`,
38202
+ listeners: {
38203
+ onBlur: ({ value: amount }) => {
38204
+ const quantity = form.getFieldValue(`lineItems[${index}].quantity`);
38205
+ let nextUnitPrice = BIG_DECIMAL_ZERO;
38206
+ try {
38207
+ nextUnitPrice = BD5.unsafeDivide(convertCentsToBigDecimal(amount), quantity);
38208
+ } catch (e) {
38209
+ }
38210
+ form.setFieldValue(`lineItems[${index}].unitPrice`, convertBigDecimalToCents(nextUnitPrice));
38211
+ }
38212
+ },
38213
+ children: (innerField) => /* @__PURE__ */ jsx338(innerField.FormCurrencyField, { label: "Amount", showLabel: index === 0 })
38214
+ }
38215
+ ),
38216
+ /* @__PURE__ */ jsx338(form.AppField, { name: `lineItems[${index}].isTaxable`, children: (innerField) => /* @__PURE__ */ jsx338(innerField.FormCheckboxField, { label: "Tax", showLabel: index === 0 }) }),
38217
+ /* @__PURE__ */ jsx338(Button2, { variant: "outlined", icon: true, "aria-label": "Delete line item", onClick: () => field.removeValue(index), children: /* @__PURE__ */ jsx338(Trash2, { size: 16 }) })
38218
+ ] }, `lineItems[${index}]`)),
38219
+ /* @__PURE__ */ jsxs213(Button2, { variant: "outlined", onClick: () => field.pushValue(EMPTY_LINE_ITEM), children: [
38220
+ "Add line item",
38221
+ /* @__PURE__ */ jsx338(Plus2, { size: 16 })
38222
+ ] })
38223
+ ] }) }) })
38224
+ ] });
38225
+ };
38226
+
38227
+ // src/components/DataPoint/DataPoint.tsx
38228
+ import { jsx as jsx339, jsxs as jsxs214 } from "react/jsx-runtime";
38229
+ var DataPoint = ({ label, children }) => {
38230
+ return /* @__PURE__ */ jsxs214(VStack, { gap: "3xs", children: [
38231
+ /* @__PURE__ */ jsx339(Span, { variant: "subtle", size: "xs", children: label }),
38232
+ children
38233
+ ] });
38234
+ };
38235
+
38236
+ // src/components/Invoices/InvoiceStatusCell/InvoiceStatusCell.tsx
38237
+ import pluralize6 from "pluralize";
38238
+ import { jsx as jsx340, jsxs as jsxs215 } from "react/jsx-runtime";
38239
+ var getDueStatusConfig = (invoice, { inline }) => {
38240
+ const badgeSize = inline ? "xs" /* EXTRA_SMALL */ : "small" /* SMALL */;
38241
+ const iconSize = inline ? 10 : 12;
38242
+ switch (invoice.status) {
38243
+ case "WRITTEN_OFF" /* WrittenOff */: {
38244
+ return { text: "Written Off" };
38245
+ }
38246
+ case "PARTIALLY_WRITTEN_OFF" /* PartiallyWrittenOff */: {
38247
+ return { text: "Partially Written Off" };
38248
+ }
38249
+ case "PAID" /* Paid */: {
38250
+ return {
38251
+ text: "Paid",
38252
+ badge: /* @__PURE__ */ jsx340(Badge, { variant: "success" /* SUCCESS */, size: badgeSize, icon: /* @__PURE__ */ jsx340(CheckCircle_default, { size: iconSize }), iconOnly: true })
38253
+ };
38254
+ }
38255
+ case "VOIDED" /* Voided */: {
38256
+ return { text: "Voided" };
38257
+ }
38258
+ case "SENT" /* Sent */:
38259
+ case "PARTIALLY_PAID" /* PartiallyPaid */: {
38260
+ if (invoice.dueAt === null) {
38261
+ return {
38262
+ text: invoice.status === "PARTIALLY_PAID" /* PartiallyPaid */ ? "Partially Paid" : "Sent"
38263
+ };
38264
+ }
38265
+ const dueDifference = getDueDifference(invoice.dueAt);
38266
+ if (dueDifference === 0) {
38267
+ return {
38268
+ text: "Due Today"
38269
+ };
38270
+ }
38271
+ if (dueDifference < 0) {
38272
+ return {
38273
+ text: "Overdue",
38274
+ subText: `Due ${pluralize6("day", Math.abs(dueDifference), true)} ago`,
38275
+ badge: /* @__PURE__ */ jsx340(Badge, { variant: "warning" /* WARNING */, size: badgeSize, icon: /* @__PURE__ */ jsx340(AlertCircle_default, { size: iconSize }), iconOnly: true })
38276
+ };
38277
+ }
38278
+ return {
38279
+ text: "Sent",
38280
+ subText: `Due in ${pluralize6("day", Math.abs(dueDifference), true)}`
38281
+ };
38282
+ }
38283
+ default: {
38284
+ unsafeAssertUnreachable({
38285
+ value: invoice.status,
38286
+ message: "Unexpected invoice status"
38287
+ });
38288
+ }
38289
+ }
38290
+ };
38291
+ var InvoiceStatusCell = ({ invoice, inline = false }) => {
38292
+ const dueStatus = getDueStatusConfig(invoice, { inline });
38293
+ const Stack3 = inline ? HStack : VStack;
38294
+ const subText = inline && dueStatus.subText ? `(${dueStatus.subText})` : dueStatus.subText;
38295
+ return /* @__PURE__ */ jsxs215(HStack, { gap: "xs", align: "center", children: [
38296
+ dueStatus.badge,
38297
+ /* @__PURE__ */ jsxs215(Stack3, __spreadProps(__spreadValues({}, inline && { gap: "3xs", align: "center" }), { children: [
38298
+ /* @__PURE__ */ jsx340(Span, { children: dueStatus.text }),
38299
+ subText && /* @__PURE__ */ jsx340(Span, { variant: "subtle", size: "sm", children: subText })
38300
+ ] }))
38301
+ ] });
38302
+ };
38303
+
38304
+ // src/components/Invoices/InvoiceDetail/InvoiceDetail.tsx
38305
+ import { jsx as jsx341, jsxs as jsxs216 } from "react/jsx-runtime";
38306
+ var InvoiceDetail = (props) => {
38307
+ const _a = props, { onSuccess: _onSuccess, onGoBack } = _a, restProps = __objRest(_a, ["onSuccess", "onGoBack"]);
38308
+ const Header6 = useCallback55(() => {
38309
+ return /* @__PURE__ */ jsx341(InvoiceDetailHeader, __spreadValues({}, restProps));
38310
+ }, [restProps]);
38311
+ return /* @__PURE__ */ jsxs216(BaseDetailView, { slots: { Header: Header6 }, name: "Invoice Detail View", onGoBack, children: [
38312
+ restProps.mode === "Update" /* Update */ && /* @__PURE__ */ jsx341(InvoiceDetailSubHeader, { invoice: restProps.invoice }),
38313
+ /* @__PURE__ */ jsx341(InvoiceForm, __spreadValues({}, props))
38314
+ ] });
38315
+ };
38316
+ var InvoiceDetailHeader = (props) => {
38317
+ const { mode } = props;
38318
+ if (mode === "Create" /* Create */) {
38319
+ return /* @__PURE__ */ jsx341(Heading2, { children: "Create Invoice" });
38320
+ }
38321
+ const invoice = props.invoice;
38322
+ const { invoiceNumber } = invoice;
38323
+ return /* @__PURE__ */ jsx341(Heading2, { children: invoiceNumber ? `Invoice ${invoiceNumber}` : "View Invoice" });
38324
+ };
38325
+ var InvoiceDetailSubHeader = ({ invoice }) => {
38326
+ const { outstandingBalance, totalAmount } = invoice;
38327
+ return /* @__PURE__ */ jsx341(HStack, { className: "Layer__InvoiceDetail__SubHeader", children: /* @__PURE__ */ jsxs216(HStack, { gap: "5xl", children: [
38328
+ /* @__PURE__ */ jsx341(DataPoint, { label: "Balance due", children: /* @__PURE__ */ jsx341(Span, { children: convertCentsToCurrency(outstandingBalance) }) }),
38329
+ /* @__PURE__ */ jsx341(DataPoint, { label: "Open balance", children: /* @__PURE__ */ jsx341(Span, { children: convertCentsToCurrency(totalAmount) }) }),
38330
+ /* @__PURE__ */ jsx341(DataPoint, { label: "Status", children: /* @__PURE__ */ jsx341(InvoiceStatusCell, { invoice, inline: true }) })
38331
+ ] }) });
38332
+ };
38333
+
38334
+ // src/components/Invoices/InvoicesTable/InvoicesTable.tsx
38335
+ import { useCallback as useCallback58, useMemo as useMemo76, useState as useState86 } from "react";
38336
+
38337
+ // src/features/invoices/api/useListInvoices.tsx
38338
+ import useSWRInfinite7 from "swr/infinite";
38339
+ var import_lodash6 = __toESM(require_lodash2());
38340
+ import { useCallback as useCallback56, useMemo as useMemo73 } from "react";
38341
+ import { Schema as Schema13 } from "effect";
38342
+
38343
+ // src/types/utility/pagination.ts
38344
+ import { Schema as Schema12, pipe as pipe6 } from "effect";
38345
+ var PaginatedResponseMetaSchema = Schema12.Struct({
38346
+ cursor: Schema12.NullOr(Schema12.String),
38347
+ hasMore: pipe6(
38348
+ Schema12.propertySignature(Schema12.Boolean),
38349
+ Schema12.fromKey("has_more")
37488
38350
  ),
37489
- additionalSalesTaxes: pipe6(
37490
- Schema10.propertySignature(Schema10.UndefinedOr(Schema10.Array(UpsertInvoiceTaxLineItemSchema))),
37491
- Schema10.fromKey("additional_sales_taxes")
38351
+ totalCount: pipe6(
38352
+ Schema12.propertySignature(Schema12.UndefinedOr(Schema12.Number)),
38353
+ Schema12.fromKey("total_count")
37492
38354
  )
37493
38355
  });
37494
38356
 
37495
38357
  // src/features/invoices/api/useListInvoices.tsx
37496
38358
  var LIST_INVOICES_TAG_KEY = "#list-invoices";
37497
- var ListInvoicesReturnSchema = Schema11.Struct({
37498
- data: Schema11.Array(InvoiceSchema),
37499
- meta: Schema11.Struct({
38359
+ var ListInvoicesReturnSchema = Schema13.Struct({
38360
+ data: Schema13.Array(InvoiceSchema),
38361
+ meta: Schema13.Struct({
37500
38362
  pagination: PaginatedResponseMetaSchema
37501
38363
  })
37502
38364
  });
@@ -37624,7 +38486,7 @@ function useListInvoices({
37624
38486
  showTotalCount: showTotalCount2
37625
38487
  }
37626
38488
  }
37627
- )().then(Schema11.decodeUnknownPromise(ListInvoicesReturnSchema)),
38489
+ )().then(Schema13.decodeUnknownPromise(ListInvoicesReturnSchema)),
37628
38490
  {
37629
38491
  keepPreviousData: true,
37630
38492
  revalidateFirstPage: false,
@@ -37643,10 +38505,10 @@ import {
37643
38505
  } from "@tanstack/react-table";
37644
38506
 
37645
38507
  // src/components/DataTable/DataTable.tsx
37646
- import { useMemo as useMemo72 } from "react";
38508
+ import { useMemo as useMemo74 } from "react";
37647
38509
 
37648
38510
  // src/components/ui/Table/Table.tsx
37649
- import { forwardRef as forwardRef20 } from "react";
38511
+ import { forwardRef as forwardRef24 } from "react";
37650
38512
  import {
37651
38513
  Cell as ReactAriaCell,
37652
38514
  Column as ReactAriaColumn,
@@ -37655,14 +38517,14 @@ import {
37655
38517
  TableBody as ReactAriaTableBody,
37656
38518
  TableHeader as ReactAriaTableHeader
37657
38519
  } from "react-aria-components";
37658
- import classNames88 from "classnames";
37659
- import { jsx as jsx326 } from "react/jsx-runtime";
38520
+ import classNames91 from "classnames";
38521
+ import { jsx as jsx342 } from "react/jsx-runtime";
37660
38522
  var CSS_PREFIX2 = "Layer__UI__Table";
37661
- var getClassName = (component, additionalClassNames) => classNames88(`${CSS_PREFIX2}-${component}`, additionalClassNames);
37662
- var Table2 = forwardRef20(
38523
+ var getClassName = (component, additionalClassNames) => classNames91(`${CSS_PREFIX2}-${component}`, additionalClassNames);
38524
+ var Table2 = forwardRef24(
37663
38525
  (_a, ref) => {
37664
38526
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37665
- return /* @__PURE__ */ jsx326(
38527
+ return /* @__PURE__ */ jsx342(
37666
38528
  ReactAriaTable,
37667
38529
  __spreadProps(__spreadValues({
37668
38530
  className: getClassName("Table" /* Table */, className)
@@ -37676,7 +38538,7 @@ var Table2 = forwardRef20(
37676
38538
  Table2.displayName = "Table" /* Table */;
37677
38539
  var TableHeaderInner = (_a, ref) => {
37678
38540
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37679
- return /* @__PURE__ */ jsx326(
38541
+ return /* @__PURE__ */ jsx342(
37680
38542
  ReactAriaTableHeader,
37681
38543
  __spreadProps(__spreadValues({
37682
38544
  className: getClassName("TableHeader" /* TableHeader */, className)
@@ -37686,11 +38548,11 @@ var TableHeaderInner = (_a, ref) => {
37686
38548
  })
37687
38549
  );
37688
38550
  };
37689
- var TableHeader = forwardRef20(TableHeaderInner);
38551
+ var TableHeader = forwardRef24(TableHeaderInner);
37690
38552
  TableHeader.displayName = "TableHeader" /* TableHeader */;
37691
38553
  var TableBodyInner = (_a, ref) => {
37692
38554
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37693
- return /* @__PURE__ */ jsx326(
38555
+ return /* @__PURE__ */ jsx342(
37694
38556
  ReactAriaTableBody,
37695
38557
  __spreadProps(__spreadValues({
37696
38558
  className: getClassName("TableBody" /* TableBody */, className)
@@ -37700,11 +38562,11 @@ var TableBodyInner = (_a, ref) => {
37700
38562
  })
37701
38563
  );
37702
38564
  };
37703
- var TableBody2 = forwardRef20(TableBodyInner);
38565
+ var TableBody2 = forwardRef24(TableBodyInner);
37704
38566
  TableBody2.displayName = "TableBody" /* TableBody */;
37705
38567
  var RowInner = (_a, ref) => {
37706
38568
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37707
- return /* @__PURE__ */ jsx326(
38569
+ return /* @__PURE__ */ jsx342(
37708
38570
  ReactAriaTableRow,
37709
38571
  __spreadProps(__spreadValues({
37710
38572
  className: getClassName("Row" /* Row */, className)
@@ -37714,13 +38576,13 @@ var RowInner = (_a, ref) => {
37714
38576
  })
37715
38577
  );
37716
38578
  };
37717
- var Row2 = forwardRef20(RowInner);
38579
+ var Row2 = forwardRef24(RowInner);
37718
38580
  Row2.displayName = "Row" /* Row */;
37719
- var Column = forwardRef20(
38581
+ var Column = forwardRef24(
37720
38582
  (_a, ref) => {
37721
38583
  var _b = _a, { children, className, textAlign = "left" } = _b, restProps = __objRest(_b, ["children", "className", "textAlign"]);
37722
38584
  const dataProperties = toDataProperties({ "text-align": textAlign });
37723
- return /* @__PURE__ */ jsx326(
38585
+ return /* @__PURE__ */ jsx342(
37724
38586
  ReactAriaColumn,
37725
38587
  __spreadProps(__spreadValues(__spreadValues({
37726
38588
  className: getClassName("Column" /* Column */, className)
@@ -37732,10 +38594,10 @@ var Column = forwardRef20(
37732
38594
  }
37733
38595
  );
37734
38596
  Column.displayName = "Column" /* Column */;
37735
- var Cell5 = forwardRef20(
38597
+ var Cell5 = forwardRef24(
37736
38598
  (_a, ref) => {
37737
38599
  var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
37738
- return /* @__PURE__ */ jsx326(
38600
+ return /* @__PURE__ */ jsx342(
37739
38601
  ReactAriaCell,
37740
38602
  __spreadProps(__spreadValues({
37741
38603
  className: getClassName("Cell" /* Cell */, className)
@@ -37749,7 +38611,7 @@ var Cell5 = forwardRef20(
37749
38611
  Cell5.displayName = "Cell" /* Cell */;
37750
38612
 
37751
38613
  // src/components/DataTable/DataTable.tsx
37752
- import { jsx as jsx327, jsxs as jsxs210 } from "react/jsx-runtime";
38614
+ import { jsx as jsx343, jsxs as jsxs217 } from "react/jsx-runtime";
37753
38615
  var DataTable = ({
37754
38616
  columnConfig,
37755
38617
  data,
@@ -37759,19 +38621,20 @@ var DataTable = ({
37759
38621
  ariaLabel,
37760
38622
  slots
37761
38623
  }) => {
37762
- const columns2 = Object.values(columnConfig);
38624
+ const columns = Object.values(columnConfig);
37763
38625
  const { EmptyState, ErrorState } = slots;
37764
- const renderTableBody = useMemo72(() => {
38626
+ const isEmptyTable = (data == null ? void 0 : data.length) === 0;
38627
+ const renderTableBody = useMemo74(() => {
37765
38628
  if (isError) {
37766
- return /* @__PURE__ */ jsx327(Row2, { children: /* @__PURE__ */ jsx327(Cell5, { colSpan: columns2.length, children: /* @__PURE__ */ jsx327(ErrorState, {}) }) });
38629
+ return /* @__PURE__ */ jsx343(Row2, { children: /* @__PURE__ */ jsx343(Cell5, { colSpan: columns.length, children: /* @__PURE__ */ jsx343(ErrorState, {}) }) });
37767
38630
  }
37768
38631
  if (isLoading) {
37769
- return /* @__PURE__ */ jsx327(Row2, { children: /* @__PURE__ */ jsx327(Cell5, { colSpan: columns2.length, children: /* @__PURE__ */ jsx327(Loader2, {}) }) });
38632
+ return /* @__PURE__ */ jsx343(Row2, { children: /* @__PURE__ */ jsx343(Cell5, { colSpan: columns.length, children: /* @__PURE__ */ jsx343(Loader2, {}) }) });
37770
38633
  }
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, {}) }) });
38634
+ if (isEmptyTable) {
38635
+ return /* @__PURE__ */ jsx343(Row2, { children: /* @__PURE__ */ jsx343(Cell5, { colSpan: columns.length, children: /* @__PURE__ */ jsx343(EmptyState, {}) }) });
37773
38636
  }
37774
- const RowRenderer = (row) => /* @__PURE__ */ jsx327(Row2, { children: columns2.map((col) => /* @__PURE__ */ jsx327(
38637
+ const RowRenderer = (row) => /* @__PURE__ */ jsx343(Row2, { children: columns.map((col) => /* @__PURE__ */ jsx343(
37775
38638
  Cell5,
37776
38639
  {
37777
38640
  className: `Layer__UI__Table-Cell__${componentName}--${col.id}`,
@@ -37781,16 +38644,16 @@ var DataTable = ({
37781
38644
  )) }, row.id);
37782
38645
  RowRenderer.displayName = "Row";
37783
38646
  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 })
38647
+ }, [isError, isLoading, isEmptyTable, columns, ErrorState, EmptyState, componentName]);
38648
+ return /* @__PURE__ */ jsxs217(Table2, { "aria-label": ariaLabel, className: `Layer__UI__Table__${componentName}`, children: [
38649
+ /* @__PURE__ */ jsx343(TableHeader, { columns, children: ({ id, header, isRowHeader }) => /* @__PURE__ */ jsx343(Column, { isRowHeader, className: `Layer__UI__Table-Column__${componentName}--${id}`, children: header }, id) }),
38650
+ /* @__PURE__ */ jsx343(TableBody2, { items: data, children: renderTableBody })
37788
38651
  ] });
37789
38652
  };
37790
38653
 
37791
38654
  // 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";
38655
+ import { useCallback as useCallback57, useMemo as useMemo75, useState as useState85 } from "react";
38656
+ import { jsx as jsx344, jsxs as jsxs218 } from "react/jsx-runtime";
37794
38657
  var EMPTY_ARRAY = [];
37795
38658
  function PaginatedTable({
37796
38659
  data,
@@ -37803,10 +38666,10 @@ function PaginatedTable({
37803
38666
  slots
37804
38667
  }) {
37805
38668
  const { pageSize = 20, hasMore, fetchMore } = paginationProps;
37806
- const [pagination, setPagination] = useState82({ pageIndex: 0, pageSize });
38669
+ const [pagination, setPagination] = useState85({ pageIndex: 0, pageSize });
37807
38670
  const columnHelper = createColumnHelper();
37808
- const columns2 = Object.values(columnConfig);
37809
- const columnDefs = columns2.map((col) => {
38671
+ const columns = Object.values(columnConfig);
38672
+ const columnDefs = columns.map((col) => {
37810
38673
  return columnHelper.display({
37811
38674
  id: col.id,
37812
38675
  header: () => col.header,
@@ -37823,12 +38686,12 @@ function PaginatedTable({
37823
38686
  autoResetPageIndex: false
37824
38687
  });
37825
38688
  const { rows } = table.getRowModel();
37826
- const rowData = useMemo73(() => rows.map((r) => r.original), [rows]);
37827
- const onPageChange = useCallback49((page) => {
38689
+ const rowData = useMemo75(() => rows.map((r) => r.original), [rows]);
38690
+ const onPageChange = useCallback57((page) => {
37828
38691
  table.setPageIndex(page - 1);
37829
38692
  }, [table]);
37830
- return /* @__PURE__ */ jsxs211(VStack, { children: [
37831
- /* @__PURE__ */ jsx328(
38693
+ return /* @__PURE__ */ jsxs218(VStack, { children: [
38694
+ /* @__PURE__ */ jsx344(
37832
38695
  DataTable,
37833
38696
  {
37834
38697
  ariaLabel,
@@ -37840,7 +38703,7 @@ function PaginatedTable({
37840
38703
  slots
37841
38704
  }
37842
38705
  ),
37843
- !isError && !isLoading && /* @__PURE__ */ jsx328(
38706
+ !isError && !isLoading && /* @__PURE__ */ jsx344(
37844
38707
  Pagination,
37845
38708
  {
37846
38709
  currentPage: table.getState().pagination.pageIndex + 1,
@@ -37854,14 +38717,11 @@ function PaginatedTable({
37854
38717
  ] });
37855
38718
  }
37856
38719
 
37857
- // src/components/Invoices/InvoicesTable.tsx
37858
- import pluralize6 from "pluralize";
37859
-
37860
38720
  // src/icons/ChevronRightFill.tsx
37861
- import { jsx as jsx329, jsxs as jsxs212 } from "react/jsx-runtime";
38721
+ import { jsx as jsx345, jsxs as jsxs219 } from "react/jsx-runtime";
37862
38722
  var ChevronRightFill = (_a) => {
37863
38723
  var _b = _a, { size = 18 } = _b, props = __objRest(_b, ["size"]);
37864
- return /* @__PURE__ */ jsxs212(
38724
+ return /* @__PURE__ */ jsxs219(
37865
38725
  "svg",
37866
38726
  __spreadProps(__spreadValues({
37867
38727
  xmlns: "http://www.w3.org/2000/svg",
@@ -37871,8 +38731,8 @@ var ChevronRightFill = (_a) => {
37871
38731
  width: size,
37872
38732
  height: size,
37873
38733
  children: [
37874
- /* @__PURE__ */ jsx329("path", { d: "M6.75 4.5L11.25 9L6.75 13.5", fill: "currentColor" }),
37875
- /* @__PURE__ */ jsx329(
38734
+ /* @__PURE__ */ jsx345("path", { d: "M6.75 4.5L11.25 9L6.75 13.5", fill: "currentColor" }),
38735
+ /* @__PURE__ */ jsx345(
37876
38736
  "path",
37877
38737
  {
37878
38738
  d: "M6.75 4.5L11.25 9L6.75 13.5Z",
@@ -37887,38 +38747,38 @@ var ChevronRightFill = (_a) => {
37887
38747
  };
37888
38748
  var ChevronRightFill_default = ChevronRightFill;
37889
38749
 
37890
- // src/components/Invoices/InvoicesTable.tsx
37891
- import { HandCoins, Search as Search2, Plus as Plus2 } from "lucide-react";
38750
+ // src/components/Invoices/InvoicesTable/InvoicesTable.tsx
38751
+ import { HandCoins, Search as Search2, Plus as Plus3 } from "lucide-react";
37892
38752
 
37893
38753
  // src/components/DataTable/DataTableHeader.tsx
37894
- import { jsx as jsx330, jsxs as jsxs213 } from "react/jsx-runtime";
38754
+ import { jsx as jsx346, jsxs as jsxs220 } from "react/jsx-runtime";
37895
38755
  var DataTableHeader = ({ name, count, slotProps = {}, slots = {} }) => {
37896
38756
  const { showCount, totalCount } = count != null ? count : {};
37897
38757
  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, {}))
38758
+ return /* @__PURE__ */ jsxs220(VStack, { children: [
38759
+ /* @__PURE__ */ jsxs220(HStack, { justify: "space-between", align: "center", className: "Layer__DataTableHeader__Header", children: [
38760
+ /* @__PURE__ */ jsxs220(HStack, { pis: "md", align: "center", gap: "xl", children: [
38761
+ /* @__PURE__ */ jsxs220(HStack, { align: "center", gap: "sm", children: [
38762
+ /* @__PURE__ */ jsx346(Span, { weight: "bold", size: "lg", children: name }),
38763
+ showCount && (totalCount ? /* @__PURE__ */ jsx346(Badge, { variant: "default" /* DEFAULT */, size: "medium" /* MEDIUM */, children: totalCount }) : /* @__PURE__ */ jsx346(BadgeLoader, {}))
37904
38764
  ] }),
37905
- HeaderFilters && /* @__PURE__ */ jsx330(HeaderFilters, {})
38765
+ HeaderFilters && /* @__PURE__ */ jsx346(HeaderFilters, {})
37906
38766
  ] }),
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, {})
38767
+ /* @__PURE__ */ jsxs220(HStack, { pie: "md", align: "center", gap: "3xs", children: [
38768
+ slotProps.SearchField && /* @__PURE__ */ jsx346(SearchField, __spreadValues({}, slotProps.SearchField)),
38769
+ HeaderActions && /* @__PURE__ */ jsx346(HeaderActions, {})
37910
38770
  ] })
37911
38771
  ] }),
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" }))
38772
+ Filters2 && /* @__PURE__ */ jsxs220(HStack, { pis: "md", pie: "md", justify: "space-between", align: "center", className: "Layer__DataTableHeader__Filters", children: [
38773
+ /* @__PURE__ */ jsx346(Filters2, {}),
38774
+ slotProps.ClearFiltersButton && /* @__PURE__ */ jsx346(Button2, __spreadProps(__spreadValues({ variant: "outlined" }, slotProps.ClearFiltersButton), { children: "Clear All Filters" }))
37915
38775
  ] })
37916
38776
  ] });
37917
38777
  };
37918
38778
 
37919
- // src/components/Invoices/InvoicesTable.tsx
38779
+ // src/components/Invoices/InvoicesTable/InvoicesTable.tsx
37920
38780
  import { startOfToday, endOfYesterday } from "date-fns";
37921
- import { jsx as jsx331, jsxs as jsxs214 } from "react/jsx-runtime";
38781
+ import { jsx as jsx347, jsxs as jsxs221 } from "react/jsx-runtime";
37922
38782
  var COMPONENT_NAME10 = "InvoicesTable";
37923
38783
  var InvoiceStatusOptionConfig = {
37924
38784
  ["All" /* All */]: { label: "All", value: "All" /* All */ },
@@ -37939,12 +38799,12 @@ var AmountCell = ({ invoice }) => {
37939
38799
  case "WRITTEN_OFF" /* WrittenOff */:
37940
38800
  case "VOIDED" /* Voided */:
37941
38801
  case "SENT" /* Sent */: {
37942
- return /* @__PURE__ */ jsx331(VStack, { children: /* @__PURE__ */ jsx331(Span, { align: "right", children: totalAmount }) });
38802
+ return /* @__PURE__ */ jsx347(VStack, { children: /* @__PURE__ */ jsx347(Span, { align: "right", children: totalAmount }) });
37943
38803
  }
37944
38804
  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: [
38805
+ return /* @__PURE__ */ jsxs221(VStack, { children: [
38806
+ /* @__PURE__ */ jsx347(Span, { align: "right", children: totalAmount }),
38807
+ /* @__PURE__ */ jsxs221(Span, { align: "right", variant: "subtle", size: "sm", children: [
37948
38808
  outstandingBalance,
37949
38809
  " ",
37950
38810
  "outstanding"
@@ -37959,71 +38819,11 @@ var AmountCell = ({ invoice }) => {
37959
38819
  }
37960
38820
  }
37961
38821
  };
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) => {
38822
+ var getCustomerName2 = (invoice) => {
38023
38823
  const { recipientName, customer } = invoice;
38024
38824
  return recipientName || (customer == null ? void 0 : customer.individualName) || (customer == null ? void 0 : customer.companyName);
38025
38825
  };
38026
- var columns = {
38826
+ var getColumnConfig = (onSelectInvoice) => ({
38027
38827
  ["SentAt" /* SentAt */]: {
38028
38828
  id: "SentAt" /* SentAt */,
38029
38829
  header: "Sent Date",
@@ -38038,35 +38838,35 @@ var columns = {
38038
38838
  ["Customer" /* Customer */]: {
38039
38839
  id: "Customer" /* Customer */,
38040
38840
  header: "Customer",
38041
- cell: (row) => getCustomerName(row)
38841
+ cell: (row) => getCustomerName2(row)
38042
38842
  },
38043
38843
  ["Total" /* Total */]: {
38044
38844
  id: "Total" /* Total */,
38045
38845
  header: "Amount",
38046
- cell: (row) => /* @__PURE__ */ jsx331(AmountCell, { invoice: row })
38846
+ cell: (row) => /* @__PURE__ */ jsx347(AmountCell, { invoice: row })
38047
38847
  },
38048
38848
  ["Status" /* Status */]: {
38049
38849
  id: "Status" /* Status */,
38050
38850
  header: "Status",
38051
- cell: (row) => /* @__PURE__ */ jsx331(StatusCell, { invoice: row })
38851
+ cell: (row) => /* @__PURE__ */ jsx347(InvoiceStatusCell, { invoice: row })
38052
38852
  },
38053
38853
  ["Expand" /* Expand */]: {
38054
38854
  id: "Expand" /* Expand */,
38055
- cell: (_row) => /* @__PURE__ */ jsx331(Button2, { inset: true, icon: true, "aria-label": "View invoice", variant: "ghost", children: /* @__PURE__ */ jsx331(ChevronRightFill_default, {}) })
38855
+ cell: (row) => /* @__PURE__ */ jsx347(Button2, { inset: true, icon: true, onPress: () => onSelectInvoice(row), "aria-label": "View invoice", variant: "ghost", children: /* @__PURE__ */ jsx347(ChevronRightFill_default, {}) })
38056
38856
  }
38057
- };
38058
- var unpaidStatuses = ["SENT" /* Sent */, "PARTIALLY_PAID" /* PartiallyPaid */];
38857
+ });
38858
+ var UNPAID_STATUSES2 = ["SENT" /* Sent */, "PARTIALLY_PAID" /* PartiallyPaid */];
38059
38859
  var getListInvoiceParams = ({ statusFilter }) => {
38060
38860
  if (!statusFilter) return {};
38061
38861
  switch (statusFilter) {
38062
38862
  case "All" /* All */:
38063
38863
  return {};
38064
38864
  case "Unpaid" /* Unpaid */:
38065
- return { status: unpaidStatuses };
38865
+ return { status: UNPAID_STATUSES2 };
38066
38866
  case "Overdue" /* Overdue */:
38067
- return { status: unpaidStatuses, dueAtEnd: endOfYesterday() };
38867
+ return { status: UNPAID_STATUSES2, dueAtEnd: endOfYesterday() };
38068
38868
  case "Sent" /* Sent */:
38069
- return { status: unpaidStatuses, dueAtStart: startOfToday() };
38869
+ return { status: UNPAID_STATUSES2, dueAtStart: startOfToday() };
38070
38870
  case "Paid" /* Paid */:
38071
38871
  return { status: ["PAID" /* Paid */, "PARTIALLY_WRITTEN_OFF" /* PartiallyWrittenOff */] };
38072
38872
  case "Written Off" /* WrittenOff */:
@@ -38080,9 +38880,9 @@ var getListInvoiceParams = ({ statusFilter }) => {
38080
38880
  });
38081
38881
  }
38082
38882
  };
38083
- var InvoicesTable = () => {
38084
- const [selectedInvoiceStatusOption, setSelectedInvoiceStatusOption] = useState83(ALL_OPTION);
38085
- const listInvoiceParams = useMemo74(
38883
+ var InvoicesTable = ({ onCreateInvoice, onSelectInvoice }) => {
38884
+ const [selectedInvoiceStatusOption, setSelectedInvoiceStatusOption] = useState86(ALL_OPTION);
38885
+ const listInvoiceParams = useMemo76(
38086
38886
  () => getListInvoiceParams({ statusFilter: selectedInvoiceStatusOption == null ? void 0 : selectedInvoiceStatusOption.value }),
38087
38887
  [selectedInvoiceStatusOption == null ? void 0 : selectedInvoiceStatusOption.value]
38088
38888
  );
@@ -38090,25 +38890,25 @@ var InvoicesTable = () => {
38090
38890
  const invoices = data == null ? void 0 : data.flatMap(({ data: data2 }) => data2);
38091
38891
  const paginationMeta = data == null ? void 0 : data[data.length - 1].meta.pagination;
38092
38892
  const hasMore = paginationMeta == null ? void 0 : paginationMeta.hasMore;
38093
- const fetchMore = useCallback50(() => {
38893
+ const fetchMore = useCallback58(() => {
38094
38894
  if (hasMore) {
38095
38895
  void setSize(size + 1);
38096
38896
  }
38097
38897
  }, [hasMore, setSize, size]);
38098
- const paginationProps = useMemo74(() => {
38898
+ const paginationProps = useMemo76(() => {
38099
38899
  return {
38100
38900
  pageSize: 10,
38101
38901
  hasMore,
38102
38902
  fetchMore
38103
38903
  };
38104
38904
  }, [fetchMore, hasMore]);
38105
- const options = useMemo74(() => Object.values(InvoiceStatusOptionConfig), []);
38106
- const SelectedValue = useMemo74(() => {
38905
+ const options = useMemo76(() => Object.values(InvoiceStatusOptionConfig), []);
38906
+ const SelectedValue = useMemo76(() => {
38107
38907
  const label = selectedInvoiceStatusOption == null ? void 0 : selectedInvoiceStatusOption.label;
38108
38908
  return label ? `Status: ${label}` : "Status";
38109
38909
  }, [selectedInvoiceStatusOption == null ? void 0 : selectedInvoiceStatusOption.label]);
38110
- const StatusFilter = useCallback50(
38111
- () => /* @__PURE__ */ jsx331(
38910
+ const StatusFilter = useCallback58(
38911
+ () => /* @__PURE__ */ jsx347(
38112
38912
  ComboBox,
38113
38913
  {
38114
38914
  className: "Layer__InvoicesTable__StatusFilter",
@@ -38124,27 +38924,27 @@ var InvoicesTable = () => {
38124
38924
  ),
38125
38925
  [SelectedValue, options, selectedInvoiceStatusOption]
38126
38926
  );
38127
- const CreateInvoiceButton = useCallback50(
38128
- () => /* @__PURE__ */ jsxs214(Button2, { children: [
38927
+ const CreateInvoiceButton = useCallback58(
38928
+ () => /* @__PURE__ */ jsxs221(Button2, { onPress: onCreateInvoice, children: [
38129
38929
  "Create Invoice",
38130
- /* @__PURE__ */ jsx331(Plus2, { size: 16 })
38930
+ /* @__PURE__ */ jsx347(Plus3, { size: 16 })
38131
38931
  ] }),
38132
- []
38932
+ [onCreateInvoice]
38133
38933
  );
38134
- const InvoicesTableEmptyState = useCallback50(() => {
38934
+ const InvoicesTableEmptyState = useCallback58(() => {
38135
38935
  const isFiltered = selectedInvoiceStatusOption && selectedInvoiceStatusOption !== ALL_OPTION;
38136
- return /* @__PURE__ */ jsx331(
38936
+ return /* @__PURE__ */ jsx347(
38137
38937
  DataState,
38138
38938
  {
38139
38939
  status: "allDone" /* allDone */,
38140
38940
  title: isFiltered ? "No results found" : "No invoices yet",
38141
38941
  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, {}),
38942
+ icon: isFiltered ? /* @__PURE__ */ jsx347(Search2, {}) : /* @__PURE__ */ jsx347(HandCoins, {}),
38143
38943
  spacing: true
38144
38944
  }
38145
38945
  );
38146
38946
  }, [selectedInvoiceStatusOption]);
38147
- const InvoicesTableErrorState = useCallback50(() => /* @__PURE__ */ jsx331(
38947
+ const InvoicesTableErrorState = useCallback58(() => /* @__PURE__ */ jsx347(
38148
38948
  DataState,
38149
38949
  {
38150
38950
  status: "failed" /* failed */,
@@ -38156,8 +38956,9 @@ var InvoicesTable = () => {
38156
38956
  spacing: true
38157
38957
  }
38158
38958
  ), [refetch]);
38159
- return /* @__PURE__ */ jsxs214(Container, { name: "InvoicesTable", children: [
38160
- /* @__PURE__ */ jsx331(
38959
+ const columnConfig = useMemo76(() => getColumnConfig(onSelectInvoice), [onSelectInvoice]);
38960
+ return /* @__PURE__ */ jsxs221(Container, { name: "InvoicesTable", children: [
38961
+ /* @__PURE__ */ jsx347(
38161
38962
  DataTableHeader,
38162
38963
  {
38163
38964
  name: "Invoices",
@@ -38167,14 +38968,14 @@ var InvoicesTable = () => {
38167
38968
  }
38168
38969
  }
38169
38970
  ),
38170
- /* @__PURE__ */ jsx331(
38971
+ /* @__PURE__ */ jsx347(
38171
38972
  PaginatedTable,
38172
38973
  {
38173
38974
  ariaLabel: "Invoices",
38174
38975
  data: invoices,
38175
38976
  isLoading: data === void 0 || isLoading,
38176
38977
  isError,
38177
- columnConfig: columns,
38978
+ columnConfig,
38178
38979
  paginationProps,
38179
38980
  componentName: COMPONENT_NAME10,
38180
38981
  slots: {
@@ -38187,28 +38988,38 @@ var InvoicesTable = () => {
38187
38988
  };
38188
38989
 
38189
38990
  // src/components/Invoices/Invoices.tsx
38190
- import { jsx as jsx332 } from "react/jsx-runtime";
38991
+ import { jsx as jsx348 } from "react/jsx-runtime";
38191
38992
  var unstable_Invoices = ({
38192
38993
  showTitle = true,
38193
38994
  stringOverrides
38194
38995
  }) => {
38195
- return /* @__PURE__ */ jsx332(
38996
+ const [invoiceFormMode, setInvoiceFormMode] = useState87(null);
38997
+ const goBackToInvoicesTable = useCallback59(() => {
38998
+ setInvoiceFormMode(null);
38999
+ }, []);
39000
+ const onCreateInvoice = useCallback59(() => {
39001
+ setInvoiceFormMode({ mode: "Create" /* Create */ });
39002
+ }, []);
39003
+ const onSelectInvoice = useCallback59((invoice) => {
39004
+ setInvoiceFormMode({ mode: "Update" /* Update */, invoice });
39005
+ }, []);
39006
+ return /* @__PURE__ */ jsx348(
38196
39007
  View,
38197
39008
  {
38198
39009
  title: (stringOverrides == null ? void 0 : stringOverrides.title) || "Invoices",
38199
39010
  showHeader: showTitle,
38200
- children: /* @__PURE__ */ jsx332(InvoicesTable, {})
39011
+ children: invoiceFormMode !== null ? /* @__PURE__ */ jsx348(InvoiceDetail, __spreadProps(__spreadValues({}, invoiceFormMode), { onGoBack: goBackToInvoicesTable })) : /* @__PURE__ */ jsx348(InvoicesTable, { onCreateInvoice, onSelectInvoice })
38201
39012
  }
38202
39013
  );
38203
39014
  };
38204
39015
 
38205
39016
  // src/providers/BankTransactionsProvider/BankTransactionsProvider.tsx
38206
- import { jsx as jsx333 } from "react/jsx-runtime";
39017
+ import { jsx as jsx349 } from "react/jsx-runtime";
38207
39018
  var BankTransactionsProvider = ({
38208
39019
  children
38209
39020
  }) => {
38210
39021
  const bankTransactionsContextData = useAugmentedBankTransactions();
38211
- return /* @__PURE__ */ jsx333(BankTransactionsContext.Provider, { value: bankTransactionsContextData, children });
39022
+ return /* @__PURE__ */ jsx349(BankTransactionsContext.Provider, { value: bankTransactionsContextData, children });
38212
39023
  };
38213
39024
  export {
38214
39025
  AccountingOverview,