@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.
- package/dist/cjs/index.cjs +1214 -402
- package/dist/esm/index.mjs +1244 -433
- package/dist/index.css +253 -133
- package/dist/index.d.ts +1563 -187
- package/package.json +1 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -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
|
|
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
|
-
|
|
7165
|
+
displayMode
|
|
7187
7166
|
}) => {
|
|
7188
|
-
switch (
|
|
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:
|
|
7204
|
-
message: "Invalid `
|
|
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
|
|
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
|
-
|
|
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
|
|
12787
|
+
subMonths,
|
|
12822
12788
|
subQuarters,
|
|
12823
|
-
subYears
|
|
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(
|
|
12836
|
-
endDate: endOfMonth3(
|
|
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(
|
|
12856
|
-
endDate: endOfYear2(
|
|
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
|
|
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
|
|
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 :
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 (
|
|
23856
|
+
if (differenceInMonths(startOfMonth10(chartWindow.start), current) < 0 && differenceInMonths(startOfMonth10(chartWindow.end), current) > 1) {
|
|
23867
23857
|
return chartWindow;
|
|
23868
23858
|
}
|
|
23869
|
-
if (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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) =>
|
|
24062
|
+
(x) => differenceInMonths(
|
|
24073
24063
|
startOfMonth10(new Date(x.year, x.month - 1, 1)),
|
|
24074
24064
|
chartWindow.start
|
|
24075
|
-
) >= 0 &&
|
|
24065
|
+
) >= 0 && differenceInMonths(
|
|
24076
24066
|
startOfMonth10(new Date(x.year, x.month - 1, 1)),
|
|
24077
24067
|
chartWindow.start
|
|
24078
|
-
) < 12 &&
|
|
24068
|
+
) < 12 && differenceInMonths(
|
|
24079
24069
|
chartWindow.end,
|
|
24080
24070
|
startOfMonth10(new Date(x.year, x.month - 1, 1))
|
|
24081
|
-
) >= 0 &&
|
|
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
|
|
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), {
|
|
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
|
|
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 =
|
|
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 =
|
|
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("
|
|
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:
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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/
|
|
37296
|
-
import { useCallback as
|
|
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/
|
|
37299
|
-
import
|
|
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/
|
|
37305
|
-
import {
|
|
37306
|
-
|
|
37307
|
-
|
|
37308
|
-
|
|
37309
|
-
|
|
37310
|
-
|
|
37311
|
-
|
|
37312
|
-
|
|
37313
|
-
|
|
37314
|
-
|
|
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
|
|
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 =
|
|
37330
|
-
var TransformedInvoiceStatusSchema =
|
|
37331
|
-
|
|
37332
|
-
|
|
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 =
|
|
37344
|
-
id:
|
|
37345
|
-
externalId:
|
|
37346
|
-
|
|
37347
|
-
|
|
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:
|
|
37350
|
-
|
|
37351
|
-
|
|
37686
|
+
invoiceId: pipe5(
|
|
37687
|
+
Schema9.propertySignature(Schema9.UUID),
|
|
37688
|
+
Schema9.fromKey("invoice_id")
|
|
37352
37689
|
),
|
|
37353
|
-
description:
|
|
37354
|
-
product:
|
|
37355
|
-
unitPrice:
|
|
37356
|
-
|
|
37357
|
-
|
|
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:
|
|
37360
|
-
subtotal:
|
|
37361
|
-
discountAmount:
|
|
37362
|
-
|
|
37363
|
-
|
|
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:
|
|
37366
|
-
|
|
37367
|
-
|
|
37702
|
+
salesTaxTotal: pipe5(
|
|
37703
|
+
Schema9.propertySignature(Schema9.Number),
|
|
37704
|
+
Schema9.fromKey("sales_taxes_total")
|
|
37368
37705
|
),
|
|
37369
|
-
totalAmount:
|
|
37370
|
-
|
|
37371
|
-
|
|
37706
|
+
totalAmount: pipe5(
|
|
37707
|
+
Schema9.propertySignature(Schema9.Number),
|
|
37708
|
+
Schema9.fromKey("total_amount")
|
|
37372
37709
|
),
|
|
37373
|
-
memo:
|
|
37710
|
+
memo: Schema9.NullOr(Schema9.String)
|
|
37374
37711
|
});
|
|
37375
|
-
var InvoiceSchema =
|
|
37376
|
-
id:
|
|
37377
|
-
businessId:
|
|
37378
|
-
|
|
37379
|
-
|
|
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:
|
|
37382
|
-
|
|
37383
|
-
|
|
37718
|
+
externalId: pipe5(
|
|
37719
|
+
Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
|
|
37720
|
+
Schema9.fromKey("external_id")
|
|
37384
37721
|
),
|
|
37385
37722
|
status: TransformedInvoiceStatusSchema,
|
|
37386
|
-
sentAt:
|
|
37387
|
-
|
|
37388
|
-
|
|
37723
|
+
sentAt: pipe5(
|
|
37724
|
+
Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
|
|
37725
|
+
Schema9.fromKey("sent_at")
|
|
37389
37726
|
),
|
|
37390
|
-
dueAt:
|
|
37391
|
-
|
|
37392
|
-
|
|
37727
|
+
dueAt: pipe5(
|
|
37728
|
+
Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
|
|
37729
|
+
Schema9.fromKey("due_at")
|
|
37393
37730
|
),
|
|
37394
|
-
paidAt:
|
|
37395
|
-
|
|
37396
|
-
|
|
37731
|
+
paidAt: pipe5(
|
|
37732
|
+
Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
|
|
37733
|
+
Schema9.fromKey("paid_at")
|
|
37397
37734
|
),
|
|
37398
|
-
voidedAt:
|
|
37399
|
-
|
|
37400
|
-
|
|
37735
|
+
voidedAt: pipe5(
|
|
37736
|
+
Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
|
|
37737
|
+
Schema9.fromKey("voided_at")
|
|
37401
37738
|
),
|
|
37402
|
-
invoiceNumber:
|
|
37403
|
-
|
|
37404
|
-
|
|
37739
|
+
invoiceNumber: pipe5(
|
|
37740
|
+
Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
|
|
37741
|
+
Schema9.fromKey("invoice_number")
|
|
37405
37742
|
),
|
|
37406
|
-
recipientName:
|
|
37407
|
-
|
|
37408
|
-
|
|
37743
|
+
recipientName: pipe5(
|
|
37744
|
+
Schema9.propertySignature(Schema9.NullOr(Schema9.String)),
|
|
37745
|
+
Schema9.fromKey("recipient_name")
|
|
37409
37746
|
),
|
|
37410
|
-
customer:
|
|
37411
|
-
lineItems:
|
|
37412
|
-
|
|
37413
|
-
|
|
37747
|
+
customer: Schema9.NullOr(CustomerSchema),
|
|
37748
|
+
lineItems: pipe5(
|
|
37749
|
+
Schema9.propertySignature(Schema9.Array(InvoiceLineItemSchema)),
|
|
37750
|
+
Schema9.fromKey("line_items")
|
|
37414
37751
|
),
|
|
37415
|
-
subtotal:
|
|
37416
|
-
additionalDiscount:
|
|
37417
|
-
|
|
37418
|
-
|
|
37752
|
+
subtotal: Schema9.Number,
|
|
37753
|
+
additionalDiscount: pipe5(
|
|
37754
|
+
Schema9.propertySignature(Schema9.Number),
|
|
37755
|
+
Schema9.fromKey("additional_discount")
|
|
37419
37756
|
),
|
|
37420
|
-
additionalSalesTaxesTotal:
|
|
37421
|
-
|
|
37422
|
-
|
|
37757
|
+
additionalSalesTaxesTotal: pipe5(
|
|
37758
|
+
Schema9.propertySignature(Schema9.Number),
|
|
37759
|
+
Schema9.fromKey("additional_sales_taxes_total")
|
|
37423
37760
|
),
|
|
37424
|
-
totalAmount:
|
|
37425
|
-
|
|
37426
|
-
|
|
37761
|
+
totalAmount: pipe5(
|
|
37762
|
+
Schema9.propertySignature(Schema9.Number),
|
|
37763
|
+
Schema9.fromKey("total_amount")
|
|
37427
37764
|
),
|
|
37428
|
-
outstandingBalance:
|
|
37429
|
-
|
|
37430
|
-
|
|
37765
|
+
outstandingBalance: pipe5(
|
|
37766
|
+
Schema9.propertySignature(Schema9.Number),
|
|
37767
|
+
Schema9.fromKey("outstanding_balance")
|
|
37431
37768
|
),
|
|
37432
|
-
importedAt:
|
|
37433
|
-
|
|
37434
|
-
|
|
37769
|
+
importedAt: pipe5(
|
|
37770
|
+
Schema9.propertySignature(Schema9.Date),
|
|
37771
|
+
Schema9.fromKey("imported_at")
|
|
37435
37772
|
),
|
|
37436
|
-
updatedAt:
|
|
37437
|
-
|
|
37438
|
-
|
|
37773
|
+
updatedAt: pipe5(
|
|
37774
|
+
Schema9.propertySignature(Schema9.NullOr(Schema9.Date)),
|
|
37775
|
+
Schema9.fromKey("updated_at")
|
|
37439
37776
|
),
|
|
37440
|
-
memo:
|
|
37777
|
+
memo: Schema9.NullOr(Schema9.String)
|
|
37441
37778
|
});
|
|
37442
|
-
var UpsertInvoiceTaxLineItemSchema =
|
|
37443
|
-
amount:
|
|
37779
|
+
var UpsertInvoiceTaxLineItemSchema = Schema9.Struct({
|
|
37780
|
+
amount: Schema9.Number
|
|
37444
37781
|
});
|
|
37445
|
-
var UpsertInvoiceLineItemSchema =
|
|
37446
|
-
description:
|
|
37447
|
-
|
|
37448
|
-
|
|
37449
|
-
|
|
37450
|
-
|
|
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
|
-
|
|
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 =
|
|
37464
|
-
sentAt:
|
|
37465
|
-
|
|
37466
|
-
|
|
37791
|
+
var UpsertInvoiceSchema = Schema9.Struct({
|
|
37792
|
+
sentAt: pipe5(
|
|
37793
|
+
Schema9.propertySignature(Schema9.Date),
|
|
37794
|
+
Schema9.fromKey("sent_at")
|
|
37467
37795
|
),
|
|
37468
|
-
dueAt:
|
|
37469
|
-
|
|
37470
|
-
|
|
37796
|
+
dueAt: pipe5(
|
|
37797
|
+
Schema9.propertySignature(Schema9.Date),
|
|
37798
|
+
Schema9.fromKey("due_at")
|
|
37471
37799
|
),
|
|
37472
|
-
invoiceNumber:
|
|
37473
|
-
|
|
37474
|
-
|
|
37800
|
+
invoiceNumber: pipe5(
|
|
37801
|
+
Schema9.propertySignature(Schema9.UndefinedOr(Schema9.String)),
|
|
37802
|
+
Schema9.fromKey("invoice_number")
|
|
37475
37803
|
),
|
|
37476
|
-
customerId:
|
|
37477
|
-
|
|
37478
|
-
|
|
37804
|
+
customerId: pipe5(
|
|
37805
|
+
Schema9.propertySignature(Schema9.UUID),
|
|
37806
|
+
Schema9.fromKey("customer_id")
|
|
37479
37807
|
),
|
|
37480
|
-
memo:
|
|
37481
|
-
lineItems:
|
|
37482
|
-
|
|
37483
|
-
|
|
37808
|
+
memo: Schema9.NullOr(Schema9.String),
|
|
37809
|
+
lineItems: pipe5(
|
|
37810
|
+
Schema9.propertySignature(Schema9.Array(UpsertInvoiceLineItemSchema)),
|
|
37811
|
+
Schema9.fromKey("line_items")
|
|
37484
37812
|
),
|
|
37485
|
-
additionalDiscount:
|
|
37486
|
-
|
|
37487
|
-
|
|
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
|
-
|
|
37490
|
-
|
|
37491
|
-
|
|
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 =
|
|
37498
|
-
data:
|
|
37499
|
-
meta:
|
|
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(
|
|
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
|
|
38508
|
+
import { useMemo as useMemo74 } from "react";
|
|
37647
38509
|
|
|
37648
38510
|
// src/components/ui/Table/Table.tsx
|
|
37649
|
-
import { forwardRef as
|
|
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
|
|
37659
|
-
import { jsx as
|
|
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) =>
|
|
37662
|
-
var Table2 =
|
|
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__ */
|
|
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__ */
|
|
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 =
|
|
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__ */
|
|
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 =
|
|
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__ */
|
|
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 =
|
|
38579
|
+
var Row2 = forwardRef24(RowInner);
|
|
37718
38580
|
Row2.displayName = "Row" /* Row */;
|
|
37719
|
-
var Column =
|
|
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__ */
|
|
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 =
|
|
38597
|
+
var Cell5 = forwardRef24(
|
|
37736
38598
|
(_a, ref) => {
|
|
37737
38599
|
var _b = _a, { children, className } = _b, restProps = __objRest(_b, ["children", "className"]);
|
|
37738
|
-
return /* @__PURE__ */
|
|
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
|
|
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
|
|
38624
|
+
const columns = Object.values(columnConfig);
|
|
37763
38625
|
const { EmptyState, ErrorState } = slots;
|
|
37764
|
-
const
|
|
38626
|
+
const isEmptyTable = (data == null ? void 0 : data.length) === 0;
|
|
38627
|
+
const renderTableBody = useMemo74(() => {
|
|
37765
38628
|
if (isError) {
|
|
37766
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
38632
|
+
return /* @__PURE__ */ jsx343(Row2, { children: /* @__PURE__ */ jsx343(Cell5, { colSpan: columns.length, children: /* @__PURE__ */ jsx343(Loader2, {}) }) });
|
|
37770
38633
|
}
|
|
37771
|
-
if (
|
|
37772
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
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,
|
|
37785
|
-
return /* @__PURE__ */
|
|
37786
|
-
/* @__PURE__ */
|
|
37787
|
-
/* @__PURE__ */
|
|
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
|
|
37793
|
-
import { jsx as
|
|
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] =
|
|
38669
|
+
const [pagination, setPagination] = useState85({ pageIndex: 0, pageSize });
|
|
37807
38670
|
const columnHelper = createColumnHelper();
|
|
37808
|
-
const
|
|
37809
|
-
const columnDefs =
|
|
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 =
|
|
37827
|
-
const onPageChange =
|
|
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__ */
|
|
37831
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
37875
|
-
/* @__PURE__ */
|
|
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
|
|
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
|
|
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__ */
|
|
37899
|
-
/* @__PURE__ */
|
|
37900
|
-
/* @__PURE__ */
|
|
37901
|
-
/* @__PURE__ */
|
|
37902
|
-
/* @__PURE__ */
|
|
37903
|
-
showCount && (totalCount ? /* @__PURE__ */
|
|
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__ */
|
|
38765
|
+
HeaderFilters && /* @__PURE__ */ jsx346(HeaderFilters, {})
|
|
37906
38766
|
] }),
|
|
37907
|
-
/* @__PURE__ */
|
|
37908
|
-
slotProps.SearchField && /* @__PURE__ */
|
|
37909
|
-
HeaderActions && /* @__PURE__ */
|
|
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__ */
|
|
37913
|
-
/* @__PURE__ */
|
|
37914
|
-
slotProps.ClearFiltersButton && /* @__PURE__ */
|
|
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
|
|
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__ */
|
|
38802
|
+
return /* @__PURE__ */ jsx347(VStack, { children: /* @__PURE__ */ jsx347(Span, { align: "right", children: totalAmount }) });
|
|
37943
38803
|
}
|
|
37944
38804
|
case "PARTIALLY_PAID" /* PartiallyPaid */: {
|
|
37945
|
-
return /* @__PURE__ */
|
|
37946
|
-
/* @__PURE__ */
|
|
37947
|
-
/* @__PURE__ */
|
|
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
|
|
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
|
|
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) =>
|
|
38841
|
+
cell: (row) => getCustomerName2(row)
|
|
38042
38842
|
},
|
|
38043
38843
|
["Total" /* Total */]: {
|
|
38044
38844
|
id: "Total" /* Total */,
|
|
38045
38845
|
header: "Amount",
|
|
38046
|
-
cell: (row) => /* @__PURE__ */
|
|
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__ */
|
|
38851
|
+
cell: (row) => /* @__PURE__ */ jsx347(InvoiceStatusCell, { invoice: row })
|
|
38052
38852
|
},
|
|
38053
38853
|
["Expand" /* Expand */]: {
|
|
38054
38854
|
id: "Expand" /* Expand */,
|
|
38055
|
-
cell: (
|
|
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
|
|
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:
|
|
38865
|
+
return { status: UNPAID_STATUSES2 };
|
|
38066
38866
|
case "Overdue" /* Overdue */:
|
|
38067
|
-
return { status:
|
|
38867
|
+
return { status: UNPAID_STATUSES2, dueAtEnd: endOfYesterday() };
|
|
38068
38868
|
case "Sent" /* Sent */:
|
|
38069
|
-
return { status:
|
|
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] =
|
|
38085
|
-
const listInvoiceParams =
|
|
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 =
|
|
38893
|
+
const fetchMore = useCallback58(() => {
|
|
38094
38894
|
if (hasMore) {
|
|
38095
38895
|
void setSize(size + 1);
|
|
38096
38896
|
}
|
|
38097
38897
|
}, [hasMore, setSize, size]);
|
|
38098
|
-
const paginationProps =
|
|
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 =
|
|
38106
|
-
const SelectedValue =
|
|
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 =
|
|
38111
|
-
() => /* @__PURE__ */
|
|
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 =
|
|
38128
|
-
() => /* @__PURE__ */
|
|
38927
|
+
const CreateInvoiceButton = useCallback58(
|
|
38928
|
+
() => /* @__PURE__ */ jsxs221(Button2, { onPress: onCreateInvoice, children: [
|
|
38129
38929
|
"Create Invoice",
|
|
38130
|
-
/* @__PURE__ */
|
|
38930
|
+
/* @__PURE__ */ jsx347(Plus3, { size: 16 })
|
|
38131
38931
|
] }),
|
|
38132
|
-
[]
|
|
38932
|
+
[onCreateInvoice]
|
|
38133
38933
|
);
|
|
38134
|
-
const InvoicesTableEmptyState =
|
|
38934
|
+
const InvoicesTableEmptyState = useCallback58(() => {
|
|
38135
38935
|
const isFiltered = selectedInvoiceStatusOption && selectedInvoiceStatusOption !== ALL_OPTION;
|
|
38136
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
38942
|
+
icon: isFiltered ? /* @__PURE__ */ jsx347(Search2, {}) : /* @__PURE__ */ jsx347(HandCoins, {}),
|
|
38143
38943
|
spacing: true
|
|
38144
38944
|
}
|
|
38145
38945
|
);
|
|
38146
38946
|
}, [selectedInvoiceStatusOption]);
|
|
38147
|
-
const InvoicesTableErrorState =
|
|
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
|
-
|
|
38160
|
-
|
|
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__ */
|
|
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
|
|
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
|
|
38991
|
+
import { jsx as jsx348 } from "react/jsx-runtime";
|
|
38191
38992
|
var unstable_Invoices = ({
|
|
38192
38993
|
showTitle = true,
|
|
38193
38994
|
stringOverrides
|
|
38194
38995
|
}) => {
|
|
38195
|
-
|
|
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__ */
|
|
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
|
|
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__ */
|
|
39022
|
+
return /* @__PURE__ */ jsx349(BankTransactionsContext.Provider, { value: bankTransactionsContextData, children });
|
|
38212
39023
|
};
|
|
38213
39024
|
export {
|
|
38214
39025
|
AccountingOverview,
|