@layerfi/components 0.1.0 → 0.1.2
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/.eslintrc.js +40 -0
- package/.prettierrc.json +21 -0
- package/README.md +114 -10
- package/dist/esm/index.js +2094 -526
- package/dist/esm/index.js.map +4 -4
- package/dist/index.d.ts +902 -188
- package/dist/index.js +2153 -605
- package/dist/index.js.map +4 -4
- package/dist/styles/index.css +1317 -317
- package/dist/styles/index.css.map +3 -3
- package/index.d.ts +1309 -0
- package/package.json +13 -18
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var src_exports = {};
|
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
BalanceSheet: () => BalanceSheet,
|
|
34
34
|
BankTransactions: () => BankTransactions,
|
|
35
|
+
ChartOfAccounts: () => ChartOfAccounts,
|
|
35
36
|
Hello: () => Hello,
|
|
36
37
|
LayerProvider: () => LayerProvider,
|
|
37
38
|
ProfitAndLoss: () => ProfitAndLoss
|
|
@@ -39,7 +40,7 @@ __export(src_exports, {
|
|
|
39
40
|
module.exports = __toCommonJS(src_exports);
|
|
40
41
|
|
|
41
42
|
// src/components/BalanceSheet/BalanceSheet.tsx
|
|
42
|
-
var
|
|
43
|
+
var import_react6 = __toESM(require("react"));
|
|
43
44
|
|
|
44
45
|
// src/api/util.ts
|
|
45
46
|
var formStringFromObject = (object) => Object.entries(object).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&");
|
|
@@ -49,7 +50,6 @@ var authenticate = ({
|
|
|
49
50
|
appId,
|
|
50
51
|
appSecret,
|
|
51
52
|
authenticationUrl = "https://auth.layerfi.com/oauth2/token",
|
|
52
|
-
clientId,
|
|
53
53
|
scope
|
|
54
54
|
}) => () => fetch(authenticationUrl, {
|
|
55
55
|
method: "POST",
|
|
@@ -60,7 +60,7 @@ var authenticate = ({
|
|
|
60
60
|
body: formStringFromObject({
|
|
61
61
|
grant_type: "client_credentials",
|
|
62
62
|
scope,
|
|
63
|
-
client_id:
|
|
63
|
+
client_id: appId
|
|
64
64
|
})
|
|
65
65
|
}).then((res) => res.json());
|
|
66
66
|
|
|
@@ -207,23 +207,82 @@ var balance_sheet_default = {
|
|
|
207
207
|
// src/api/layer/balance_sheet.ts
|
|
208
208
|
var getBalanceSheet = (_token, _params) => () => balance_sheet_default;
|
|
209
209
|
|
|
210
|
+
// src/models/APIError.ts
|
|
211
|
+
var APIError = class _APIError extends Error {
|
|
212
|
+
constructor(message, code, messages) {
|
|
213
|
+
super(message);
|
|
214
|
+
this.name = "APIError";
|
|
215
|
+
this.code = code;
|
|
216
|
+
this.messages = messages;
|
|
217
|
+
Object.setPrototypeOf(this, _APIError.prototype);
|
|
218
|
+
}
|
|
219
|
+
getMessage() {
|
|
220
|
+
return this.message;
|
|
221
|
+
}
|
|
222
|
+
getAllMessages() {
|
|
223
|
+
return this.messages?.map((x) => x.description);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
210
227
|
// src/api/layer/authenticated_http.ts
|
|
211
|
-
var get = (url) => (accessToken, options) => () => fetch(url(options?.params || {})
|
|
228
|
+
var get = (url) => (baseUrl, accessToken, options) => () => fetch(`${baseUrl}${url(options?.params || {})}`, {
|
|
212
229
|
headers: {
|
|
213
230
|
Authorization: "Bearer " + (accessToken || ""),
|
|
214
231
|
"Content-Type": "application/json"
|
|
215
232
|
},
|
|
216
233
|
method: "GET"
|
|
217
|
-
}).then((res) => res.
|
|
218
|
-
var
|
|
234
|
+
}).then((res) => handleResponse(res)).catch((error) => handleException(error));
|
|
235
|
+
var request = (verb) => (url) => (baseUrl, accessToken, options) => fetch(`${baseUrl}${url(options?.params || {})}`, {
|
|
219
236
|
headers: {
|
|
220
237
|
Authorization: "Bearer " + (accessToken || ""),
|
|
221
238
|
"Content-Type": "application/json",
|
|
222
239
|
"Cache-Control": "no-cache"
|
|
223
240
|
},
|
|
224
|
-
method:
|
|
241
|
+
method: verb.toUpperCase(),
|
|
225
242
|
body: JSON.stringify(options?.body)
|
|
226
|
-
}).then((res) => res.
|
|
243
|
+
}).then((res) => handleResponse(res)).catch((error) => handleException(error));
|
|
244
|
+
var post = request("post");
|
|
245
|
+
var put = request("put");
|
|
246
|
+
var handleResponse = async (res) => {
|
|
247
|
+
if (!res.ok) {
|
|
248
|
+
const errors = await tryToReadErrorsFromResponse(res);
|
|
249
|
+
const apiError = new APIError(
|
|
250
|
+
"An error occurred while fetching the data from API.",
|
|
251
|
+
res.status,
|
|
252
|
+
errors
|
|
253
|
+
);
|
|
254
|
+
throw apiError;
|
|
255
|
+
}
|
|
256
|
+
const parsedResponse = await res.json();
|
|
257
|
+
if (parsedResponse && "errors" in parsedResponse) {
|
|
258
|
+
const apiError = new APIError(
|
|
259
|
+
"Errors in the API response.",
|
|
260
|
+
res.status,
|
|
261
|
+
parsedResponse.errors ?? []
|
|
262
|
+
);
|
|
263
|
+
throw apiError;
|
|
264
|
+
}
|
|
265
|
+
return parsedResponse;
|
|
266
|
+
};
|
|
267
|
+
var handleException = async (error) => {
|
|
268
|
+
if (error.name === "APIError") {
|
|
269
|
+
throw error;
|
|
270
|
+
}
|
|
271
|
+
const apiError = new APIError(
|
|
272
|
+
"An error occurred while parsing the data from API.",
|
|
273
|
+
void 0,
|
|
274
|
+
[]
|
|
275
|
+
);
|
|
276
|
+
throw apiError;
|
|
277
|
+
};
|
|
278
|
+
var tryToReadErrorsFromResponse = async (res) => {
|
|
279
|
+
try {
|
|
280
|
+
const data = await res?.json();
|
|
281
|
+
return data?.errors ?? [];
|
|
282
|
+
} catch (_err) {
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
};
|
|
227
286
|
|
|
228
287
|
// src/api/layer/bankTransactions.ts
|
|
229
288
|
var getBankTransactions = get(
|
|
@@ -231,29 +290,37 @@ var getBankTransactions = get(
|
|
|
231
290
|
businessId,
|
|
232
291
|
sortBy = "date",
|
|
233
292
|
sortOrder = "DESC"
|
|
234
|
-
}) =>
|
|
293
|
+
}) => `/v1/businesses/${businessId}/bank-transactions?sort_by=${sortBy}&sort_order=${sortOrder}`
|
|
235
294
|
);
|
|
236
295
|
var categorizeBankTransaction = put(
|
|
237
|
-
({ businessId, bankTransactionId }) =>
|
|
296
|
+
({ businessId, bankTransactionId }) => `/v1/businesses/${businessId}/bank-transactions/${bankTransactionId}/categorize`
|
|
238
297
|
);
|
|
239
298
|
|
|
240
299
|
// src/api/layer/categories.ts
|
|
241
|
-
var getCategories = get(
|
|
242
|
-
|
|
300
|
+
var getCategories = get(({ businessId }) => `/v1/businesses/${businessId}/categories`);
|
|
301
|
+
|
|
302
|
+
// src/api/layer/chart_of_accounts.ts
|
|
303
|
+
var getChartOfAccounts = get(
|
|
304
|
+
({ businessId }) => `/v1/businesses/${businessId}/ledger/accounts`
|
|
305
|
+
);
|
|
306
|
+
var createAccount = post(
|
|
307
|
+
({ businessId }) => `/v1/businesses/${businessId}/ledger/accounts`
|
|
243
308
|
);
|
|
244
309
|
|
|
245
310
|
// src/api/layer/profit_and_loss.ts
|
|
246
311
|
var getProfitAndLoss = get(
|
|
247
|
-
({ businessId, startDate, endDate }) =>
|
|
312
|
+
({ businessId, startDate, endDate }) => `/v1/businesses/${businessId}/reports/profit-and-loss?start_date=${startDate ? encodeURIComponent(startDate) : ""}&end_date=${endDate ? encodeURIComponent(endDate) : ""}`
|
|
248
313
|
);
|
|
249
314
|
|
|
250
315
|
// src/api/layer.ts
|
|
251
316
|
var Layer = {
|
|
252
317
|
authenticate,
|
|
253
318
|
categorizeBankTransaction,
|
|
319
|
+
createAccount,
|
|
254
320
|
getBalanceSheet,
|
|
255
321
|
getBankTransactions,
|
|
256
322
|
getCategories,
|
|
323
|
+
getChartOfAccounts,
|
|
257
324
|
getProfitAndLoss
|
|
258
325
|
};
|
|
259
326
|
|
|
@@ -263,9 +330,17 @@ var import_react2 = require("react");
|
|
|
263
330
|
// src/contexts/LayerContext/LayerContext.tsx
|
|
264
331
|
var import_react = require("react");
|
|
265
332
|
var LayerContext = (0, import_react.createContext)({
|
|
266
|
-
auth: {
|
|
333
|
+
auth: {
|
|
334
|
+
access_token: "",
|
|
335
|
+
expires_at: new Date(2e3, 1, 1),
|
|
336
|
+
expires_in: -1,
|
|
337
|
+
token_type: ""
|
|
338
|
+
},
|
|
267
339
|
businessId: "",
|
|
268
|
-
categories: []
|
|
340
|
+
categories: [],
|
|
341
|
+
apiUrl: "",
|
|
342
|
+
theme: void 0,
|
|
343
|
+
setTheme: () => void 0
|
|
269
344
|
});
|
|
270
345
|
|
|
271
346
|
// src/hooks/useLayerContext/useLayerContext.tsx
|
|
@@ -274,7 +349,7 @@ var useLayerContext = () => (0, import_react2.useContext)(LayerContext);
|
|
|
274
349
|
// src/hooks/useBalanceSheet/useBalanceSheet.tsx
|
|
275
350
|
var import_date_fns = require("date-fns");
|
|
276
351
|
var import_swr = __toESM(require("swr"));
|
|
277
|
-
var useBalanceSheet = (date) => {
|
|
352
|
+
var useBalanceSheet = (date = /* @__PURE__ */ new Date()) => {
|
|
278
353
|
const { auth, businessId } = useLayerContext();
|
|
279
354
|
const dateString = (0, import_date_fns.format)((0, import_date_fns.startOfDay)(date), "yyyy-mm-dd");
|
|
280
355
|
const { data, isLoading, error } = (0, import_swr.default)(
|
|
@@ -358,67 +433,44 @@ var import_react4 = __toESM(require("react"));
|
|
|
358
433
|
|
|
359
434
|
// src/icons/ChevronDown.tsx
|
|
360
435
|
var React4 = __toESM(require("react"));
|
|
361
|
-
var ChevronDown = ({ size =
|
|
436
|
+
var ChevronDown = ({ size = 18, ...props }) => /* @__PURE__ */ React4.createElement(
|
|
362
437
|
"svg",
|
|
363
438
|
{
|
|
439
|
+
viewBox: "0 0 18 18",
|
|
440
|
+
fill: "none",
|
|
364
441
|
xmlns: "http://www.w3.org/2000/svg",
|
|
442
|
+
...props,
|
|
365
443
|
width: size,
|
|
366
|
-
height: size
|
|
367
|
-
fill: "none",
|
|
368
|
-
viewBox: "0 0 24 24",
|
|
369
|
-
...props
|
|
444
|
+
height: size
|
|
370
445
|
},
|
|
371
446
|
/* @__PURE__ */ React4.createElement(
|
|
372
447
|
"path",
|
|
373
448
|
{
|
|
449
|
+
d: "M4.5 6.75L9 11.25L13.5 6.75",
|
|
450
|
+
stroke: "currentColor",
|
|
374
451
|
strokeLinecap: "round",
|
|
375
|
-
strokeLinejoin: "round"
|
|
376
|
-
strokeWidth: 2,
|
|
377
|
-
d: "m6 9 6 6 6-6"
|
|
452
|
+
strokeLinejoin: "round"
|
|
378
453
|
}
|
|
379
454
|
)
|
|
380
455
|
);
|
|
381
456
|
var ChevronDown_default = ChevronDown;
|
|
382
457
|
|
|
383
|
-
// src/icons/ChevronRight.tsx
|
|
384
|
-
var React5 = __toESM(require("react"));
|
|
385
|
-
var ChavronRight = ({ strokeColor, size, ...props }) => /* @__PURE__ */ React5.createElement(
|
|
386
|
-
"svg",
|
|
387
|
-
{
|
|
388
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
389
|
-
width: size || 24,
|
|
390
|
-
height: size || 24,
|
|
391
|
-
fill: "none",
|
|
392
|
-
viewBox: "0 0 24 24",
|
|
393
|
-
...props
|
|
394
|
-
},
|
|
395
|
-
/* @__PURE__ */ React5.createElement(
|
|
396
|
-
"path",
|
|
397
|
-
{
|
|
398
|
-
stroke: strokeColor ?? "#000",
|
|
399
|
-
strokeLinecap: "round",
|
|
400
|
-
strokeLinejoin: "round",
|
|
401
|
-
strokeWidth: 2,
|
|
402
|
-
d: "m9 18 6-6-6-6"
|
|
403
|
-
}
|
|
404
|
-
)
|
|
405
|
-
);
|
|
406
|
-
var ChevronRight_default = ChavronRight;
|
|
407
|
-
|
|
408
458
|
// src/models/Money.ts
|
|
409
459
|
var formatter = new Intl.NumberFormat("en-US", {
|
|
410
460
|
minimumIntegerDigits: 1,
|
|
411
461
|
minimumFractionDigits: 2,
|
|
412
462
|
maximumFractionDigits: 2
|
|
413
463
|
});
|
|
414
|
-
var centsToDollars = (cents) => formatter.format(cents / 100);
|
|
415
|
-
var dollarsToCents = (dollars) => Math.round(parseFloat(dollars) * 100);
|
|
464
|
+
var centsToDollars = (cents = NaN) => isNaN(cents) ? "-.--" : formatter.format(cents / 100);
|
|
465
|
+
var dollarsToCents = (dollars = "") => Math.round(parseFloat(dollars) * 100);
|
|
416
466
|
|
|
417
467
|
// src/components/BalanceSheetRow/BalanceSheetRow.tsx
|
|
418
468
|
var BalanceSheetRow = ({
|
|
419
469
|
lineItem,
|
|
420
470
|
depth = 0,
|
|
421
|
-
maxDepth = 2
|
|
471
|
+
maxDepth = 2,
|
|
472
|
+
variant,
|
|
473
|
+
summarize = true
|
|
422
474
|
}) => {
|
|
423
475
|
if (!lineItem) {
|
|
424
476
|
return null;
|
|
@@ -441,9 +493,11 @@ var BalanceSheetRow = ({
|
|
|
441
493
|
);
|
|
442
494
|
labelClasses.push(`Layer__balance-sheet-row__label--depth-${depth}`);
|
|
443
495
|
valueClasses.push(`Layer__balance-sheet-row__value--depth-${depth}`);
|
|
496
|
+
variant && labelClasses.push(`Layer__balance-sheet-row__label--variant-${variant}`);
|
|
497
|
+
variant && valueClasses.push(`Layer__balance-sheet-row__value--variant-${variant}`);
|
|
444
498
|
const toggleExpanded = () => setExpanded(!expanded);
|
|
445
499
|
const canGoDeeper = depth < maxDepth;
|
|
446
|
-
const hasChildren = line_items?.length > 0;
|
|
500
|
+
const hasChildren = (line_items?.length ?? 0) > 0;
|
|
447
501
|
const displayChildren = hasChildren && canGoDeeper;
|
|
448
502
|
labelClasses.push(
|
|
449
503
|
`Layer__balance-sheet-row__label--display-children-${displayChildren}`
|
|
@@ -451,21 +505,68 @@ var BalanceSheetRow = ({
|
|
|
451
505
|
valueClasses.push(
|
|
452
506
|
`Layer__balance-sheet-row__value--display-children-${displayChildren}`
|
|
453
507
|
);
|
|
454
|
-
|
|
455
|
-
|
|
508
|
+
displayChildren && expanded && labelClasses.push("Layer__balance-sheet-row__label--expanded");
|
|
509
|
+
displayChildren && expanded && valueClasses.push("Layer__balance-sheet-row__value--expanded");
|
|
510
|
+
return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("div", { className: labelClasses.join(" "), onClick: toggleExpanded }, /* @__PURE__ */ import_react4.default.createElement(ChevronDown_default, { size: 16 }), display_name), /* @__PURE__ */ import_react4.default.createElement("div", { className: valueClasses.join(" ") }, !!value && amountString), canGoDeeper && hasChildren && /* @__PURE__ */ import_react4.default.createElement(
|
|
511
|
+
"div",
|
|
456
512
|
{
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
513
|
+
className: `Layer__balance-sheet-row__children ${expanded && "Layer__balance-sheet-row__children--expanded"}`
|
|
514
|
+
},
|
|
515
|
+
/* @__PURE__ */ import_react4.default.createElement("div", { className: "Layer__balance-sheet-row__children--content" }, (line_items || []).map((line_item, idx) => /* @__PURE__ */ import_react4.default.createElement(
|
|
516
|
+
BalanceSheetRow,
|
|
517
|
+
{
|
|
518
|
+
key: `${line_item.display_name}_${idx}`,
|
|
519
|
+
lineItem: line_item,
|
|
520
|
+
depth: depth + 1,
|
|
521
|
+
maxDepth
|
|
522
|
+
}
|
|
523
|
+
)), summarize && /* @__PURE__ */ import_react4.default.createElement(
|
|
524
|
+
BalanceSheetRow,
|
|
525
|
+
{
|
|
526
|
+
key: display_name,
|
|
527
|
+
lineItem: { value, display_name: `Total of ${display_name}` },
|
|
528
|
+
variant: "summation",
|
|
529
|
+
depth: depth + 1,
|
|
530
|
+
maxDepth
|
|
531
|
+
}
|
|
532
|
+
))
|
|
533
|
+
));
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
// src/components/SkeletonBalanceSheetRow/SkeletonBalanceSheetRow.tsx
|
|
537
|
+
var import_react5 = __toESM(require("react"));
|
|
538
|
+
var SkeletonBalanceSheetRow = ({ children }) => {
|
|
539
|
+
const labelClasses = [
|
|
540
|
+
"Layer__balance-sheet-row",
|
|
541
|
+
"Layer__balance-sheet-row__label",
|
|
542
|
+
"Layer__balance-sheet-row__label--skeleton"
|
|
543
|
+
];
|
|
544
|
+
const valueClasses = [
|
|
545
|
+
"Layer__balance-sheet-row",
|
|
546
|
+
"Layer__balance-sheet-row__value",
|
|
547
|
+
"Layer__balance-sheet-row__value--skeleton"
|
|
548
|
+
];
|
|
549
|
+
return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("div", { className: labelClasses.join(" ") }, children && /* @__PURE__ */ import_react5.default.createElement(ChevronDown_default, { size: 16 }), /* @__PURE__ */ import_react5.default.createElement(
|
|
550
|
+
"div",
|
|
551
|
+
{
|
|
552
|
+
style: { width: "20rem" },
|
|
553
|
+
className: "Layer__balance-sheet-row__skeleton-text"
|
|
554
|
+
},
|
|
555
|
+
" "
|
|
556
|
+
)), /* @__PURE__ */ import_react5.default.createElement("div", { className: valueClasses.join(" ") }, /* @__PURE__ */ import_react5.default.createElement(
|
|
557
|
+
"div",
|
|
558
|
+
{
|
|
559
|
+
style: { width: "4rem" },
|
|
560
|
+
className: "Layer__balance-sheet-row__skeleton-text"
|
|
561
|
+
},
|
|
562
|
+
" "
|
|
563
|
+
)), children && /* @__PURE__ */ import_react5.default.createElement("div", { className: "Layer__balance-sheet-row__children Layer__balance-sheet-row__children--expanded Layer__balance-sheet-row__children--skeleton" }, children));
|
|
463
564
|
};
|
|
464
565
|
|
|
465
566
|
// src/components/BalanceSheet/BalanceSheet.tsx
|
|
466
567
|
var import_date_fns3 = require("date-fns");
|
|
467
568
|
var BalanceSheet = () => {
|
|
468
|
-
const [effectiveDate, setEffectiveDate] = (0,
|
|
569
|
+
const [effectiveDate, setEffectiveDate] = (0, import_react6.useState)(/* @__PURE__ */ new Date());
|
|
469
570
|
const { data, isLoading } = useBalanceSheet(effectiveDate);
|
|
470
571
|
const assets = {
|
|
471
572
|
name: "Assets",
|
|
@@ -480,22 +581,29 @@ var BalanceSheet = () => {
|
|
|
480
581
|
value: void 0
|
|
481
582
|
};
|
|
482
583
|
const dateString = (0, import_date_fns3.format)(effectiveDate, "LLLL d, yyyy");
|
|
483
|
-
return /* @__PURE__ */
|
|
584
|
+
return /* @__PURE__ */ import_react6.default.createElement("div", { className: "Layer__component Layer__balance-sheet" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "Layer__balance-sheet__header" }, /* @__PURE__ */ import_react6.default.createElement("h2", { className: "Layer__balance-sheet__title" }, "Balance Sheet", /* @__PURE__ */ import_react6.default.createElement("span", { className: "Layer__balance-sheet__date" }, dateString)), /* @__PURE__ */ import_react6.default.createElement(
|
|
484
585
|
BalanceSheetDatePicker,
|
|
485
586
|
{
|
|
486
587
|
value: effectiveDate,
|
|
487
588
|
onChange: (event) => setEffectiveDate((0, import_date_fns3.parseISO)(event.target.value))
|
|
488
589
|
}
|
|
489
|
-
), /* @__PURE__ */
|
|
590
|
+
), /* @__PURE__ */ import_react6.default.createElement("button", { className: "Layer__balance-sheet__download-button" }, /* @__PURE__ */ import_react6.default.createElement(DownloadCloud_default, null), "Download")), !data || isLoading ? /* @__PURE__ */ import_react6.default.createElement("div", { className: "Layer__balance-sheet__table" }, /* @__PURE__ */ import_react6.default.createElement(SkeletonBalanceSheetRow, null, /* @__PURE__ */ import_react6.default.createElement(SkeletonBalanceSheetRow, null), /* @__PURE__ */ import_react6.default.createElement(SkeletonBalanceSheetRow, null, /* @__PURE__ */ import_react6.default.createElement(SkeletonBalanceSheetRow, null), /* @__PURE__ */ import_react6.default.createElement(SkeletonBalanceSheetRow, null))), /* @__PURE__ */ import_react6.default.createElement(SkeletonBalanceSheetRow, null, /* @__PURE__ */ import_react6.default.createElement(SkeletonBalanceSheetRow, null))) : /* @__PURE__ */ import_react6.default.createElement("div", { className: "Layer__balance-sheet__table" }, /* @__PURE__ */ import_react6.default.createElement(
|
|
591
|
+
BalanceSheetRow,
|
|
592
|
+
{
|
|
593
|
+
key: assets.name,
|
|
594
|
+
lineItem: assets,
|
|
595
|
+
summarize: false
|
|
596
|
+
}
|
|
597
|
+
), /* @__PURE__ */ import_react6.default.createElement(BalanceSheetRow, { key: lne.name, lineItem: lne, summarize: false })));
|
|
490
598
|
};
|
|
491
599
|
|
|
492
600
|
// src/components/BankTransactions/BankTransactions.tsx
|
|
493
|
-
var
|
|
601
|
+
var import_react29 = __toESM(require("react"));
|
|
494
602
|
|
|
495
603
|
// src/hooks/useBankTransactions/useBankTransactions.tsx
|
|
496
604
|
var import_swr2 = __toESM(require("swr"));
|
|
497
605
|
var useBankTransactions = () => {
|
|
498
|
-
const { auth, businessId } = useLayerContext();
|
|
606
|
+
const { auth, businessId, apiUrl } = useLayerContext();
|
|
499
607
|
const {
|
|
500
608
|
data: responseData,
|
|
501
609
|
isLoading,
|
|
@@ -503,437 +611,1333 @@ var useBankTransactions = () => {
|
|
|
503
611
|
mutate
|
|
504
612
|
} = (0, import_swr2.default)(
|
|
505
613
|
businessId && auth?.access_token && `bank-transactions-${businessId}`,
|
|
506
|
-
Layer.getBankTransactions(auth?.access_token, {
|
|
614
|
+
Layer.getBankTransactions(apiUrl, auth?.access_token, {
|
|
615
|
+
params: { businessId }
|
|
616
|
+
})
|
|
507
617
|
);
|
|
508
618
|
const {
|
|
509
619
|
data = [],
|
|
510
620
|
meta: metadata = {},
|
|
511
621
|
error = void 0
|
|
512
622
|
} = responseData || {};
|
|
513
|
-
const categorize = (id, newCategory) =>
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
if (transaction) {
|
|
518
|
-
mutate();
|
|
623
|
+
const categorize = (id, newCategory) => {
|
|
624
|
+
const foundBT = data.find((x) => x.business_id === businessId && x.id === id);
|
|
625
|
+
if (foundBT) {
|
|
626
|
+
updateOneLocal({ ...foundBT, processing: true, error: void 0 });
|
|
519
627
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
628
|
+
return Layer.categorizeBankTransaction(apiUrl, auth.access_token, {
|
|
629
|
+
params: { businessId, bankTransactionId: id },
|
|
630
|
+
body: newCategory
|
|
631
|
+
}).then(({ data: newBT, errors }) => {
|
|
632
|
+
if (newBT) {
|
|
633
|
+
newBT.recently_categorized = true;
|
|
634
|
+
updateOneLocal(newBT);
|
|
635
|
+
}
|
|
636
|
+
if (errors) {
|
|
637
|
+
console.error(errors);
|
|
638
|
+
throw errors;
|
|
639
|
+
}
|
|
640
|
+
}).catch((err) => {
|
|
641
|
+
const newBT = data.find(
|
|
642
|
+
(x) => x.business_id === businessId && x.id === id
|
|
643
|
+
);
|
|
644
|
+
if (newBT) {
|
|
645
|
+
updateOneLocal({
|
|
646
|
+
...newBT,
|
|
647
|
+
error: err.message,
|
|
648
|
+
processing: false
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
};
|
|
653
|
+
const updateOneLocal = (newBankTransaction) => {
|
|
654
|
+
const updatedData = data.map(
|
|
655
|
+
(bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
|
|
656
|
+
);
|
|
657
|
+
mutate({ data: updatedData }, { revalidate: false });
|
|
658
|
+
};
|
|
659
|
+
return {
|
|
660
|
+
data,
|
|
661
|
+
metadata,
|
|
662
|
+
isLoading,
|
|
663
|
+
error: responseError || error,
|
|
664
|
+
categorize,
|
|
665
|
+
updateOneLocal
|
|
666
|
+
};
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
// src/hooks/useElementSize/useElementSize.ts
|
|
670
|
+
var import_react7 = require("react");
|
|
671
|
+
var useElementSize = (callback) => {
|
|
672
|
+
const ref = (0, import_react7.useRef)(null);
|
|
673
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
674
|
+
const element = ref?.current;
|
|
675
|
+
if (!element) {
|
|
676
|
+
return;
|
|
523
677
|
}
|
|
524
|
-
|
|
525
|
-
|
|
678
|
+
const observer = new ResizeObserver((entries) => {
|
|
679
|
+
callback(element, entries[0], {
|
|
680
|
+
width: element.offsetWidth,
|
|
681
|
+
height: element.offsetHeight
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
observer.observe(element);
|
|
685
|
+
return () => {
|
|
686
|
+
observer.disconnect();
|
|
687
|
+
};
|
|
688
|
+
}, [callback, ref]);
|
|
689
|
+
return ref;
|
|
526
690
|
};
|
|
527
691
|
|
|
528
|
-
// src/components/
|
|
529
|
-
var
|
|
692
|
+
// src/components/BankTransactionListItem/BankTransactionListItem.tsx
|
|
693
|
+
var import_react24 = __toESM(require("react"));
|
|
530
694
|
|
|
531
|
-
// src/
|
|
532
|
-
var
|
|
533
|
-
var
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
695
|
+
// src/components/Button/Button.tsx
|
|
696
|
+
var import_react8 = __toESM(require("react"));
|
|
697
|
+
var import_classnames = __toESM(require("classnames"));
|
|
698
|
+
var Button = ({
|
|
699
|
+
className,
|
|
700
|
+
children,
|
|
701
|
+
variant = "primary" /* primary */,
|
|
702
|
+
leftIcon,
|
|
703
|
+
rightIcon,
|
|
704
|
+
iconOnly,
|
|
537
705
|
...props
|
|
538
|
-
}) =>
|
|
706
|
+
}) => {
|
|
707
|
+
let justify = "center";
|
|
708
|
+
if (leftIcon && rightIcon) {
|
|
709
|
+
justify = "space-between";
|
|
710
|
+
} else if (rightIcon) {
|
|
711
|
+
justify = "space-between";
|
|
712
|
+
} else if (leftIcon) {
|
|
713
|
+
justify = "start";
|
|
714
|
+
}
|
|
715
|
+
const baseClassName = (0, import_classnames.default)(
|
|
716
|
+
"Layer__btn",
|
|
717
|
+
`Layer__btn--${variant}`,
|
|
718
|
+
iconOnly ? "Layer__btn--icon-only" : "",
|
|
719
|
+
className
|
|
720
|
+
);
|
|
721
|
+
return /* @__PURE__ */ import_react8.default.createElement("button", { ...props, className: baseClassName }, /* @__PURE__ */ import_react8.default.createElement("span", { className: `Layer__btn-content Layer__justify--${justify}` }, leftIcon && /* @__PURE__ */ import_react8.default.createElement("span", { className: "Layer__btn-icon Layer__btn-icon--left" }, leftIcon), !iconOnly && /* @__PURE__ */ import_react8.default.createElement("span", { className: "Layer__btn-text" }, children), rightIcon && /* @__PURE__ */ import_react8.default.createElement("span", { className: "Layer__btn-icon Layer__btn-icon--right" }, rightIcon)));
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
// src/components/Button/SubmitButton.tsx
|
|
725
|
+
var import_react13 = __toESM(require("react"));
|
|
726
|
+
|
|
727
|
+
// src/icons/AlertCircle.tsx
|
|
728
|
+
var React9 = __toESM(require("react"));
|
|
729
|
+
var AlertCircle = ({ size = 18, ...props }) => /* @__PURE__ */ React9.createElement(
|
|
539
730
|
"svg",
|
|
540
731
|
{
|
|
732
|
+
viewBox: "0 0 18 18",
|
|
733
|
+
fill: "none",
|
|
541
734
|
xmlns: "http://www.w3.org/2000/svg",
|
|
735
|
+
...props,
|
|
542
736
|
width: size,
|
|
543
|
-
height: size
|
|
544
|
-
viewBox: "0 0 24 24",
|
|
545
|
-
fill: fillColor,
|
|
546
|
-
...props
|
|
737
|
+
height: size
|
|
547
738
|
},
|
|
548
|
-
/* @__PURE__ */
|
|
739
|
+
/* @__PURE__ */ React9.createElement(
|
|
549
740
|
"path",
|
|
550
741
|
{
|
|
551
|
-
|
|
742
|
+
d: "M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z",
|
|
743
|
+
stroke: "currentColor",
|
|
552
744
|
strokeLinecap: "round",
|
|
553
|
-
strokeLinejoin: "round"
|
|
554
|
-
|
|
555
|
-
|
|
745
|
+
strokeLinejoin: "round"
|
|
746
|
+
}
|
|
747
|
+
),
|
|
748
|
+
/* @__PURE__ */ React9.createElement(
|
|
749
|
+
"path",
|
|
750
|
+
{
|
|
751
|
+
d: "M9 6V9",
|
|
752
|
+
stroke: "currentColor",
|
|
753
|
+
strokeLinecap: "round",
|
|
754
|
+
strokeLinejoin: "round"
|
|
755
|
+
}
|
|
756
|
+
),
|
|
757
|
+
/* @__PURE__ */ React9.createElement(
|
|
758
|
+
"path",
|
|
759
|
+
{
|
|
760
|
+
d: "M9 12H9.0075",
|
|
761
|
+
stroke: "currentColor",
|
|
762
|
+
strokeLinecap: "round",
|
|
763
|
+
strokeLinejoin: "round"
|
|
556
764
|
}
|
|
557
765
|
)
|
|
558
766
|
);
|
|
559
|
-
var
|
|
767
|
+
var AlertCircle_default = AlertCircle;
|
|
560
768
|
|
|
561
|
-
// src/icons/
|
|
562
|
-
var
|
|
563
|
-
var
|
|
769
|
+
// src/icons/Check.tsx
|
|
770
|
+
var React10 = __toESM(require("react"));
|
|
771
|
+
var Check = ({ size = 18, ...props }) => /* @__PURE__ */ React10.createElement(
|
|
564
772
|
"svg",
|
|
565
773
|
{
|
|
566
|
-
|
|
567
|
-
width: 24,
|
|
568
|
-
height: 24,
|
|
774
|
+
viewBox: "0 0 18 18",
|
|
569
775
|
fill: "none",
|
|
570
|
-
|
|
571
|
-
...props
|
|
776
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
777
|
+
...props,
|
|
778
|
+
width: size,
|
|
779
|
+
height: size
|
|
572
780
|
},
|
|
573
|
-
/* @__PURE__ */
|
|
781
|
+
/* @__PURE__ */ React10.createElement(
|
|
574
782
|
"path",
|
|
575
783
|
{
|
|
576
|
-
|
|
784
|
+
d: "M15 4.5L6.75 12.75L3 9",
|
|
785
|
+
stroke: "currentColor",
|
|
577
786
|
strokeLinecap: "round",
|
|
578
|
-
strokeLinejoin: "round"
|
|
579
|
-
strokeWidth: 2,
|
|
580
|
-
d: "m18 15-6-6-6 6"
|
|
787
|
+
strokeLinejoin: "round"
|
|
581
788
|
}
|
|
582
789
|
)
|
|
583
790
|
);
|
|
584
|
-
var
|
|
585
|
-
|
|
586
|
-
// src/components/CategoryMenu/CategoryMenu.tsx
|
|
587
|
-
var import_react6 = __toESM(require("react"));
|
|
588
|
-
var import_react_select = __toESM(require("react-select"));
|
|
589
|
-
var CategoryMenu = ({
|
|
590
|
-
bankTransaction,
|
|
591
|
-
name,
|
|
592
|
-
value,
|
|
593
|
-
onChange
|
|
594
|
-
}) => {
|
|
595
|
-
const { categories } = useLayerContext();
|
|
596
|
-
const suggestedOptions = bankTransaction?.categorization_flow?.type === "ASK_FROM_SUGGESTIONS" /* ASK_FROM_SUGGESTIONS */ ? [
|
|
597
|
-
{
|
|
598
|
-
label: "Suggested",
|
|
599
|
-
options: bankTransaction.categorization_flow.suggestions
|
|
600
|
-
}
|
|
601
|
-
] : [];
|
|
602
|
-
const categoryOptions = (categories || []).map((category) => {
|
|
603
|
-
if (category?.subCategories && category?.subCategories?.length > 0) {
|
|
604
|
-
return {
|
|
605
|
-
label: category.display_name,
|
|
606
|
-
options: category.subCategories
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
return {
|
|
610
|
-
label: category.display_name,
|
|
611
|
-
options: [category]
|
|
612
|
-
};
|
|
613
|
-
}).filter((x) => x);
|
|
614
|
-
const options = [...suggestedOptions, ...categoryOptions];
|
|
615
|
-
return /* @__PURE__ */ import_react6.default.createElement(
|
|
616
|
-
import_react_select.default,
|
|
617
|
-
{
|
|
618
|
-
name,
|
|
619
|
-
className: "Layer__category-menu",
|
|
620
|
-
options,
|
|
621
|
-
isSearchable: true,
|
|
622
|
-
value,
|
|
623
|
-
onChange: (newValue) => newValue && onChange(newValue),
|
|
624
|
-
getOptionLabel: (category) => category.display_name,
|
|
625
|
-
getOptionValue: (category) => category.stable_name || category.category,
|
|
626
|
-
menuPortalTarget: document.body,
|
|
627
|
-
styles: { menuPortal: (base) => ({ ...base, zIndex: 9999 }) }
|
|
628
|
-
}
|
|
629
|
-
);
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
// src/components/ExpandedBankTransactionRow/ExpandedBankTransactionRow.tsx
|
|
633
|
-
var import_react9 = __toESM(require("react"));
|
|
791
|
+
var Check_default = Check;
|
|
634
792
|
|
|
635
|
-
// src/icons/
|
|
793
|
+
// src/icons/CheckCircle.tsx
|
|
636
794
|
var React11 = __toESM(require("react"));
|
|
637
|
-
var
|
|
795
|
+
var CheckCircle = ({ size = 18, ...props }) => /* @__PURE__ */ React11.createElement(
|
|
638
796
|
"svg",
|
|
639
797
|
{
|
|
798
|
+
viewBox: "0 0 18 18",
|
|
799
|
+
fill: "none",
|
|
640
800
|
xmlns: "http://www.w3.org/2000/svg",
|
|
801
|
+
...props,
|
|
641
802
|
width: size,
|
|
642
|
-
height: size
|
|
643
|
-
fill: "none",
|
|
644
|
-
viewBox: "0 0 24 24",
|
|
645
|
-
...props
|
|
803
|
+
height: size
|
|
646
804
|
},
|
|
647
805
|
/* @__PURE__ */ React11.createElement(
|
|
648
806
|
"path",
|
|
649
807
|
{
|
|
650
|
-
|
|
808
|
+
d: "M16.5 8.30999V8.99999C16.4991 10.6173 15.9754 12.191 15.007 13.4864C14.0386 14.7817 12.6775 15.7293 11.1265 16.1879C9.57557 16.6465 7.91794 16.5914 6.40085 16.0309C4.88375 15.4704 3.58848 14.4346 2.70821 13.0778C1.82794 11.721 1.40984 10.116 1.51625 8.50223C1.62266 6.88841 2.2479 5.35223 3.2987 4.12279C4.34951 2.89335 5.76958 2.03653 7.34713 1.6801C8.92469 1.32367 10.5752 1.48674 12.0525 2.14499",
|
|
809
|
+
stroke: "currentColor",
|
|
651
810
|
strokeLinecap: "round",
|
|
652
|
-
strokeLinejoin: "round"
|
|
653
|
-
|
|
654
|
-
|
|
811
|
+
strokeLinejoin: "round"
|
|
812
|
+
}
|
|
813
|
+
),
|
|
814
|
+
/* @__PURE__ */ React11.createElement(
|
|
815
|
+
"path",
|
|
816
|
+
{
|
|
817
|
+
d: "M16.5 3L9 10.5075L6.75 8.2575",
|
|
818
|
+
stroke: "currentColor",
|
|
819
|
+
strokeLinecap: "round",
|
|
820
|
+
strokeLinejoin: "round"
|
|
655
821
|
}
|
|
656
822
|
)
|
|
657
823
|
);
|
|
658
|
-
var
|
|
824
|
+
var CheckCircle_default = CheckCircle;
|
|
659
825
|
|
|
660
|
-
// src/icons/
|
|
826
|
+
// src/icons/Loader.tsx
|
|
661
827
|
var React12 = __toESM(require("react"));
|
|
662
|
-
var
|
|
828
|
+
var Loader = ({ size = 18, ...props }) => /* @__PURE__ */ React12.createElement(
|
|
663
829
|
"svg",
|
|
664
830
|
{
|
|
831
|
+
viewBox: "0 0 18 18",
|
|
832
|
+
fill: "none",
|
|
665
833
|
xmlns: "http://www.w3.org/2000/svg",
|
|
834
|
+
...props,
|
|
666
835
|
width: size,
|
|
667
|
-
height: size
|
|
668
|
-
fill: "none",
|
|
669
|
-
viewBox: "0 0 24 24",
|
|
670
|
-
...props
|
|
836
|
+
height: size
|
|
671
837
|
},
|
|
672
838
|
/* @__PURE__ */ React12.createElement(
|
|
673
839
|
"path",
|
|
674
840
|
{
|
|
675
|
-
|
|
841
|
+
d: "M9 1.5V4.5",
|
|
842
|
+
stroke: "currentColor",
|
|
676
843
|
strokeLinecap: "round",
|
|
677
|
-
strokeLinejoin: "round"
|
|
678
|
-
|
|
679
|
-
|
|
844
|
+
strokeLinejoin: "round"
|
|
845
|
+
}
|
|
846
|
+
),
|
|
847
|
+
/* @__PURE__ */ React12.createElement(
|
|
848
|
+
"path",
|
|
849
|
+
{
|
|
850
|
+
d: "M9 13.5V16.5",
|
|
851
|
+
stroke: "currentColor",
|
|
852
|
+
strokeLinecap: "round",
|
|
853
|
+
strokeLinejoin: "round"
|
|
854
|
+
}
|
|
855
|
+
),
|
|
856
|
+
/* @__PURE__ */ React12.createElement(
|
|
857
|
+
"path",
|
|
858
|
+
{
|
|
859
|
+
d: "M3.6975 3.6975L5.82 5.82",
|
|
860
|
+
stroke: "currentColor",
|
|
861
|
+
strokeLinecap: "round",
|
|
862
|
+
strokeLinejoin: "round"
|
|
863
|
+
}
|
|
864
|
+
),
|
|
865
|
+
/* @__PURE__ */ React12.createElement(
|
|
866
|
+
"path",
|
|
867
|
+
{
|
|
868
|
+
d: "M12.18 12.18L14.3025 14.3025",
|
|
869
|
+
stroke: "currentColor",
|
|
870
|
+
strokeLinecap: "round",
|
|
871
|
+
strokeLinejoin: "round"
|
|
872
|
+
}
|
|
873
|
+
),
|
|
874
|
+
/* @__PURE__ */ React12.createElement(
|
|
875
|
+
"path",
|
|
876
|
+
{
|
|
877
|
+
d: "M1.5 9H4.5",
|
|
878
|
+
stroke: "currentColor",
|
|
879
|
+
strokeLinecap: "round",
|
|
880
|
+
strokeLinejoin: "round"
|
|
881
|
+
}
|
|
882
|
+
),
|
|
883
|
+
/* @__PURE__ */ React12.createElement(
|
|
884
|
+
"path",
|
|
885
|
+
{
|
|
886
|
+
d: "M13.5 9H16.5",
|
|
887
|
+
stroke: "currentColor",
|
|
888
|
+
strokeLinecap: "round",
|
|
889
|
+
strokeLinejoin: "round"
|
|
890
|
+
}
|
|
891
|
+
),
|
|
892
|
+
/* @__PURE__ */ React12.createElement(
|
|
893
|
+
"path",
|
|
894
|
+
{
|
|
895
|
+
d: "M3.6975 14.3025L5.82 12.18",
|
|
896
|
+
stroke: "currentColor",
|
|
897
|
+
strokeLinecap: "round",
|
|
898
|
+
strokeLinejoin: "round"
|
|
899
|
+
}
|
|
900
|
+
),
|
|
901
|
+
/* @__PURE__ */ React12.createElement(
|
|
902
|
+
"path",
|
|
903
|
+
{
|
|
904
|
+
d: "M12.18 5.82L14.3025 3.6975",
|
|
905
|
+
stroke: "currentColor",
|
|
906
|
+
strokeLinecap: "round",
|
|
907
|
+
strokeLinejoin: "round"
|
|
680
908
|
}
|
|
681
909
|
)
|
|
682
910
|
);
|
|
683
|
-
var
|
|
911
|
+
var Loader_default = Loader;
|
|
684
912
|
|
|
685
|
-
// src/components/
|
|
686
|
-
var
|
|
913
|
+
// src/components/Tooltip/Tooltip.tsx
|
|
914
|
+
var import_react11 = __toESM(require("react"));
|
|
687
915
|
|
|
688
|
-
// src/components/
|
|
689
|
-
var
|
|
690
|
-
var
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
916
|
+
// src/components/Tooltip/useTooltip.ts
|
|
917
|
+
var import_react9 = __toESM(require("react"));
|
|
918
|
+
var import_react10 = require("@floating-ui/react");
|
|
919
|
+
var TooltipContext = import_react9.default.createContext(null);
|
|
920
|
+
var useTooltipContext = () => {
|
|
921
|
+
const context = import_react9.default.useContext(TooltipContext);
|
|
922
|
+
if (context == null) {
|
|
923
|
+
throw new Error("Tooltip components must be wrapped in <Tooltip />");
|
|
924
|
+
}
|
|
925
|
+
return context;
|
|
926
|
+
};
|
|
927
|
+
var useTooltip = ({
|
|
928
|
+
initialOpen = false,
|
|
929
|
+
placement = "top",
|
|
930
|
+
open: controlledOpen,
|
|
931
|
+
onOpenChange: setControlledOpen,
|
|
696
932
|
disabled,
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
933
|
+
offset: offsetProp = 5,
|
|
934
|
+
shift: shiftProp = { padding: 5 }
|
|
935
|
+
} = {}) => {
|
|
936
|
+
const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react9.useState)(initialOpen);
|
|
937
|
+
const open = controlledOpen ?? uncontrolledOpen;
|
|
938
|
+
const setOpen = setControlledOpen ?? setUncontrolledOpen;
|
|
939
|
+
const data = (0, import_react10.useFloating)({
|
|
940
|
+
placement,
|
|
941
|
+
open: disabled ? false : open,
|
|
942
|
+
onOpenChange: setOpen,
|
|
943
|
+
whileElementsMounted: import_react10.autoUpdate,
|
|
944
|
+
middleware: [
|
|
945
|
+
(0, import_react10.offset)(offsetProp),
|
|
946
|
+
(0, import_react10.flip)({
|
|
947
|
+
crossAxis: placement.includes("-"),
|
|
948
|
+
fallbackAxisSideDirection: "start",
|
|
949
|
+
padding: shiftProp?.padding ?? 5
|
|
950
|
+
}),
|
|
951
|
+
(0, import_react10.shift)(shiftProp)
|
|
952
|
+
]
|
|
953
|
+
});
|
|
954
|
+
const context = data.context;
|
|
955
|
+
const hover = (0, import_react10.useHover)(context, {
|
|
956
|
+
move: false,
|
|
957
|
+
enabled: controlledOpen == null
|
|
958
|
+
});
|
|
959
|
+
const focus = (0, import_react10.useFocus)(context, {
|
|
960
|
+
enabled: controlledOpen == null
|
|
961
|
+
});
|
|
962
|
+
const dismiss = (0, import_react10.useDismiss)(context);
|
|
963
|
+
const role = (0, import_react10.useRole)(context, { role: "tooltip" });
|
|
964
|
+
const interactions = (0, import_react10.useInteractions)([hover, focus, dismiss, role]);
|
|
965
|
+
const { isMounted, styles } = (0, import_react10.useTransitionStyles)(context, {
|
|
966
|
+
initial: {
|
|
967
|
+
opacity: 0
|
|
703
968
|
},
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
969
|
+
duration: 200
|
|
970
|
+
});
|
|
971
|
+
return import_react9.default.useMemo(
|
|
972
|
+
() => ({
|
|
973
|
+
open,
|
|
974
|
+
setOpen,
|
|
975
|
+
isMounted,
|
|
976
|
+
styles,
|
|
977
|
+
disabled,
|
|
978
|
+
...interactions,
|
|
979
|
+
...data
|
|
980
|
+
}),
|
|
981
|
+
[open, setOpen, interactions, data, styles, disabled]
|
|
716
982
|
);
|
|
717
983
|
};
|
|
718
984
|
|
|
719
|
-
// src/components/
|
|
720
|
-
var
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
onChange,
|
|
725
|
-
selected
|
|
985
|
+
// src/components/Tooltip/Tooltip.tsx
|
|
986
|
+
var import_react12 = require("@floating-ui/react");
|
|
987
|
+
var Tooltip = ({
|
|
988
|
+
children,
|
|
989
|
+
...options
|
|
726
990
|
}) => {
|
|
727
|
-
const
|
|
728
|
-
return /* @__PURE__ */
|
|
991
|
+
const tooltip = useTooltip(options);
|
|
992
|
+
return /* @__PURE__ */ import_react11.default.createElement(TooltipContext.Provider, { value: tooltip }, children);
|
|
993
|
+
};
|
|
994
|
+
var TooltipTrigger = (0, import_react11.forwardRef)(function TooltipTrigger2({ children, asChild = false, ...props }, propRef) {
|
|
995
|
+
const context = useTooltipContext();
|
|
996
|
+
const childrenRef = children.ref;
|
|
997
|
+
const ref = (0, import_react12.useMergeRefs)([context.refs.setReference, propRef, childrenRef]);
|
|
998
|
+
if (asChild && (0, import_react11.isValidElement)(children)) {
|
|
999
|
+
return (0, import_react11.cloneElement)(
|
|
1000
|
+
children,
|
|
1001
|
+
context.getReferenceProps({
|
|
1002
|
+
ref,
|
|
1003
|
+
...props,
|
|
1004
|
+
...children.props,
|
|
1005
|
+
"data-state": context.open ? "open" : "closed"
|
|
1006
|
+
})
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
return /* @__PURE__ */ import_react11.default.createElement(
|
|
1010
|
+
"span",
|
|
1011
|
+
{
|
|
1012
|
+
ref,
|
|
1013
|
+
"data-state": context.open ? "open" : "closed",
|
|
1014
|
+
className: `Layer__tooltip-trigger Layer__tooltip-trigger--${context.open ? "open" : "closed"}`,
|
|
1015
|
+
...context.getReferenceProps(props)
|
|
1016
|
+
},
|
|
1017
|
+
children
|
|
1018
|
+
);
|
|
1019
|
+
});
|
|
1020
|
+
var TooltipContent = (0, import_react11.forwardRef)(function TooltipContent2({ style, className, ...props }, propRef) {
|
|
1021
|
+
const context = useTooltipContext();
|
|
1022
|
+
const ref = (0, import_react12.useMergeRefs)([context.refs.setFloating, propRef]);
|
|
1023
|
+
if (!context.open || context.disabled)
|
|
1024
|
+
return null;
|
|
1025
|
+
return /* @__PURE__ */ import_react11.default.createElement(import_react12.FloatingPortal, null, /* @__PURE__ */ import_react11.default.createElement(
|
|
729
1026
|
"div",
|
|
730
1027
|
{
|
|
731
|
-
|
|
1028
|
+
ref,
|
|
1029
|
+
className,
|
|
1030
|
+
style: {
|
|
1031
|
+
...context.styles,
|
|
1032
|
+
...context.floatingStyles,
|
|
1033
|
+
...style
|
|
1034
|
+
},
|
|
1035
|
+
...context.getFloatingProps(props)
|
|
1036
|
+
}
|
|
1037
|
+
));
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
// src/components/Button/SubmitButton.tsx
|
|
1041
|
+
var import_classnames2 = __toESM(require("classnames"));
|
|
1042
|
+
var buildRightIcon = ({
|
|
1043
|
+
processing,
|
|
1044
|
+
error
|
|
1045
|
+
}) => {
|
|
1046
|
+
if (processing) {
|
|
1047
|
+
return /* @__PURE__ */ import_react13.default.createElement(Loader_default, { size: 14, className: "Layer__anim--rotating" });
|
|
1048
|
+
}
|
|
1049
|
+
if (error) {
|
|
1050
|
+
return /* @__PURE__ */ import_react13.default.createElement(Tooltip, { offset: 12 }, /* @__PURE__ */ import_react13.default.createElement(TooltipTrigger, null, /* @__PURE__ */ import_react13.default.createElement(AlertCircle_default, { size: 14 })), /* @__PURE__ */ import_react13.default.createElement(TooltipContent, { className: "Layer__tooltip" }, error));
|
|
1051
|
+
}
|
|
1052
|
+
return /* @__PURE__ */ import_react13.default.createElement("span", null, /* @__PURE__ */ import_react13.default.createElement(Check_default, { className: "Layer__btn-icon--on-active", size: 14 }), /* @__PURE__ */ import_react13.default.createElement(
|
|
1053
|
+
CheckCircle_default,
|
|
1054
|
+
{
|
|
1055
|
+
className: "Layer__btn-icon--on-inactive",
|
|
1056
|
+
size: 14,
|
|
1057
|
+
style: { paddingTop: 4 }
|
|
1058
|
+
}
|
|
1059
|
+
));
|
|
1060
|
+
};
|
|
1061
|
+
var SubmitButton = ({
|
|
1062
|
+
active,
|
|
1063
|
+
className,
|
|
1064
|
+
processing,
|
|
1065
|
+
disabled,
|
|
1066
|
+
error,
|
|
1067
|
+
children,
|
|
1068
|
+
...props
|
|
1069
|
+
}) => {
|
|
1070
|
+
const baseClassName = (0, import_classnames2.default)(
|
|
1071
|
+
active ? "Layer__btn--active" : "",
|
|
1072
|
+
className
|
|
1073
|
+
);
|
|
1074
|
+
return /* @__PURE__ */ import_react13.default.createElement(
|
|
1075
|
+
Button,
|
|
1076
|
+
{
|
|
1077
|
+
...props,
|
|
1078
|
+
className: baseClassName,
|
|
1079
|
+
variant: "primary" /* primary */,
|
|
1080
|
+
disabled: processing || disabled,
|
|
1081
|
+
rightIcon: buildRightIcon({ processing, error })
|
|
732
1082
|
},
|
|
733
|
-
|
|
734
|
-
RadioButton,
|
|
735
|
-
{
|
|
736
|
-
...button,
|
|
737
|
-
key: button.value,
|
|
738
|
-
name,
|
|
739
|
-
size,
|
|
740
|
-
checked: selectedValue === button.value,
|
|
741
|
-
onChange,
|
|
742
|
-
disabled: button.disabled ?? false
|
|
743
|
-
}
|
|
744
|
-
))
|
|
1083
|
+
children
|
|
745
1084
|
);
|
|
746
1085
|
};
|
|
747
1086
|
|
|
748
|
-
// src/components/
|
|
749
|
-
var
|
|
1087
|
+
// src/components/CategoryMenu/CategoryMenu.tsx
|
|
1088
|
+
var import_react14 = __toESM(require("react"));
|
|
1089
|
+
var import_react_select = __toESM(require("react-select"));
|
|
1090
|
+
var DropdownIndicator = (props) => {
|
|
1091
|
+
return /* @__PURE__ */ import_react14.default.createElement(import_react_select.components.DropdownIndicator, { ...props }, /* @__PURE__ */ import_react14.default.createElement(ChevronDown_default, null));
|
|
1092
|
+
};
|
|
1093
|
+
var CategoryMenu = ({
|
|
750
1094
|
bankTransaction,
|
|
751
|
-
|
|
1095
|
+
name,
|
|
1096
|
+
value,
|
|
1097
|
+
onChange,
|
|
1098
|
+
disabled,
|
|
1099
|
+
className
|
|
752
1100
|
}) => {
|
|
753
|
-
const {
|
|
754
|
-
const
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
1101
|
+
const { categories } = useLayerContext();
|
|
1102
|
+
const suggestedOptions = bankTransaction?.categorization_flow?.type === "ASK_FROM_SUGGESTIONS" /* ASK_FROM_SUGGESTIONS */ ? [
|
|
1103
|
+
{
|
|
1104
|
+
label: "Suggested",
|
|
1105
|
+
options: bankTransaction.categorization_flow.suggestions
|
|
1106
|
+
}
|
|
1107
|
+
] : [];
|
|
1108
|
+
const categoryOptions = (categories || []).map((category) => {
|
|
1109
|
+
if (category?.subCategories && category?.subCategories?.length > 0) {
|
|
1110
|
+
return {
|
|
1111
|
+
label: category.display_name,
|
|
1112
|
+
options: category.subCategories
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
return {
|
|
1116
|
+
label: category.display_name,
|
|
1117
|
+
options: [category]
|
|
1118
|
+
};
|
|
1119
|
+
}).filter((x) => x);
|
|
1120
|
+
const options = [...suggestedOptions, ...categoryOptions];
|
|
1121
|
+
return /* @__PURE__ */ import_react14.default.createElement(
|
|
1122
|
+
import_react_select.default,
|
|
1123
|
+
{
|
|
1124
|
+
name,
|
|
1125
|
+
className: `Layer__category-menu Layer__select ${className ?? ""}`,
|
|
1126
|
+
classNamePrefix: "Layer__select",
|
|
1127
|
+
options,
|
|
1128
|
+
isSearchable: true,
|
|
1129
|
+
value,
|
|
1130
|
+
onChange: (newValue) => newValue && onChange(newValue),
|
|
1131
|
+
getOptionLabel: (category) => category.display_name,
|
|
1132
|
+
getOptionValue: (category) => category.stable_name || category.category,
|
|
1133
|
+
menuPortalTarget: document.body,
|
|
1134
|
+
styles: { menuPortal: (base) => ({ ...base, zIndex: 9999 }) },
|
|
1135
|
+
components: { DropdownIndicator },
|
|
1136
|
+
isDisabled: disabled
|
|
1137
|
+
}
|
|
1138
|
+
);
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1141
|
+
// src/components/ExpandedBankTransactionRow/ExpandedBankTransactionRow.tsx
|
|
1142
|
+
var import_react22 = __toESM(require("react"));
|
|
1143
|
+
|
|
1144
|
+
// src/icons/FolderPlus.tsx
|
|
1145
|
+
var React17 = __toESM(require("react"));
|
|
1146
|
+
var FolderPlus = ({ size = 18, ...props }) => /* @__PURE__ */ React17.createElement(
|
|
1147
|
+
"svg",
|
|
1148
|
+
{
|
|
1149
|
+
viewBox: "0 0 18 18",
|
|
1150
|
+
fill: "none",
|
|
1151
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1152
|
+
...props,
|
|
1153
|
+
width: size,
|
|
1154
|
+
height: size
|
|
1155
|
+
},
|
|
1156
|
+
/* @__PURE__ */ React17.createElement(
|
|
1157
|
+
"path",
|
|
1158
|
+
{
|
|
1159
|
+
d: "M16.5 14.25C16.5 14.6478 16.342 15.0294 16.0607 15.3107C15.7794 15.592 15.3978 15.75 15 15.75H3C2.60218 15.75 2.22064 15.592 1.93934 15.3107C1.65804 15.0294 1.5 14.6478 1.5 14.25V3.75C1.5 3.35218 1.65804 2.97064 1.93934 2.68934C2.22064 2.40804 2.60218 2.25 3 2.25H6.75L8.25 4.5H15C15.3978 4.5 15.7794 4.65804 16.0607 4.93934C16.342 5.22064 16.5 5.60218 16.5 6V14.25Z",
|
|
1160
|
+
stroke: "currentColor",
|
|
1161
|
+
strokeLinecap: "round",
|
|
1162
|
+
strokeLinejoin: "round"
|
|
1163
|
+
}
|
|
1164
|
+
),
|
|
1165
|
+
/* @__PURE__ */ React17.createElement(
|
|
1166
|
+
"path",
|
|
1167
|
+
{
|
|
1168
|
+
d: "M9 8.25V12.75",
|
|
1169
|
+
stroke: "currentColor",
|
|
1170
|
+
strokeLinecap: "round",
|
|
1171
|
+
strokeLinejoin: "round"
|
|
1172
|
+
}
|
|
1173
|
+
),
|
|
1174
|
+
/* @__PURE__ */ React17.createElement(
|
|
1175
|
+
"path",
|
|
1176
|
+
{
|
|
1177
|
+
d: "M6.75 10.5H11.25",
|
|
1178
|
+
stroke: "currentColor",
|
|
1179
|
+
strokeLinecap: "round",
|
|
1180
|
+
strokeLinejoin: "round"
|
|
1181
|
+
}
|
|
1182
|
+
)
|
|
1183
|
+
);
|
|
1184
|
+
var FolderPlus_default = FolderPlus;
|
|
1185
|
+
|
|
1186
|
+
// src/icons/Link.tsx
|
|
1187
|
+
var React18 = __toESM(require("react"));
|
|
1188
|
+
var Link = ({ size = 18, ...props }) => /* @__PURE__ */ React18.createElement(
|
|
1189
|
+
"svg",
|
|
1190
|
+
{
|
|
1191
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1192
|
+
viewBox: "0 0 18 18",
|
|
1193
|
+
fill: "none",
|
|
1194
|
+
...props,
|
|
1195
|
+
width: size,
|
|
1196
|
+
height: size
|
|
1197
|
+
},
|
|
1198
|
+
/* @__PURE__ */ React18.createElement(
|
|
1199
|
+
"path",
|
|
1200
|
+
{
|
|
1201
|
+
d: "M7.5 9.75C7.82209 10.1806 8.23302 10.5369 8.70491 10.7947C9.17681 11.0525 9.69863 11.2058 10.235 11.2442C10.7713 11.2827 11.3097 11.2053 11.8135 11.0173C12.3173 10.8294 12.7748 10.5353 13.155 10.155L15.405 7.905C16.0881 7.19774 16.4661 6.25048 16.4575 5.26724C16.449 4.284 16.0546 3.34346 15.3593 2.64818C14.664 1.9529 13.7235 1.55851 12.7403 1.54997C11.757 1.54143 10.8098 1.9194 10.1025 2.6025L8.8125 3.885",
|
|
1202
|
+
stroke: "currentColor",
|
|
1203
|
+
strokeLinecap: "round",
|
|
1204
|
+
strokeLinejoin: "round"
|
|
1205
|
+
}
|
|
1206
|
+
),
|
|
1207
|
+
/* @__PURE__ */ React18.createElement(
|
|
1208
|
+
"path",
|
|
1209
|
+
{
|
|
1210
|
+
d: "M10.5 8.25C10.1779 7.8194 9.76698 7.46311 9.29508 7.2053C8.82319 6.94748 8.30137 6.79416 7.76501 6.75575C7.22865 6.71734 6.69031 6.79473 6.18649 6.98266C5.68267 7.1706 5.22516 7.4647 4.845 7.845L2.595 10.095C1.9119 10.8023 1.53393 11.7495 1.54247 12.7328C1.55101 13.716 1.9454 14.6565 2.64068 15.3518C3.33596 16.0471 4.2765 16.4415 5.25974 16.45C6.24298 16.4586 7.19024 16.0806 7.8975 15.3975L9.18 14.115",
|
|
1211
|
+
stroke: "currentColor",
|
|
1212
|
+
strokeLinecap: "round",
|
|
1213
|
+
strokeLinejoin: "round"
|
|
1214
|
+
}
|
|
1215
|
+
)
|
|
1216
|
+
);
|
|
1217
|
+
var Link_default = Link;
|
|
1218
|
+
|
|
1219
|
+
// src/icons/RefreshCcw.tsx
|
|
1220
|
+
var React19 = __toESM(require("react"));
|
|
1221
|
+
var RefreshCcw = ({ size = 18, ...props }) => /* @__PURE__ */ React19.createElement(
|
|
1222
|
+
"svg",
|
|
1223
|
+
{
|
|
1224
|
+
viewBox: "0 0 18 18",
|
|
1225
|
+
fill: "none",
|
|
1226
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1227
|
+
...props,
|
|
1228
|
+
width: size,
|
|
1229
|
+
height: size
|
|
1230
|
+
},
|
|
1231
|
+
/* @__PURE__ */ React19.createElement(
|
|
1232
|
+
"path",
|
|
1233
|
+
{
|
|
1234
|
+
d: "M0.75 3V7.5H5.25",
|
|
1235
|
+
stroke: "currentColor",
|
|
1236
|
+
strokeLinecap: "round",
|
|
1237
|
+
strokeLinejoin: "round"
|
|
1238
|
+
}
|
|
1239
|
+
),
|
|
1240
|
+
/* @__PURE__ */ React19.createElement(
|
|
1241
|
+
"path",
|
|
1242
|
+
{
|
|
1243
|
+
d: "M17.25 15V10.5H12.75",
|
|
1244
|
+
stroke: "currentColor",
|
|
1245
|
+
strokeLinecap: "round",
|
|
1246
|
+
strokeLinejoin: "round"
|
|
1247
|
+
}
|
|
1248
|
+
),
|
|
1249
|
+
/* @__PURE__ */ React19.createElement(
|
|
1250
|
+
"path",
|
|
1251
|
+
{
|
|
1252
|
+
d: "M15.3675 6.75C14.9871 5.67508 14.3407 4.71405 13.4884 3.95656C12.6361 3.19907 11.6059 2.66982 10.4938 2.41819C9.38167 2.16656 8.22393 2.20075 7.12861 2.51758C6.03328 2.8344 5.03606 3.42353 4.23 4.23L0.75 7.5M17.25 10.5L13.77 13.77C12.9639 14.5765 11.9667 15.1656 10.8714 15.4824C9.77607 15.7992 8.61833 15.8334 7.50621 15.5818C6.3941 15.3302 5.36385 14.8009 4.5116 14.0434C3.65935 13.2859 3.01288 12.3249 2.6325 11.25",
|
|
1253
|
+
stroke: "currentColor",
|
|
1254
|
+
strokeLinecap: "round",
|
|
1255
|
+
strokeLinejoin: "round"
|
|
1256
|
+
}
|
|
1257
|
+
)
|
|
1258
|
+
);
|
|
1259
|
+
var RefreshCcw_default = RefreshCcw;
|
|
1260
|
+
|
|
1261
|
+
// src/icons/ScissorsFullOpen.tsx
|
|
1262
|
+
var React20 = __toESM(require("react"));
|
|
1263
|
+
var ScissorsFullOpen = ({ size = 12, ...props }) => /* @__PURE__ */ React20.createElement(
|
|
1264
|
+
"svg",
|
|
1265
|
+
{
|
|
1266
|
+
viewBox: "0 0 12 12",
|
|
1267
|
+
fill: "none",
|
|
1268
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1269
|
+
...props,
|
|
1270
|
+
width: size,
|
|
1271
|
+
height: size
|
|
1272
|
+
},
|
|
1273
|
+
/* @__PURE__ */ React20.createElement("g", { id: "scissors" }, /* @__PURE__ */ React20.createElement(
|
|
1274
|
+
"path",
|
|
1275
|
+
{
|
|
1276
|
+
id: "Vector",
|
|
1277
|
+
d: "M3 4.5C3.82843 4.5 4.5 3.82843 4.5 3C4.5 2.17157 3.82843 1.5 3 1.5C2.17157 1.5 1.5 2.17157 1.5 3C1.5 3.82843 2.17157 4.5 3 4.5Z",
|
|
1278
|
+
stroke: "currentColor",
|
|
1279
|
+
strokeLinecap: "round",
|
|
1280
|
+
strokeLinejoin: "round"
|
|
1281
|
+
}
|
|
1282
|
+
), /* @__PURE__ */ React20.createElement(
|
|
1283
|
+
"path",
|
|
1284
|
+
{
|
|
1285
|
+
id: "Vector_2",
|
|
1286
|
+
d: "M3 10.5C3.82843 10.5 4.5 9.82843 4.5 9C4.5 8.17157 3.82843 7.5 3 7.5C2.17157 7.5 1.5 8.17157 1.5 9C1.5 9.82843 2.17157 10.5 3 10.5Z",
|
|
1287
|
+
stroke: "currentColor",
|
|
1288
|
+
strokeLinecap: "round",
|
|
1289
|
+
strokeLinejoin: "round"
|
|
1290
|
+
}
|
|
1291
|
+
), /* @__PURE__ */ React20.createElement(
|
|
1292
|
+
"path",
|
|
1293
|
+
{
|
|
1294
|
+
id: "Vector_3",
|
|
1295
|
+
d: "M10 2L4.06 7.94",
|
|
1296
|
+
stroke: "currentColor",
|
|
1297
|
+
strokeLinecap: "round",
|
|
1298
|
+
strokeLinejoin: "round"
|
|
1299
|
+
}
|
|
1300
|
+
), /* @__PURE__ */ React20.createElement(
|
|
1301
|
+
"path",
|
|
1302
|
+
{
|
|
1303
|
+
id: "Vector_4",
|
|
1304
|
+
d: "M7.235 7.23999L10 9.99999",
|
|
1305
|
+
stroke: "currentColor",
|
|
1306
|
+
strokeLinecap: "round",
|
|
1307
|
+
strokeLinejoin: "round"
|
|
1308
|
+
}
|
|
1309
|
+
), /* @__PURE__ */ React20.createElement(
|
|
1310
|
+
"path",
|
|
1311
|
+
{
|
|
1312
|
+
id: "Vector_5",
|
|
1313
|
+
d: "M4.06 4.06006L6 6.00006",
|
|
1314
|
+
stroke: "currentColor",
|
|
1315
|
+
strokeLinecap: "round",
|
|
1316
|
+
strokeLinejoin: "round"
|
|
1317
|
+
}
|
|
1318
|
+
))
|
|
1319
|
+
);
|
|
1320
|
+
var ScissorsFullOpen_default = ScissorsFullOpen;
|
|
1321
|
+
|
|
1322
|
+
// src/components/Input/Input.tsx
|
|
1323
|
+
var import_react15 = __toESM(require("react"));
|
|
1324
|
+
var import_classnames3 = __toESM(require("classnames"));
|
|
1325
|
+
var Input = ({ className, ...props }) => {
|
|
1326
|
+
const baseClassName = (0, import_classnames3.default)("Layer__input", className);
|
|
1327
|
+
return /* @__PURE__ */ import_react15.default.createElement("input", { ...props, className: baseClassName });
|
|
1328
|
+
};
|
|
1329
|
+
|
|
1330
|
+
// src/components/Input/InputGroup.tsx
|
|
1331
|
+
var import_react18 = __toESM(require("react"));
|
|
1332
|
+
|
|
1333
|
+
// src/components/Typography/Text.tsx
|
|
1334
|
+
var import_react16 = __toESM(require("react"));
|
|
1335
|
+
var import_classnames4 = __toESM(require("classnames"));
|
|
1336
|
+
var Text = ({
|
|
1337
|
+
as: Component = "p",
|
|
1338
|
+
className,
|
|
1339
|
+
children,
|
|
1340
|
+
size = "md" /* md */,
|
|
1341
|
+
weight = "normal" /* normal */,
|
|
1342
|
+
withTooltip,
|
|
1343
|
+
...props
|
|
1344
|
+
}) => {
|
|
1345
|
+
const baseClassName = (0, import_classnames4.default)(
|
|
1346
|
+
`Layer__text Layer__text--${size} Layer__text--${weight}`,
|
|
1347
|
+
className
|
|
1348
|
+
);
|
|
1349
|
+
if (withTooltip) {
|
|
1350
|
+
return /* @__PURE__ */ import_react16.default.createElement(
|
|
1351
|
+
TextWithTooltip,
|
|
758
1352
|
{
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
rowState.splits[rowNumber].amount = newAmount;
|
|
787
|
-
rowState.splits[rowNumber].inputValue = newDisplaying;
|
|
788
|
-
rowState.splits[rowState.splits.length - 1].amount = remaining;
|
|
789
|
-
rowState.splits[rowState.splits.length - 1].inputValue = centsToDollars(remaining);
|
|
790
|
-
updateRowState({ ...rowState });
|
|
791
|
-
};
|
|
792
|
-
const onBlur = (event) => {
|
|
793
|
-
if (event.target.value === "") {
|
|
794
|
-
const [_, index] = event.target.name.split("-");
|
|
795
|
-
rowState.splits[parseInt(index)].inputValue = "0.00";
|
|
796
|
-
updateRowState({ ...rowState });
|
|
1353
|
+
as: Component,
|
|
1354
|
+
className: baseClassName,
|
|
1355
|
+
size,
|
|
1356
|
+
weight,
|
|
1357
|
+
withTooltip,
|
|
1358
|
+
...props
|
|
1359
|
+
},
|
|
1360
|
+
children
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
return /* @__PURE__ */ import_react16.default.createElement(Component, { ...props, className: baseClassName }, children);
|
|
1364
|
+
};
|
|
1365
|
+
var TextWithTooltip = ({
|
|
1366
|
+
as: Component = "p",
|
|
1367
|
+
className,
|
|
1368
|
+
children,
|
|
1369
|
+
size = "md" /* md */,
|
|
1370
|
+
weight = "normal" /* normal */,
|
|
1371
|
+
withTooltip = "whenTruncated" /* whenTruncated */,
|
|
1372
|
+
tooltipOptions,
|
|
1373
|
+
...props
|
|
1374
|
+
}) => {
|
|
1375
|
+
const textElementRef = (0, import_react16.useRef)();
|
|
1376
|
+
const compareSize = () => {
|
|
1377
|
+
if (textElementRef.current) {
|
|
1378
|
+
const compare = textElementRef.current.children[0].scrollWidth > textElementRef.current.children[0].clientWidth;
|
|
1379
|
+
setHover(compare);
|
|
797
1380
|
}
|
|
798
1381
|
};
|
|
799
|
-
|
|
800
|
-
|
|
1382
|
+
(0, import_react16.useEffect)(() => {
|
|
1383
|
+
compareSize();
|
|
1384
|
+
window.addEventListener("resize", compareSize);
|
|
1385
|
+
}, []);
|
|
1386
|
+
(0, import_react16.useEffect)(
|
|
1387
|
+
() => () => {
|
|
1388
|
+
window.removeEventListener("resize", compareSize);
|
|
1389
|
+
},
|
|
1390
|
+
[]
|
|
801
1391
|
);
|
|
802
|
-
const
|
|
803
|
-
|
|
804
|
-
|
|
1392
|
+
const [hoverStatus, setHover] = (0, import_react16.useState)(false);
|
|
1393
|
+
const contentClassName = (0, import_classnames4.default)(
|
|
1394
|
+
"Layer__tooltip",
|
|
1395
|
+
tooltipOptions?.contentClassName
|
|
1396
|
+
);
|
|
1397
|
+
return /* @__PURE__ */ import_react16.default.createElement(
|
|
1398
|
+
Tooltip,
|
|
1399
|
+
{
|
|
1400
|
+
disabled: !hoverStatus,
|
|
1401
|
+
offset: tooltipOptions?.offset,
|
|
1402
|
+
shift: tooltipOptions?.shift
|
|
1403
|
+
},
|
|
1404
|
+
/* @__PURE__ */ import_react16.default.createElement(TooltipTrigger, null, /* @__PURE__ */ import_react16.default.createElement(Component, { className, ref: textElementRef, ...props }, children)),
|
|
1405
|
+
/* @__PURE__ */ import_react16.default.createElement(TooltipContent, { className: contentClassName }, children)
|
|
1406
|
+
);
|
|
1407
|
+
};
|
|
1408
|
+
|
|
1409
|
+
// src/components/Typography/Heading.tsx
|
|
1410
|
+
var import_react17 = __toESM(require("react"));
|
|
1411
|
+
var import_classnames5 = __toESM(require("classnames"));
|
|
1412
|
+
var Heading = ({
|
|
1413
|
+
as: Component = "h2",
|
|
1414
|
+
className,
|
|
1415
|
+
children,
|
|
1416
|
+
size = "primary" /* primary */
|
|
1417
|
+
}) => {
|
|
1418
|
+
const baseClassName = (0, import_classnames5.default)(
|
|
1419
|
+
`Layer__heading Layer__heading--${size}`,
|
|
1420
|
+
className
|
|
1421
|
+
);
|
|
1422
|
+
return /* @__PURE__ */ import_react17.default.createElement(Component, { className: baseClassName }, children);
|
|
1423
|
+
};
|
|
1424
|
+
|
|
1425
|
+
// src/components/Input/InputGroup.tsx
|
|
1426
|
+
var import_classnames6 = __toESM(require("classnames"));
|
|
1427
|
+
var InputGroup = ({
|
|
1428
|
+
label,
|
|
1429
|
+
name,
|
|
1430
|
+
className,
|
|
1431
|
+
children
|
|
1432
|
+
}) => {
|
|
1433
|
+
const baseClassName = (0, import_classnames6.default)("Layer__input-group", className);
|
|
1434
|
+
return /* @__PURE__ */ import_react18.default.createElement("div", { className: baseClassName }, label && /* @__PURE__ */ import_react18.default.createElement(
|
|
1435
|
+
Text,
|
|
1436
|
+
{
|
|
1437
|
+
as: "label",
|
|
1438
|
+
size: "sm" /* sm */,
|
|
1439
|
+
className: "Layer__input-label",
|
|
1440
|
+
htmlFor: name
|
|
1441
|
+
},
|
|
1442
|
+
label
|
|
1443
|
+
), children);
|
|
1444
|
+
};
|
|
1445
|
+
|
|
1446
|
+
// src/components/Input/FileInput.tsx
|
|
1447
|
+
var import_react19 = __toESM(require("react"));
|
|
1448
|
+
|
|
1449
|
+
// src/icons/UploadCloud.tsx
|
|
1450
|
+
var React25 = __toESM(require("react"));
|
|
1451
|
+
var UploadCloud = ({ size = 18, ...props }) => /* @__PURE__ */ React25.createElement(
|
|
1452
|
+
"svg",
|
|
1453
|
+
{
|
|
1454
|
+
viewBox: "0 0 18 18",
|
|
1455
|
+
fill: "none",
|
|
1456
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1457
|
+
...props,
|
|
1458
|
+
width: size,
|
|
1459
|
+
height: size
|
|
1460
|
+
},
|
|
1461
|
+
/* @__PURE__ */ React25.createElement(
|
|
1462
|
+
"path",
|
|
1463
|
+
{
|
|
1464
|
+
d: "M12 12L9 9L6 12",
|
|
1465
|
+
stroke: "currentColor",
|
|
1466
|
+
strokeLinecap: "round",
|
|
1467
|
+
strokeLinejoin: "round"
|
|
1468
|
+
}
|
|
1469
|
+
),
|
|
1470
|
+
/* @__PURE__ */ React25.createElement(
|
|
1471
|
+
"path",
|
|
1472
|
+
{
|
|
1473
|
+
d: "M9 9V15.75",
|
|
1474
|
+
stroke: "currentColor",
|
|
1475
|
+
strokeLinecap: "round",
|
|
1476
|
+
strokeLinejoin: "round"
|
|
1477
|
+
}
|
|
1478
|
+
),
|
|
1479
|
+
/* @__PURE__ */ React25.createElement(
|
|
1480
|
+
"path",
|
|
1481
|
+
{
|
|
1482
|
+
d: "M15.2925 13.7925C16.024 13.3937 16.6019 12.7626 16.9349 11.999C17.2679 11.2353 17.3372 10.3824 17.1317 9.57501C16.9262 8.7676 16.4576 8.05162 15.8 7.54007C15.1424 7.02852 14.3332 6.75054 13.5 6.74999H12.555C12.328 5.87192 11.9049 5.05674 11.3175 4.36573C10.7301 3.67473 9.99364 3.12588 9.16358 2.76044C8.33352 2.39501 7.43141 2.22251 6.52509 2.2559C5.61876 2.28929 4.7318 2.52771 3.93088 2.95324C3.12997 3.37876 2.43593 3.98032 1.90097 4.71267C1.366 5.44503 1.00402 6.28914 0.842236 7.18153C0.680453 8.07393 0.72308 8.99139 0.966911 9.86493C1.21074 10.7385 1.64943 11.5454 2.25 12.225",
|
|
1483
|
+
stroke: "currentColor",
|
|
1484
|
+
strokeLinecap: "round",
|
|
1485
|
+
strokeLinejoin: "round"
|
|
1486
|
+
}
|
|
1487
|
+
),
|
|
1488
|
+
/* @__PURE__ */ React25.createElement(
|
|
1489
|
+
"path",
|
|
1490
|
+
{
|
|
1491
|
+
d: "M12 12L9 9L6 12",
|
|
1492
|
+
stroke: "currentColor",
|
|
1493
|
+
strokeLinecap: "round",
|
|
1494
|
+
strokeLinejoin: "round"
|
|
1495
|
+
}
|
|
1496
|
+
)
|
|
1497
|
+
);
|
|
1498
|
+
var UploadCloud_default = UploadCloud;
|
|
1499
|
+
|
|
1500
|
+
// src/components/Input/FileInput.tsx
|
|
1501
|
+
var FileInput = ({ text = "Upload", onUpload }) => {
|
|
1502
|
+
const hiddenFileInput = (0, import_react19.useRef)(null);
|
|
1503
|
+
const onClick = () => {
|
|
1504
|
+
if (hiddenFileInput.current) {
|
|
1505
|
+
hiddenFileInput.current.click();
|
|
1506
|
+
}
|
|
805
1507
|
};
|
|
806
|
-
const
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
category: {
|
|
811
|
-
type: "StableName",
|
|
812
|
-
stable_name: rowState?.splits[0].category?.stable_name || rowState?.splits[0].category?.category
|
|
813
|
-
}
|
|
814
|
-
} : {
|
|
815
|
-
type: "Split",
|
|
816
|
-
entries: rowState.splits.map((split) => ({
|
|
817
|
-
category: split.category?.stable_name || split.category?.category,
|
|
818
|
-
amount: split.amount
|
|
819
|
-
}))
|
|
820
|
-
}
|
|
821
|
-
).then(close);
|
|
822
|
-
const className = "Layer__expanded-bank-transaction-row";
|
|
823
|
-
return /* @__PURE__ */ import_react9.default.createElement("div", { className }, /* @__PURE__ */ import_react9.default.createElement("div", { className: `${className}__purpose-button` }, /* @__PURE__ */ import_react9.default.createElement(
|
|
824
|
-
RadioButtonGroup,
|
|
825
|
-
{
|
|
826
|
-
name: `purpose-${bankTransaction.id}`,
|
|
827
|
-
size: "small",
|
|
828
|
-
buttons: [
|
|
829
|
-
{ value: "categorize", label: "Categorize" },
|
|
830
|
-
{ value: "match", label: "Match", disabled: true }
|
|
831
|
-
],
|
|
832
|
-
selected: purpose,
|
|
833
|
-
onChange: onChangePurpose
|
|
1508
|
+
const onChange = (event) => {
|
|
1509
|
+
if (event.target.files && event.target.files.length > 0 && onUpload) {
|
|
1510
|
+
const fileUploaded = event.target.files[0];
|
|
1511
|
+
onUpload(fileUploaded);
|
|
834
1512
|
}
|
|
835
|
-
|
|
836
|
-
|
|
1513
|
+
};
|
|
1514
|
+
return /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement(
|
|
1515
|
+
Button,
|
|
837
1516
|
{
|
|
838
|
-
|
|
839
|
-
|
|
1517
|
+
onClick,
|
|
1518
|
+
variant: "secondary" /* secondary */,
|
|
1519
|
+
leftIcon: /* @__PURE__ */ import_react19.default.createElement(UploadCloud_default, null)
|
|
840
1520
|
},
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1521
|
+
text
|
|
1522
|
+
), /* @__PURE__ */ import_react19.default.createElement(
|
|
1523
|
+
"input",
|
|
1524
|
+
{
|
|
1525
|
+
type: "file",
|
|
1526
|
+
onChange,
|
|
1527
|
+
ref: hiddenFileInput,
|
|
1528
|
+
style: { display: "none" }
|
|
1529
|
+
}
|
|
1530
|
+
));
|
|
1531
|
+
};
|
|
1532
|
+
|
|
1533
|
+
// src/components/Textarea/Textarea.tsx
|
|
1534
|
+
var import_react20 = __toESM(require("react"));
|
|
1535
|
+
var import_classnames7 = __toESM(require("classnames"));
|
|
1536
|
+
var Textarea = ({
|
|
1537
|
+
className,
|
|
1538
|
+
...props
|
|
1539
|
+
}) => {
|
|
1540
|
+
const baseClassName = (0, import_classnames7.default)("Layer__textarea", className);
|
|
1541
|
+
return /* @__PURE__ */ import_react20.default.createElement("textarea", { ...props, className: baseClassName });
|
|
1542
|
+
};
|
|
1543
|
+
|
|
1544
|
+
// src/components/Toggle/Toggle.tsx
|
|
1545
|
+
var import_react21 = __toESM(require("react"));
|
|
1546
|
+
var import_classnames8 = __toESM(require("classnames"));
|
|
1547
|
+
var Toggle = ({
|
|
1548
|
+
name,
|
|
1549
|
+
options,
|
|
1550
|
+
selected,
|
|
1551
|
+
onChange,
|
|
1552
|
+
size = "medium" /* medium */
|
|
1553
|
+
}) => {
|
|
1554
|
+
const [currentWidth, setCurrentWidth] = (0, import_react21.useState)(0);
|
|
1555
|
+
const [thumbPos, setThumbPos] = (0, import_react21.useState)({ left: 0, width: 0 });
|
|
1556
|
+
const [initialized, setInitialized] = (0, import_react21.useState)(false);
|
|
1557
|
+
const toggleRef = useElementSize((a, b, c) => {
|
|
1558
|
+
if (c.width && c?.width !== currentWidth) {
|
|
1559
|
+
setCurrentWidth(c.width);
|
|
1560
|
+
}
|
|
1561
|
+
});
|
|
1562
|
+
const selectedValue = selected || options[0].value;
|
|
1563
|
+
const baseClassName = (0, import_classnames8.default)(
|
|
1564
|
+
"Layer__toggle",
|
|
1565
|
+
`Layer__toggle--${size}`,
|
|
1566
|
+
initialized ? "Layer__toggle--initialized" : ""
|
|
1567
|
+
);
|
|
1568
|
+
const handleChange = (e) => {
|
|
1569
|
+
updateThumbPosition(Number(e.target.getAttribute("data-idx") ?? 0));
|
|
1570
|
+
onChange(e);
|
|
1571
|
+
};
|
|
1572
|
+
const updateThumbPosition = (active) => {
|
|
1573
|
+
if (!toggleRef?.current) {
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
const optionsNodes = [...toggleRef.current.children].filter(
|
|
1577
|
+
(c) => c.className.includes("Layer__toggle-option")
|
|
1578
|
+
);
|
|
1579
|
+
let shift2 = 0;
|
|
1580
|
+
let width = thumbPos.width;
|
|
1581
|
+
optionsNodes.forEach((c, i) => {
|
|
1582
|
+
if (i < active) {
|
|
1583
|
+
shift2 = shift2 + c.offsetWidth;
|
|
1584
|
+
} else if (i === active) {
|
|
1585
|
+
width = c.offsetWidth;
|
|
845
1586
|
}
|
|
846
|
-
)
|
|
847
|
-
/*
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
)
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
1587
|
+
});
|
|
1588
|
+
shift2 = shift2 + (size === "medium" /* medium */ ? 2 : 1);
|
|
1589
|
+
setThumbPos({ left: shift2, width });
|
|
1590
|
+
};
|
|
1591
|
+
(0, import_react21.useEffect)(() => {
|
|
1592
|
+
const selectedIndex = getSelectedIndex();
|
|
1593
|
+
updateThumbPosition(selectedIndex);
|
|
1594
|
+
setTimeout(() => {
|
|
1595
|
+
setInitialized(true);
|
|
1596
|
+
}, 400);
|
|
1597
|
+
}, []);
|
|
1598
|
+
(0, import_react21.useEffect)(() => {
|
|
1599
|
+
const selectedIndex = getSelectedIndex();
|
|
1600
|
+
updateThumbPosition(selectedIndex);
|
|
1601
|
+
}, [currentWidth]);
|
|
1602
|
+
const getSelectedIndex = () => {
|
|
1603
|
+
let selectedIndex = options.findIndex(
|
|
1604
|
+
(option) => option.value === selectedValue
|
|
1605
|
+
);
|
|
1606
|
+
if (selectedIndex === -1) {
|
|
1607
|
+
return 0;
|
|
1608
|
+
}
|
|
1609
|
+
return selectedIndex;
|
|
1610
|
+
};
|
|
1611
|
+
return /* @__PURE__ */ import_react21.default.createElement("div", { className: baseClassName, ref: toggleRef }, options.map((option, index) => /* @__PURE__ */ import_react21.default.createElement(
|
|
1612
|
+
ToggleOption,
|
|
1613
|
+
{
|
|
1614
|
+
...option,
|
|
1615
|
+
size,
|
|
1616
|
+
key: option.value,
|
|
1617
|
+
name,
|
|
1618
|
+
checked: selectedValue === option.value,
|
|
1619
|
+
onChange: handleChange,
|
|
1620
|
+
disabled: option.disabled ?? false,
|
|
1621
|
+
index
|
|
1622
|
+
}
|
|
1623
|
+
)), /* @__PURE__ */ import_react21.default.createElement("span", { className: "Layer__toggle__thumb", style: { ...thumbPos } }));
|
|
1624
|
+
};
|
|
1625
|
+
var ToggleOption = ({
|
|
1626
|
+
checked,
|
|
1627
|
+
label,
|
|
1628
|
+
name,
|
|
1629
|
+
onChange,
|
|
1630
|
+
value,
|
|
1631
|
+
size,
|
|
1632
|
+
leftIcon,
|
|
1633
|
+
disabled,
|
|
1634
|
+
index
|
|
1635
|
+
}) => {
|
|
1636
|
+
return /* @__PURE__ */ import_react21.default.createElement("label", { className: `Layer__toggle-option`, "data-checked": checked }, /* @__PURE__ */ import_react21.default.createElement(
|
|
1637
|
+
"input",
|
|
1638
|
+
{
|
|
1639
|
+
type: "radio",
|
|
1640
|
+
checked,
|
|
1641
|
+
name,
|
|
1642
|
+
onChange,
|
|
1643
|
+
value,
|
|
1644
|
+
disabled: disabled ?? false,
|
|
1645
|
+
"data-idx": index
|
|
1646
|
+
}
|
|
1647
|
+
), /* @__PURE__ */ import_react21.default.createElement("span", { className: "Layer__toggle-option-content" }, leftIcon && /* @__PURE__ */ import_react21.default.createElement("span", { className: "Layer__toggle-option__icon" }, leftIcon), /* @__PURE__ */ import_react21.default.createElement("span", null, label)));
|
|
1648
|
+
};
|
|
1649
|
+
|
|
1650
|
+
// src/components/ExpandedBankTransactionRow/ExpandedBankTransactionRow.tsx
|
|
1651
|
+
var ExpandedBankTransactionRow = (0, import_react22.forwardRef)(
|
|
1652
|
+
({
|
|
1653
|
+
bankTransaction,
|
|
1654
|
+
isOpen = false,
|
|
1655
|
+
asListItem = false,
|
|
1656
|
+
showSubmitButton = false
|
|
1657
|
+
}, ref) => {
|
|
1658
|
+
const { categorize: categorizeBankTransaction2 } = useBankTransactions();
|
|
1659
|
+
const [purpose, setPurpose] = (0, import_react22.useState)("categorize" /* categorize */);
|
|
1660
|
+
const defaultCategory = bankTransaction.category || bankTransaction.categorization_flow?.type === "ASK_FROM_SUGGESTIONS" /* ASK_FROM_SUGGESTIONS */ && bankTransaction.categorization_flow?.suggestions?.[0];
|
|
1661
|
+
const [rowState, updateRowState] = (0, import_react22.useState)({
|
|
1662
|
+
splits: [
|
|
1663
|
+
{
|
|
1664
|
+
amount: bankTransaction.amount,
|
|
1665
|
+
inputValue: centsToDollars(bankTransaction.amount),
|
|
1666
|
+
category: defaultCategory
|
|
1667
|
+
}
|
|
1668
|
+
],
|
|
1669
|
+
description: "",
|
|
1670
|
+
file: void 0
|
|
1671
|
+
});
|
|
1672
|
+
const addSplit = () => updateRowState({
|
|
1673
|
+
...rowState,
|
|
1674
|
+
splits: [
|
|
1675
|
+
...rowState.splits,
|
|
1676
|
+
{ amount: 0, inputValue: "0.00", category: defaultCategory }
|
|
1677
|
+
]
|
|
1678
|
+
});
|
|
1679
|
+
const removeSplit = () => updateRowState({
|
|
1680
|
+
...rowState,
|
|
1681
|
+
splits: rowState.splits.slice(0, -1)
|
|
1682
|
+
});
|
|
1683
|
+
const updateAmounts = (rowNumber) => (event) => {
|
|
1684
|
+
const newAmount = dollarsToCents(event.target.value) || 0;
|
|
1685
|
+
const newDisplaying = event.target.value;
|
|
1686
|
+
const splitTotal = rowState.splits.slice(0, -1).reduce((sum, split, index) => {
|
|
1687
|
+
const amount = index === rowNumber ? newAmount : split.amount;
|
|
1688
|
+
return sum + amount;
|
|
1689
|
+
}, 0);
|
|
1690
|
+
const remaining = bankTransaction.amount - splitTotal;
|
|
1691
|
+
rowState.splits[rowNumber].amount = newAmount;
|
|
1692
|
+
rowState.splits[rowNumber].inputValue = newDisplaying;
|
|
1693
|
+
rowState.splits[rowState.splits.length - 1].amount = remaining;
|
|
1694
|
+
rowState.splits[rowState.splits.length - 1].inputValue = centsToDollars(remaining);
|
|
1695
|
+
updateRowState({ ...rowState });
|
|
1696
|
+
};
|
|
1697
|
+
const onBlur = (event) => {
|
|
1698
|
+
if (event.target.value === "") {
|
|
1699
|
+
const [_, index] = event.target.name.split("-");
|
|
1700
|
+
rowState.splits[parseInt(index)].inputValue = "0.00";
|
|
1701
|
+
updateRowState({ ...rowState });
|
|
872
1702
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
"
|
|
876
|
-
|
|
877
|
-
|
|
1703
|
+
};
|
|
1704
|
+
const onChangePurpose = (event) => setPurpose(
|
|
1705
|
+
event.target.value === "match" /* match */ ? "match" /* match */ : "categorize" /* categorize */
|
|
1706
|
+
);
|
|
1707
|
+
const changeCategory = (index, newValue) => {
|
|
1708
|
+
rowState.splits[index].category = newValue;
|
|
1709
|
+
updateRowState({ ...rowState });
|
|
1710
|
+
};
|
|
1711
|
+
const save = () => categorizeBankTransaction2(
|
|
1712
|
+
bankTransaction.id,
|
|
1713
|
+
rowState.splits.length === 1 ? {
|
|
1714
|
+
type: "Category",
|
|
1715
|
+
category: {
|
|
1716
|
+
type: "StableName",
|
|
1717
|
+
stable_name: rowState?.splits[0].category?.stable_name || rowState?.splits[0].category?.category
|
|
1718
|
+
}
|
|
1719
|
+
} : {
|
|
1720
|
+
type: "Split",
|
|
1721
|
+
entries: rowState.splits.map((split) => ({
|
|
1722
|
+
category: split.category?.stable_name || split.category?.category,
|
|
1723
|
+
amount: split.amount
|
|
1724
|
+
}))
|
|
878
1725
|
}
|
|
879
|
-
)
|
|
880
|
-
|
|
881
|
-
|
|
1726
|
+
).catch((e) => console.error(e));
|
|
1727
|
+
(0, import_react22.useImperativeHandle)(ref, () => ({
|
|
1728
|
+
save
|
|
1729
|
+
}));
|
|
1730
|
+
const className = "Layer__expanded-bank-transaction-row";
|
|
1731
|
+
return /* @__PURE__ */ import_react22.default.createElement(
|
|
1732
|
+
"span",
|
|
882
1733
|
{
|
|
883
|
-
className: `${className}
|
|
884
|
-
onClick: removeSplit
|
|
1734
|
+
className: `${className} ${className}--${isOpen ? "expanded" : "collapsed"}`
|
|
885
1735
|
},
|
|
886
|
-
/* @__PURE__ */
|
|
887
|
-
|
|
888
|
-
)),
|
|
889
|
-
/* @__PURE__ */ import_react9.default.createElement("div", { className: `${className}__table-cell` }, rowState.splits.map((split, index) => /* @__PURE__ */ import_react9.default.createElement(
|
|
890
|
-
"div",
|
|
891
|
-
{
|
|
892
|
-
className: `${className}__table-cell--split-entry`,
|
|
893
|
-
key: `split-${index}`
|
|
894
|
-
},
|
|
895
|
-
/* @__PURE__ */ import_react9.default.createElement(
|
|
896
|
-
CategoryMenu,
|
|
1736
|
+
/* @__PURE__ */ import_react22.default.createElement("span", { className: `${className}__wrapper` }, /* @__PURE__ */ import_react22.default.createElement("div", { className: `${className}__content-toggle` }, /* @__PURE__ */ import_react22.default.createElement(
|
|
1737
|
+
Toggle,
|
|
897
1738
|
{
|
|
898
|
-
bankTransaction
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
1739
|
+
name: `purpose-${bankTransaction.id}${asListItem ? "-li" : ""}`,
|
|
1740
|
+
size: "small" /* small */,
|
|
1741
|
+
options: [
|
|
1742
|
+
{
|
|
1743
|
+
value: "categorize",
|
|
1744
|
+
label: "Categorize",
|
|
1745
|
+
leftIcon: /* @__PURE__ */ import_react22.default.createElement(FolderPlus_default, { size: 15 })
|
|
1746
|
+
},
|
|
1747
|
+
{
|
|
1748
|
+
value: "match",
|
|
1749
|
+
label: "Match",
|
|
1750
|
+
disabled: true,
|
|
1751
|
+
leftIcon: /* @__PURE__ */ import_react22.default.createElement(RefreshCcw_default, { size: 15 })
|
|
1752
|
+
}
|
|
1753
|
+
],
|
|
1754
|
+
selected: purpose,
|
|
1755
|
+
onChange: onChangePurpose
|
|
902
1756
|
}
|
|
903
|
-
),
|
|
904
|
-
|
|
905
|
-
"input",
|
|
1757
|
+
)), /* @__PURE__ */ import_react22.default.createElement(
|
|
1758
|
+
"div",
|
|
906
1759
|
{
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1760
|
+
className: `${className}__content`,
|
|
1761
|
+
id: `expanded-${bankTransaction.id}`
|
|
1762
|
+
},
|
|
1763
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: `${className}__splits` }, /* @__PURE__ */ import_react22.default.createElement("div", { className: `${className}__splits-inputs` }, rowState.splits.map((split, index) => /* @__PURE__ */ import_react22.default.createElement(
|
|
1764
|
+
"div",
|
|
1765
|
+
{
|
|
1766
|
+
className: `${className}__table-cell--split-entry`,
|
|
1767
|
+
key: `split-${index}`
|
|
1768
|
+
},
|
|
1769
|
+
rowState.splits.length > 1 && /* @__PURE__ */ import_react22.default.createElement(
|
|
1770
|
+
Input,
|
|
1771
|
+
{
|
|
1772
|
+
type: "text",
|
|
1773
|
+
name: `split-${index}${asListItem ? "-li" : ""}`,
|
|
1774
|
+
disabled: index + 1 === rowState.splits.length,
|
|
1775
|
+
onChange: updateAmounts(index),
|
|
1776
|
+
value: split.inputValue,
|
|
1777
|
+
onBlur,
|
|
1778
|
+
className: `${className}__split-amount${split.amount < 0 ? "--negative" : ""}`
|
|
1779
|
+
}
|
|
1780
|
+
),
|
|
1781
|
+
/* @__PURE__ */ import_react22.default.createElement(
|
|
1782
|
+
CategoryMenu,
|
|
1783
|
+
{
|
|
1784
|
+
bankTransaction,
|
|
1785
|
+
name: `category-${index}${asListItem ? "-li" : ""}`,
|
|
1786
|
+
value: split.category,
|
|
1787
|
+
onChange: (value) => changeCategory(index, value),
|
|
1788
|
+
className: "Layer__category-menu--full"
|
|
1789
|
+
}
|
|
1790
|
+
)
|
|
1791
|
+
))), /* @__PURE__ */ import_react22.default.createElement("div", { className: `${className}__splits-buttons` }, rowState.splits.length === 1 ? /* @__PURE__ */ import_react22.default.createElement(
|
|
1792
|
+
Button,
|
|
1793
|
+
{
|
|
1794
|
+
onClick: addSplit,
|
|
1795
|
+
leftIcon: /* @__PURE__ */ import_react22.default.createElement(ScissorsFullOpen_default, { size: 14 }),
|
|
1796
|
+
variant: "secondary" /* secondary */
|
|
1797
|
+
},
|
|
1798
|
+
"Split"
|
|
1799
|
+
) : /* @__PURE__ */ import_react22.default.createElement(
|
|
1800
|
+
Button,
|
|
1801
|
+
{
|
|
1802
|
+
onClick: removeSplit,
|
|
1803
|
+
leftIcon: /* @__PURE__ */ import_react22.default.createElement(Link_default, { size: 14 }),
|
|
1804
|
+
variant: "secondary" /* secondary */
|
|
1805
|
+
},
|
|
1806
|
+
"Merge"
|
|
1807
|
+
))),
|
|
1808
|
+
/* @__PURE__ */ import_react22.default.createElement(
|
|
1809
|
+
InputGroup,
|
|
1810
|
+
{
|
|
1811
|
+
className: `${className}__description`,
|
|
1812
|
+
name: "description",
|
|
1813
|
+
label: "Description"
|
|
1814
|
+
},
|
|
1815
|
+
/* @__PURE__ */ import_react22.default.createElement(Textarea, { name: "description", placeholder: "Enter description" })
|
|
1816
|
+
),
|
|
1817
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: `${className}__file-upload` }, /* @__PURE__ */ import_react22.default.createElement(FileInput, { text: "Upload receipt" })),
|
|
1818
|
+
asListItem || showSubmitButton ? /* @__PURE__ */ import_react22.default.createElement("div", { className: `${className}__submit-btn` }, /* @__PURE__ */ import_react22.default.createElement(
|
|
1819
|
+
SubmitButton,
|
|
1820
|
+
{
|
|
1821
|
+
onClick: () => {
|
|
1822
|
+
if (!bankTransaction.processing) {
|
|
1823
|
+
save();
|
|
1824
|
+
}
|
|
1825
|
+
},
|
|
1826
|
+
className: "Layer__bank-transaction__submit-btn",
|
|
1827
|
+
processing: bankTransaction.processing,
|
|
1828
|
+
error: bankTransaction.error,
|
|
1829
|
+
active: true
|
|
1830
|
+
},
|
|
1831
|
+
"Approve"
|
|
1832
|
+
)) : null
|
|
1833
|
+
))
|
|
1834
|
+
);
|
|
1835
|
+
}
|
|
1836
|
+
);
|
|
1837
|
+
|
|
1838
|
+
// src/components/Pill/Pill.tsx
|
|
1839
|
+
var import_react23 = __toESM(require("react"));
|
|
1840
|
+
var Pill = ({ children }) => /* @__PURE__ */ import_react23.default.createElement("span", { className: "Layer__pill" }, children);
|
|
1841
|
+
|
|
1842
|
+
// src/components/BankTransactionListItem/BankTransactionListItem.tsx
|
|
1843
|
+
var import_classnames9 = __toESM(require("classnames"));
|
|
1844
|
+
var import_date_fns4 = require("date-fns");
|
|
1845
|
+
var isCredit = ({ direction }) => direction === "CREDIT" /* CREDIT */;
|
|
1846
|
+
var BankTransactionListItem = ({
|
|
1847
|
+
dateFormat: dateFormat2,
|
|
1848
|
+
bankTransaction,
|
|
1849
|
+
isOpen,
|
|
1850
|
+
toggleOpen,
|
|
1851
|
+
editable
|
|
1852
|
+
}) => {
|
|
1853
|
+
const expandedRowRef = (0, import_react24.useRef)(null);
|
|
1854
|
+
const [removed, setRemoved] = (0, import_react24.useState)(false);
|
|
1855
|
+
const { categorize: categorizeBankTransaction2 } = useBankTransactions();
|
|
1856
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react24.useState)(
|
|
1857
|
+
bankTransaction.categorization_flow?.type === "ASK_FROM_SUGGESTIONS" /* ASK_FROM_SUGGESTIONS */ ? bankTransaction.categorization_flow.suggestions[0] : void 0
|
|
1858
|
+
);
|
|
1859
|
+
const save = () => {
|
|
1860
|
+
if (isOpen && expandedRowRef?.current) {
|
|
1861
|
+
expandedRowRef?.current?.save();
|
|
1862
|
+
toggleOpen(bankTransaction.id);
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
categorizeBankTransaction2(bankTransaction.id, {
|
|
1866
|
+
type: "Category",
|
|
1867
|
+
category: {
|
|
1868
|
+
type: "StableName",
|
|
1869
|
+
stable_name: selectedCategory?.stable_name || selectedCategory?.category || ""
|
|
1870
|
+
}
|
|
1871
|
+
});
|
|
1872
|
+
};
|
|
1873
|
+
if (removed) {
|
|
1874
|
+
return null;
|
|
1875
|
+
}
|
|
1876
|
+
const className = "Layer__bank-transaction-list-item";
|
|
1877
|
+
const openClassName = isOpen ? `${className}--expanded` : "";
|
|
1878
|
+
const rowClassName = (0, import_classnames9.default)(
|
|
1879
|
+
className,
|
|
1880
|
+
bankTransaction.recently_categorized ? "Layer__bank-transaction-row--removing" : "",
|
|
1881
|
+
isOpen ? openClassName : ""
|
|
1882
|
+
);
|
|
1883
|
+
return /* @__PURE__ */ import_react24.default.createElement("li", { className: rowClassName }, /* @__PURE__ */ import_react24.default.createElement("span", { className: `${className}__heading` }, /* @__PURE__ */ import_react24.default.createElement("span", { className: `${className}__heading-date` }, (0, import_date_fns4.format)((0, import_date_fns4.parseISO)(bankTransaction.date), dateFormat2)), /* @__PURE__ */ import_react24.default.createElement("span", { className: `${className}__heading-separator` }), /* @__PURE__ */ import_react24.default.createElement("span", { className: `${className}__heading-account-name` }, bankTransaction.account_name ?? "")), /* @__PURE__ */ import_react24.default.createElement("span", { className: `${className}__body` }, /* @__PURE__ */ import_react24.default.createElement("span", { className: `${className}__body__name` }, bankTransaction.counterparty_name), /* @__PURE__ */ import_react24.default.createElement(
|
|
1884
|
+
"span",
|
|
1885
|
+
{
|
|
1886
|
+
className: `${className}__amount-${isCredit(bankTransaction) ? "credit" : "debit"}`
|
|
1887
|
+
},
|
|
1888
|
+
isCredit(bankTransaction) ? "+$" : " $",
|
|
1889
|
+
centsToDollars(bankTransaction.amount)
|
|
1890
|
+
), /* @__PURE__ */ import_react24.default.createElement(
|
|
1891
|
+
"div",
|
|
1892
|
+
{
|
|
1893
|
+
onClick: () => toggleOpen(bankTransaction.id),
|
|
1894
|
+
className: "Layer__bank-transaction-row__expand-button"
|
|
1895
|
+
},
|
|
1896
|
+
/* @__PURE__ */ import_react24.default.createElement(
|
|
1897
|
+
ChevronDown_default,
|
|
1898
|
+
{
|
|
1899
|
+
className: `Layer__chevron ${isOpen ? "Layer__chevron__up" : "Layer__chevron__down"}`
|
|
1900
|
+
}
|
|
1901
|
+
)
|
|
1902
|
+
)), /* @__PURE__ */ import_react24.default.createElement("span", { className: `${className}__expanded-row` }, /* @__PURE__ */ import_react24.default.createElement(
|
|
1903
|
+
ExpandedBankTransactionRow,
|
|
1904
|
+
{
|
|
1905
|
+
ref: expandedRowRef,
|
|
1906
|
+
bankTransaction,
|
|
1907
|
+
close: () => toggleOpen(bankTransaction.id),
|
|
1908
|
+
isOpen,
|
|
1909
|
+
asListItem: true
|
|
1910
|
+
}
|
|
1911
|
+
)), /* @__PURE__ */ import_react24.default.createElement("span", { className: `${className}__base-row` }, editable ? /* @__PURE__ */ import_react24.default.createElement(
|
|
1912
|
+
CategoryMenu,
|
|
1913
|
+
{
|
|
1914
|
+
bankTransaction,
|
|
1915
|
+
name: `category-${bankTransaction.id}`,
|
|
1916
|
+
value: selectedCategory,
|
|
1917
|
+
onChange: setSelectedCategory,
|
|
1918
|
+
disabled: bankTransaction.processing
|
|
1919
|
+
}
|
|
1920
|
+
) : null, !editable ? /* @__PURE__ */ import_react24.default.createElement(Pill, null, bankTransaction?.category?.display_name) : null, editable && /* @__PURE__ */ import_react24.default.createElement(
|
|
1921
|
+
SubmitButton,
|
|
1922
|
+
{
|
|
1923
|
+
onClick: () => {
|
|
1924
|
+
if (!bankTransaction.processing) {
|
|
1925
|
+
save();
|
|
914
1926
|
}
|
|
915
|
-
)
|
|
916
|
-
))),
|
|
917
|
-
/* @__PURE__ */ import_react9.default.createElement(
|
|
918
|
-
"div",
|
|
919
|
-
{
|
|
920
|
-
className: `${className}__table-cell ${className}__table-cell--description`
|
|
921
1927
|
},
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
));
|
|
1928
|
+
className: "Layer__bank-transaction__submit-btn",
|
|
1929
|
+
processing: bankTransaction.processing,
|
|
1930
|
+
error: bankTransaction.error,
|
|
1931
|
+
iconOnly: true
|
|
1932
|
+
}
|
|
1933
|
+
)));
|
|
928
1934
|
};
|
|
929
1935
|
|
|
930
|
-
// src/components/Pill/Pill.tsx
|
|
931
|
-
var import_react10 = __toESM(require("react"));
|
|
932
|
-
var Pill = ({ children }) => /* @__PURE__ */ import_react10.default.createElement("span", { className: "Layer__pill" }, children);
|
|
933
|
-
|
|
934
1936
|
// src/components/BankTransactionRow/BankTransactionRow.tsx
|
|
935
|
-
var
|
|
936
|
-
var
|
|
1937
|
+
var import_react25 = __toESM(require("react"));
|
|
1938
|
+
var import_classnames10 = __toESM(require("classnames"));
|
|
1939
|
+
var import_date_fns5 = require("date-fns");
|
|
1940
|
+
var isCredit2 = ({ direction }) => direction === "CREDIT" /* CREDIT */;
|
|
937
1941
|
var BankTransactionRow = ({
|
|
938
1942
|
dateFormat: dateFormat2,
|
|
939
1943
|
bankTransaction,
|
|
@@ -941,65 +1945,269 @@ var BankTransactionRow = ({
|
|
|
941
1945
|
toggleOpen,
|
|
942
1946
|
editable
|
|
943
1947
|
}) => {
|
|
1948
|
+
const expandedRowRef = (0, import_react25.useRef)(null);
|
|
1949
|
+
const [removed, setRemoved] = (0, import_react25.useState)(false);
|
|
944
1950
|
const { categorize: categorizeBankTransaction2 } = useBankTransactions();
|
|
945
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
946
|
-
bankTransaction.categorization_flow
|
|
1951
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react25.useState)(
|
|
1952
|
+
bankTransaction.categorization_flow?.type === "ASK_FROM_SUGGESTIONS" /* ASK_FROM_SUGGESTIONS */ ? bankTransaction.categorization_flow.suggestions[0] : void 0
|
|
947
1953
|
);
|
|
948
|
-
const
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
type: "StableName",
|
|
954
|
-
stable_name: selectedCategory?.stable_name || selectedCategory?.category || ""
|
|
1954
|
+
const save = () => {
|
|
1955
|
+
if (isOpen && expandedRowRef?.current) {
|
|
1956
|
+
expandedRowRef?.current?.save();
|
|
1957
|
+
toggleOpen(bankTransaction.id);
|
|
1958
|
+
return;
|
|
955
1959
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1960
|
+
categorizeBankTransaction2(bankTransaction.id, {
|
|
1961
|
+
type: "Category",
|
|
1962
|
+
category: {
|
|
1963
|
+
type: "StableName",
|
|
1964
|
+
stable_name: selectedCategory?.stable_name || selectedCategory?.category || ""
|
|
1965
|
+
}
|
|
1966
|
+
});
|
|
1967
|
+
};
|
|
1968
|
+
if (removed) {
|
|
1969
|
+
return null;
|
|
1970
|
+
}
|
|
1971
|
+
const className = "Layer__bank-transaction-row";
|
|
1972
|
+
const openClassName = isOpen ? `${className}--expanded` : "";
|
|
1973
|
+
const rowClassName = (0, import_classnames10.default)(
|
|
1974
|
+
className,
|
|
1975
|
+
bankTransaction.recently_categorized ? "Layer__bank-transaction-row--removing" : "",
|
|
1976
|
+
isOpen ? openClassName : ""
|
|
1977
|
+
);
|
|
1978
|
+
return /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement(
|
|
1979
|
+
"tr",
|
|
959
1980
|
{
|
|
960
|
-
className:
|
|
1981
|
+
className: rowClassName,
|
|
1982
|
+
onTransitionEnd: ({ propertyName }) => {
|
|
1983
|
+
if (propertyName === "top") {
|
|
1984
|
+
setRemoved(true);
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
961
1987
|
},
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1988
|
+
/* @__PURE__ */ import_react25.default.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ import_react25.default.createElement("span", { className: "Layer__table-cell-content" }, (0, import_date_fns5.format)((0, import_date_fns5.parseISO)(bankTransaction.date), dateFormat2))),
|
|
1989
|
+
/* @__PURE__ */ import_react25.default.createElement("td", { className: "Layer__table-cell Layer__bank-transactions__tx-col" }, /* @__PURE__ */ import_react25.default.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ import_react25.default.createElement(
|
|
1990
|
+
Text,
|
|
1991
|
+
{
|
|
1992
|
+
as: "span",
|
|
1993
|
+
className: "Layer__bank-transactions__tx-text",
|
|
1994
|
+
withTooltip: "whenTruncated" /* whenTruncated */,
|
|
1995
|
+
tooltipOptions: {
|
|
1996
|
+
contentClassName: "Layer__bank-transactions__tx-tooltip"
|
|
1997
|
+
}
|
|
1998
|
+
},
|
|
1999
|
+
bankTransaction.counterparty_name
|
|
2000
|
+
))),
|
|
2001
|
+
/* @__PURE__ */ import_react25.default.createElement("td", { className: "Layer__table-cell Layer__bank-transactions__account-col" }, /* @__PURE__ */ import_react25.default.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ import_react25.default.createElement(
|
|
2002
|
+
Text,
|
|
2003
|
+
{
|
|
2004
|
+
as: "span",
|
|
2005
|
+
className: "Layer__bank-transactions__account-text",
|
|
2006
|
+
withTooltip: "whenTruncated" /* whenTruncated */
|
|
2007
|
+
},
|
|
2008
|
+
bankTransaction.account_name ?? ""
|
|
2009
|
+
))),
|
|
2010
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
2011
|
+
"td",
|
|
2012
|
+
{
|
|
2013
|
+
className: `Layer__table-cell Layer__table-cell__amount-col Layer__table-cell--amount ${className}__table-cell--amount-${isCredit2(bankTransaction) ? "credit" : "debit"}`
|
|
2014
|
+
},
|
|
2015
|
+
/* @__PURE__ */ import_react25.default.createElement("span", { className: "Layer__table-cell-content" }, isCredit2(bankTransaction) ? "+$" : " $", centsToDollars(bankTransaction.amount))
|
|
2016
|
+
),
|
|
2017
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
2018
|
+
"td",
|
|
2019
|
+
{
|
|
2020
|
+
className: (0, import_classnames10.default)(
|
|
2021
|
+
"Layer__table-cell",
|
|
2022
|
+
"Layer__table-cell__category-col",
|
|
2023
|
+
`${className}__actions-cell`,
|
|
2024
|
+
`${className}__actions-cell--${isOpen ? "open" : "close"}`
|
|
2025
|
+
)
|
|
2026
|
+
},
|
|
2027
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
2028
|
+
"span",
|
|
2029
|
+
{
|
|
2030
|
+
className: `${className}__actions-container Layer__table-cell-content`
|
|
2031
|
+
},
|
|
2032
|
+
editable && !isOpen ? /* @__PURE__ */ import_react25.default.createElement(
|
|
2033
|
+
CategoryMenu,
|
|
2034
|
+
{
|
|
2035
|
+
bankTransaction,
|
|
2036
|
+
name: `category-${bankTransaction.id}`,
|
|
2037
|
+
value: selectedCategory,
|
|
2038
|
+
onChange: setSelectedCategory,
|
|
2039
|
+
disabled: bankTransaction.processing
|
|
2040
|
+
}
|
|
2041
|
+
) : null,
|
|
2042
|
+
!editable ? /* @__PURE__ */ import_react25.default.createElement(Text, { as: "span", className: `${className}__category-text` }, bankTransaction?.category?.display_name) : null,
|
|
2043
|
+
editable && /* @__PURE__ */ import_react25.default.createElement(
|
|
2044
|
+
SubmitButton,
|
|
2045
|
+
{
|
|
2046
|
+
onClick: () => {
|
|
2047
|
+
if (!bankTransaction.processing) {
|
|
2048
|
+
save();
|
|
2049
|
+
}
|
|
2050
|
+
},
|
|
2051
|
+
className: "Layer__bank-transaction__submit-btn",
|
|
2052
|
+
processing: bankTransaction.processing,
|
|
2053
|
+
error: bankTransaction.error,
|
|
2054
|
+
active: isOpen
|
|
2055
|
+
},
|
|
2056
|
+
"Approve"
|
|
2057
|
+
),
|
|
2058
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
2059
|
+
"div",
|
|
2060
|
+
{
|
|
2061
|
+
onClick: () => toggleOpen(bankTransaction.id),
|
|
2062
|
+
className: "Layer__bank-transaction-row__expand-button"
|
|
2063
|
+
},
|
|
2064
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
2065
|
+
ChevronDown_default,
|
|
2066
|
+
{
|
|
2067
|
+
className: `Layer__chevron ${isOpen ? "Layer__chevron__up" : "Layer__chevron__down"}`
|
|
2068
|
+
}
|
|
2069
|
+
)
|
|
2070
|
+
)
|
|
2071
|
+
)
|
|
2072
|
+
)
|
|
2073
|
+
), /* @__PURE__ */ import_react25.default.createElement("tr", null, /* @__PURE__ */ import_react25.default.createElement("td", { colSpan: 5 }, /* @__PURE__ */ import_react25.default.createElement(
|
|
2074
|
+
ExpandedBankTransactionRow,
|
|
965
2075
|
{
|
|
2076
|
+
ref: expandedRowRef,
|
|
966
2077
|
bankTransaction,
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
2078
|
+
close: () => toggleOpen(bankTransaction.id),
|
|
2079
|
+
isOpen,
|
|
2080
|
+
showSubmitButton: !editable
|
|
970
2081
|
}
|
|
971
|
-
)
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
2082
|
+
))));
|
|
2083
|
+
};
|
|
2084
|
+
|
|
2085
|
+
// src/components/Container/Container.tsx
|
|
2086
|
+
var import_react26 = __toESM(require("react"));
|
|
2087
|
+
|
|
2088
|
+
// src/utils/colors.ts
|
|
2089
|
+
var parseStylesFromThemeConfig = (theme) => {
|
|
2090
|
+
let styles = {};
|
|
2091
|
+
if (!theme) {
|
|
2092
|
+
return styles;
|
|
2093
|
+
}
|
|
2094
|
+
if (theme.colors) {
|
|
2095
|
+
const darkColor = parseColorFromTheme("dark", theme.colors.dark);
|
|
2096
|
+
const lightColor = parseColorFromTheme("light", theme.colors.light);
|
|
2097
|
+
styles = { ...styles, ...darkColor, ...lightColor };
|
|
2098
|
+
}
|
|
2099
|
+
return styles;
|
|
2100
|
+
};
|
|
2101
|
+
var parseColorFromTheme = (colorName, color) => {
|
|
2102
|
+
if (!color) {
|
|
2103
|
+
return {};
|
|
2104
|
+
}
|
|
2105
|
+
try {
|
|
2106
|
+
if ("h" in color && "s" in color && "l" in color) {
|
|
2107
|
+
console.log("its hsl", color);
|
|
2108
|
+
return {
|
|
2109
|
+
[`--color-${colorName}-h`]: color.h,
|
|
2110
|
+
[`--color-${colorName}-s`]: color.s,
|
|
2111
|
+
[`--color-${colorName}-l`]: color.l
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
if ("r" in color && "g" in color && "b" in color) {
|
|
2115
|
+
const { h, s, l } = rgbToHsl(color);
|
|
2116
|
+
console.log("its rgb", h, s, l);
|
|
2117
|
+
return {
|
|
2118
|
+
[`--color-${colorName}-h`]: h,
|
|
2119
|
+
[`--color-${colorName}-s`]: `${s}%`,
|
|
2120
|
+
[`--color-${colorName}-l`]: `${l}%`
|
|
2121
|
+
};
|
|
2122
|
+
}
|
|
2123
|
+
if ("hex" in color) {
|
|
2124
|
+
console.log("its hex");
|
|
2125
|
+
const rgb = hexToRgb(color.hex);
|
|
2126
|
+
if (!rgb) {
|
|
2127
|
+
return {};
|
|
983
2128
|
}
|
|
984
|
-
|
|
985
|
-
|
|
2129
|
+
const { h, s, l } = rgbToHsl({
|
|
2130
|
+
r: rgb.r.toString(),
|
|
2131
|
+
g: rgb.g.toString(),
|
|
2132
|
+
b: rgb.b.toString()
|
|
2133
|
+
});
|
|
2134
|
+
console.log("its hex", h, s, l);
|
|
2135
|
+
return {
|
|
2136
|
+
[`--color-${colorName}-h`]: h,
|
|
2137
|
+
[`--color-${colorName}-s`]: `${s}%`,
|
|
2138
|
+
[`--color-${colorName}-l`]: `${l}%`
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2141
|
+
return {};
|
|
2142
|
+
} catch (_err) {
|
|
2143
|
+
return {};
|
|
2144
|
+
}
|
|
2145
|
+
};
|
|
2146
|
+
var rgbToHsl = (color) => {
|
|
2147
|
+
let r = Number(color.r);
|
|
2148
|
+
let g = Number(color.g);
|
|
2149
|
+
let b = Number(color.b);
|
|
2150
|
+
r /= 255;
|
|
2151
|
+
g /= 255;
|
|
2152
|
+
b /= 255;
|
|
2153
|
+
const l = Math.max(r, g, b);
|
|
2154
|
+
const s = l - Math.min(r, g, b);
|
|
2155
|
+
const h = s ? l === r ? (g - b) / s : l === g ? 2 + (b - r) / s : 4 + (r - g) / s : 0;
|
|
2156
|
+
return {
|
|
2157
|
+
h: 60 * h < 0 ? 60 * h + 360 : 60 * h,
|
|
2158
|
+
s: 100 * (s ? l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s)) : 0),
|
|
2159
|
+
l: 100 * (2 * l - s) / 2
|
|
2160
|
+
};
|
|
2161
|
+
};
|
|
2162
|
+
var hexToRgb = (hex) => {
|
|
2163
|
+
const values = hex.replace(
|
|
2164
|
+
/^#?([a-f\d])([a-f\d])([a-f\d])$/i,
|
|
2165
|
+
(m, r, g, b) => "#" + r + r + g + g + b + b
|
|
2166
|
+
).substring(1).match(/.{2}/g)?.map((x) => parseInt(x, 16));
|
|
2167
|
+
if (!values) {
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2170
|
+
return {
|
|
2171
|
+
r: values[0],
|
|
2172
|
+
g: values[1],
|
|
2173
|
+
b: values[2]
|
|
2174
|
+
};
|
|
2175
|
+
};
|
|
2176
|
+
|
|
2177
|
+
// src/components/Container/Container.tsx
|
|
2178
|
+
var Container = ({ name, className, children }) => {
|
|
2179
|
+
const baseClassName = `Layer__${name} ${className ?? ""}`;
|
|
2180
|
+
const { theme } = useLayerContext();
|
|
2181
|
+
const styles = parseStylesFromThemeConfig(theme);
|
|
2182
|
+
return /* @__PURE__ */ import_react26.default.createElement(
|
|
986
2183
|
"div",
|
|
987
2184
|
{
|
|
988
|
-
|
|
989
|
-
|
|
2185
|
+
className: `Layer__component Layer__component-container ${baseClassName}`,
|
|
2186
|
+
style: { ...styles }
|
|
990
2187
|
},
|
|
991
|
-
|
|
992
|
-
)
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
2188
|
+
children
|
|
2189
|
+
);
|
|
2190
|
+
};
|
|
2191
|
+
|
|
2192
|
+
// src/components/Container/Header.tsx
|
|
2193
|
+
var import_react27 = __toESM(require("react"));
|
|
2194
|
+
var import_classnames11 = __toESM(require("classnames"));
|
|
2195
|
+
var Header = (0, import_react27.forwardRef)(
|
|
2196
|
+
({ className, children, style }, ref) => {
|
|
2197
|
+
const baseClassName = (0, import_classnames11.default)("Layer__component-header", className);
|
|
2198
|
+
return /* @__PURE__ */ import_react27.default.createElement("header", { ref, className: baseClassName, style }, children);
|
|
2199
|
+
}
|
|
2200
|
+
);
|
|
2201
|
+
|
|
2202
|
+
// src/components/Loader/Loader.tsx
|
|
2203
|
+
var import_react28 = __toESM(require("react"));
|
|
2204
|
+
var Loader2 = ({ children }) => {
|
|
2205
|
+
return /* @__PURE__ */ import_react28.default.createElement("span", { className: "Layer__loader" }, /* @__PURE__ */ import_react28.default.createElement(Loader_default, { size: 14, className: "Layer__anim--rotating" }), children ?? "Loading...");
|
|
999
2206
|
};
|
|
1000
2207
|
|
|
1001
2208
|
// src/components/BankTransactions/BankTransactions.tsx
|
|
1002
|
-
var
|
|
2209
|
+
var COMPONENT_NAME = "bank-transactions";
|
|
2210
|
+
var dateFormat = "LLL d, yyyy";
|
|
1003
2211
|
var CategorizedCategories = [
|
|
1004
2212
|
"CATEGORIZED" /* CATEGORIZED */,
|
|
1005
2213
|
"JOURNALING" /* JOURNALING */,
|
|
@@ -1013,46 +2221,83 @@ var filterVisibility = (display) => (bankTransaction) => {
|
|
|
1013
2221
|
const categorized = CategorizedCategories.includes(
|
|
1014
2222
|
bankTransaction.categorization_status
|
|
1015
2223
|
);
|
|
1016
|
-
const inReview = ReviewCategories.includes(
|
|
1017
|
-
bankTransaction.categorization_status
|
|
1018
|
-
);
|
|
2224
|
+
const inReview = ReviewCategories.includes(bankTransaction.categorization_status) || bankTransaction.recently_categorized;
|
|
1019
2225
|
return display === "review" /* review */ && inReview || display === "categorized" /* categorized */ && categorized;
|
|
1020
2226
|
};
|
|
1021
2227
|
var BankTransactions = () => {
|
|
1022
|
-
const [display, setDisplay] = (0,
|
|
1023
|
-
const { data } = useBankTransactions();
|
|
2228
|
+
const [display, setDisplay] = (0, import_react29.useState)("review" /* review */);
|
|
2229
|
+
const { data, isLoading } = useBankTransactions();
|
|
1024
2230
|
const bankTransactions = data.filter(filterVisibility(display));
|
|
1025
2231
|
const onCategorizationDisplayChange = (event) => setDisplay(
|
|
1026
2232
|
event.target.value === "categorized" /* categorized */ ? "categorized" /* categorized */ : "review" /* review */
|
|
1027
2233
|
);
|
|
1028
|
-
const [openRows, setOpenRows] = (0,
|
|
2234
|
+
const [openRows, setOpenRows] = (0, import_react29.useState)({});
|
|
1029
2235
|
const toggleOpen = (id) => setOpenRows({ ...openRows, [id]: !openRows[id] });
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
{
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
onChange: onCategorizationDisplayChange
|
|
2236
|
+
const [shiftStickyHeader, setShiftStickyHeader] = (0, import_react29.useState)(0);
|
|
2237
|
+
const headerRef = useElementSize((_el, _en, size) => {
|
|
2238
|
+
if (size?.height && size?.height >= 90) {
|
|
2239
|
+
const newShift = -Math.floor(size.height / 2) + 6;
|
|
2240
|
+
if (newShift !== shiftStickyHeader) {
|
|
2241
|
+
setShiftStickyHeader(newShift);
|
|
2242
|
+
}
|
|
2243
|
+
} else if (size?.height > 0 && shiftStickyHeader !== 0) {
|
|
2244
|
+
setShiftStickyHeader(0);
|
|
1040
2245
|
}
|
|
1041
|
-
|
|
1042
|
-
|
|
2246
|
+
});
|
|
2247
|
+
const editable = display === "review" /* review */;
|
|
2248
|
+
return /* @__PURE__ */ import_react29.default.createElement(Container, { name: COMPONENT_NAME }, /* @__PURE__ */ import_react29.default.createElement(
|
|
2249
|
+
Header,
|
|
2250
|
+
{
|
|
2251
|
+
ref: headerRef,
|
|
2252
|
+
className: "Layer__bank-transactions__header",
|
|
2253
|
+
style: { top: shiftStickyHeader }
|
|
2254
|
+
},
|
|
2255
|
+
/* @__PURE__ */ import_react29.default.createElement(Heading, { className: "Layer__bank-transactions__title" }, "Transactions"),
|
|
2256
|
+
/* @__PURE__ */ import_react29.default.createElement(
|
|
2257
|
+
Toggle,
|
|
2258
|
+
{
|
|
2259
|
+
name: "bank-transaction-display",
|
|
2260
|
+
options: [
|
|
2261
|
+
{ label: "To Review", value: "review" /* review */ },
|
|
2262
|
+
{ label: "Categorized", value: "categorized" /* categorized */ }
|
|
2263
|
+
],
|
|
2264
|
+
selected: display,
|
|
2265
|
+
onChange: onCategorizationDisplayChange
|
|
2266
|
+
}
|
|
2267
|
+
)
|
|
2268
|
+
), /* @__PURE__ */ import_react29.default.createElement(
|
|
2269
|
+
"table",
|
|
2270
|
+
{
|
|
2271
|
+
width: "100%",
|
|
2272
|
+
className: "Layer__table Layer__bank-transactions__table"
|
|
2273
|
+
},
|
|
2274
|
+
/* @__PURE__ */ import_react29.default.createElement("thead", null, /* @__PURE__ */ import_react29.default.createElement("tr", null, /* @__PURE__ */ import_react29.default.createElement("th", { className: "Layer__table-header Layer__bank-transactions__date-col" }, "Date"), /* @__PURE__ */ import_react29.default.createElement("th", { className: "Layer__table-header Layer__bank-transactions__tx-col" }, "Transaction"), /* @__PURE__ */ import_react29.default.createElement("th", { className: "Layer__table-header Layer__bank-transactions__account-col" }, "Account"), /* @__PURE__ */ import_react29.default.createElement("th", { className: "Layer__table-header Layer__table-cell--amount Layer__table-cell__amount-col" }, "Amount"), editable ? /* @__PURE__ */ import_react29.default.createElement("th", { className: "Layer__table-header Layer__table-header--primary Layer__table-cell__category-col" }, "Categorize") : /* @__PURE__ */ import_react29.default.createElement("th", { className: "Layer__table-header Layer__table-cell__category-col" }, "Category"))),
|
|
2275
|
+
/* @__PURE__ */ import_react29.default.createElement("tbody", null, !isLoading && bankTransactions.map((bankTransaction) => /* @__PURE__ */ import_react29.default.createElement(
|
|
2276
|
+
BankTransactionRow,
|
|
2277
|
+
{
|
|
2278
|
+
key: bankTransaction.id,
|
|
2279
|
+
dateFormat,
|
|
2280
|
+
bankTransaction,
|
|
2281
|
+
isOpen: openRows[bankTransaction.id],
|
|
2282
|
+
toggleOpen,
|
|
2283
|
+
editable
|
|
2284
|
+
}
|
|
2285
|
+
)))
|
|
2286
|
+
), isLoading || !bankTransactions || bankTransactions?.length === 0 ? /* @__PURE__ */ import_react29.default.createElement(Loader2, null) : null, !isLoading && /* @__PURE__ */ import_react29.default.createElement("ul", { className: "Layer__bank-transactions__list" }, bankTransactions.map((bankTransaction) => /* @__PURE__ */ import_react29.default.createElement(
|
|
2287
|
+
BankTransactionListItem,
|
|
1043
2288
|
{
|
|
1044
2289
|
key: bankTransaction.id,
|
|
1045
2290
|
dateFormat,
|
|
1046
2291
|
bankTransaction,
|
|
1047
2292
|
isOpen: openRows[bankTransaction.id],
|
|
1048
2293
|
toggleOpen,
|
|
1049
|
-
editable
|
|
2294
|
+
editable
|
|
1050
2295
|
}
|
|
1051
2296
|
))));
|
|
1052
2297
|
};
|
|
1053
2298
|
|
|
1054
2299
|
// src/components/Hello/Hello.tsx
|
|
1055
|
-
var
|
|
2300
|
+
var import_react30 = __toESM(require("react"));
|
|
1056
2301
|
var import_swr3 = __toESM(require("swr"));
|
|
1057
2302
|
var fetcher = (url) => fetch(url).then((res) => res.json());
|
|
1058
2303
|
var Hello = ({ user }) => {
|
|
@@ -1061,26 +2306,26 @@ var Hello = ({ user }) => {
|
|
|
1061
2306
|
fetcher
|
|
1062
2307
|
);
|
|
1063
2308
|
const name = (isLoading ? "..." : data?.name) || "User";
|
|
1064
|
-
return /* @__PURE__ */
|
|
2309
|
+
return /* @__PURE__ */ import_react30.default.createElement(import_react30.default.Fragment, null, /* @__PURE__ */ import_react30.default.createElement("div", { className: "hello" }, "Hello, ", name, "!"));
|
|
1065
2310
|
};
|
|
1066
2311
|
|
|
1067
2312
|
// src/components/ProfitAndLoss/ProfitAndLoss.tsx
|
|
1068
|
-
var
|
|
2313
|
+
var import_react38 = __toESM(require("react"));
|
|
1069
2314
|
|
|
1070
2315
|
// src/hooks/useProfitAndLoss/useProfitAndLoss.tsx
|
|
1071
|
-
var
|
|
1072
|
-
var
|
|
2316
|
+
var import_react31 = require("react");
|
|
2317
|
+
var import_date_fns6 = require("date-fns");
|
|
1073
2318
|
var import_swr4 = __toESM(require("swr"));
|
|
1074
2319
|
var useProfitAndLoss = ({ startDate: initialStartDate, endDate: initialEndDate } = {
|
|
1075
|
-
startDate: (0,
|
|
1076
|
-
endDate: (0,
|
|
2320
|
+
startDate: (0, import_date_fns6.startOfMonth)(/* @__PURE__ */ new Date()),
|
|
2321
|
+
endDate: (0, import_date_fns6.endOfMonth)(/* @__PURE__ */ new Date())
|
|
1077
2322
|
}) => {
|
|
1078
|
-
const { auth, businessId } = useLayerContext();
|
|
1079
|
-
const [startDate, setStartDate] = (0,
|
|
1080
|
-
initialStartDate || (0,
|
|
2323
|
+
const { auth, businessId, apiUrl } = useLayerContext();
|
|
2324
|
+
const [startDate, setStartDate] = (0, import_react31.useState)(
|
|
2325
|
+
initialStartDate || (0, import_date_fns6.startOfMonth)(Date.now())
|
|
1081
2326
|
);
|
|
1082
|
-
const [endDate, setEndDate] = (0,
|
|
1083
|
-
initialEndDate || (0,
|
|
2327
|
+
const [endDate, setEndDate] = (0, import_react31.useState)(
|
|
2328
|
+
initialEndDate || (0, import_date_fns6.endOfMonth)(Date.now())
|
|
1084
2329
|
);
|
|
1085
2330
|
const {
|
|
1086
2331
|
data: rawData,
|
|
@@ -1088,11 +2333,11 @@ var useProfitAndLoss = ({ startDate: initialStartDate, endDate: initialEndDate }
|
|
|
1088
2333
|
error: rawError
|
|
1089
2334
|
} = (0, import_swr4.default)(
|
|
1090
2335
|
businessId && startDate && endDate && auth?.access_token && `profit-and-loss-${businessId}-${startDate.valueOf()}-${endDate.valueOf()}`,
|
|
1091
|
-
Layer.getProfitAndLoss(auth?.access_token, {
|
|
2336
|
+
Layer.getProfitAndLoss(apiUrl, auth?.access_token, {
|
|
1092
2337
|
params: {
|
|
1093
2338
|
businessId,
|
|
1094
|
-
startDate: (0,
|
|
1095
|
-
endDate: (0,
|
|
2339
|
+
startDate: (0, import_date_fns6.formatISO)(startDate),
|
|
2340
|
+
endDate: (0, import_date_fns6.formatISO)(endDate)
|
|
1096
2341
|
}
|
|
1097
2342
|
})
|
|
1098
2343
|
);
|
|
@@ -1114,10 +2359,10 @@ var useProfitAndLoss = ({ startDate: initialStartDate, endDate: initialEndDate }
|
|
|
1114
2359
|
};
|
|
1115
2360
|
|
|
1116
2361
|
// src/components/ProfitAndLossChart/ProfitAndLossChart.tsx
|
|
1117
|
-
var
|
|
2362
|
+
var import_react33 = __toESM(require("react"));
|
|
1118
2363
|
|
|
1119
2364
|
// src/components/ProfitAndLossChart/Indicator.tsx
|
|
1120
|
-
var
|
|
2365
|
+
var import_react32 = __toESM(require("react"));
|
|
1121
2366
|
var emptyViewBox = { x: 0, y: 0, width: 0, height: 0 };
|
|
1122
2367
|
var Indicator = ({
|
|
1123
2368
|
viewBox = {},
|
|
@@ -1137,16 +2382,17 @@ var Indicator = ({
|
|
|
1137
2382
|
const boxWidth = width * 2 + 4;
|
|
1138
2383
|
const multiplier = 1.5;
|
|
1139
2384
|
const xOffset = (boxWidth * multiplier - boxWidth) / 2;
|
|
1140
|
-
(0,
|
|
2385
|
+
(0, import_react32.useEffect)(() => {
|
|
1141
2386
|
setAnimateFrom(animateTo);
|
|
1142
2387
|
}, [animateTo]);
|
|
1143
2388
|
const actualX = animateFrom === -1 ? animateTo : animateFrom;
|
|
1144
|
-
return /* @__PURE__ */
|
|
2389
|
+
return /* @__PURE__ */ import_react32.default.createElement(
|
|
1145
2390
|
"rect",
|
|
1146
2391
|
{
|
|
1147
2392
|
className: "Layer__profit-and-loss-chart__selection-indicator",
|
|
1148
2393
|
style: {
|
|
1149
2394
|
width: `${boxWidth * multiplier}px`,
|
|
2395
|
+
// @ts-expect-error -- y is fine but x apparently isn't!
|
|
1150
2396
|
x: actualX - xOffset,
|
|
1151
2397
|
y: y + height
|
|
1152
2398
|
}
|
|
@@ -1155,106 +2401,106 @@ var Indicator = ({
|
|
|
1155
2401
|
};
|
|
1156
2402
|
|
|
1157
2403
|
// src/components/ProfitAndLossChart/ProfitAndLossChart.tsx
|
|
1158
|
-
var
|
|
2404
|
+
var import_date_fns7 = require("date-fns");
|
|
1159
2405
|
var import_recharts = require("recharts");
|
|
1160
2406
|
var barGap = 4;
|
|
1161
2407
|
var barSize = 20;
|
|
1162
2408
|
var ProfitAndLossChart = () => {
|
|
1163
|
-
const { changeDateRange, dateRange } = (0,
|
|
1164
|
-
const thisMonth = (0,
|
|
2409
|
+
const { changeDateRange, dateRange } = (0, import_react33.useContext)(ProfitAndLoss.Context);
|
|
2410
|
+
const thisMonth = (0, import_date_fns7.startOfMonth)(Date.now());
|
|
1165
2411
|
const startSelectionMonth = dateRange.startDate.getMonth();
|
|
1166
2412
|
const endSelectionMonth = dateRange.endDate.getMonth();
|
|
1167
2413
|
const monthData = [];
|
|
1168
2414
|
monthData.push(
|
|
1169
2415
|
useProfitAndLoss({
|
|
1170
|
-
startDate: (0,
|
|
1171
|
-
endDate: (0,
|
|
2416
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 11 })),
|
|
2417
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 11 }))
|
|
1172
2418
|
})?.data
|
|
1173
2419
|
);
|
|
1174
2420
|
monthData.push(
|
|
1175
2421
|
useProfitAndLoss({
|
|
1176
|
-
startDate: (0,
|
|
1177
|
-
endDate: (0,
|
|
2422
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 10 })),
|
|
2423
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 10 }))
|
|
1178
2424
|
})?.data
|
|
1179
2425
|
);
|
|
1180
2426
|
monthData.push(
|
|
1181
2427
|
useProfitAndLoss({
|
|
1182
|
-
startDate: (0,
|
|
1183
|
-
endDate: (0,
|
|
2428
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 9 })),
|
|
2429
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 9 }))
|
|
1184
2430
|
})?.data
|
|
1185
2431
|
);
|
|
1186
2432
|
monthData.push(
|
|
1187
2433
|
useProfitAndLoss({
|
|
1188
|
-
startDate: (0,
|
|
1189
|
-
endDate: (0,
|
|
2434
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 8 })),
|
|
2435
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 8 }))
|
|
1190
2436
|
})?.data
|
|
1191
2437
|
);
|
|
1192
2438
|
monthData.push(
|
|
1193
2439
|
useProfitAndLoss({
|
|
1194
|
-
startDate: (0,
|
|
1195
|
-
endDate: (0,
|
|
2440
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 7 })),
|
|
2441
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 7 }))
|
|
1196
2442
|
})?.data
|
|
1197
2443
|
);
|
|
1198
2444
|
monthData.push(
|
|
1199
2445
|
useProfitAndLoss({
|
|
1200
|
-
startDate: (0,
|
|
1201
|
-
endDate: (0,
|
|
2446
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 6 })),
|
|
2447
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 6 }))
|
|
1202
2448
|
})?.data
|
|
1203
2449
|
);
|
|
1204
2450
|
monthData.push(
|
|
1205
2451
|
useProfitAndLoss({
|
|
1206
|
-
startDate: (0,
|
|
1207
|
-
endDate: (0,
|
|
2452
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 5 })),
|
|
2453
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 5 }))
|
|
1208
2454
|
})?.data
|
|
1209
2455
|
);
|
|
1210
2456
|
monthData.push(
|
|
1211
2457
|
useProfitAndLoss({
|
|
1212
|
-
startDate: (0,
|
|
1213
|
-
endDate: (0,
|
|
2458
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 4 })),
|
|
2459
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 4 }))
|
|
1214
2460
|
})?.data
|
|
1215
2461
|
);
|
|
1216
2462
|
monthData.push(
|
|
1217
2463
|
useProfitAndLoss({
|
|
1218
|
-
startDate: (0,
|
|
1219
|
-
endDate: (0,
|
|
2464
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 3 })),
|
|
2465
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 3 }))
|
|
1220
2466
|
})?.data
|
|
1221
2467
|
);
|
|
1222
2468
|
monthData.push(
|
|
1223
2469
|
useProfitAndLoss({
|
|
1224
|
-
startDate: (0,
|
|
1225
|
-
endDate: (0,
|
|
2470
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 2 })),
|
|
2471
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 2 }))
|
|
1226
2472
|
})?.data
|
|
1227
2473
|
);
|
|
1228
2474
|
monthData.push(
|
|
1229
2475
|
useProfitAndLoss({
|
|
1230
|
-
startDate: (0,
|
|
1231
|
-
endDate: (0,
|
|
2476
|
+
startDate: (0, import_date_fns7.startOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 1 })),
|
|
2477
|
+
endDate: (0, import_date_fns7.endOfMonth)((0, import_date_fns7.sub)(thisMonth, { months: 1 }))
|
|
1232
2478
|
})?.data
|
|
1233
2479
|
);
|
|
1234
2480
|
monthData.push(
|
|
1235
2481
|
useProfitAndLoss({
|
|
1236
2482
|
startDate: thisMonth,
|
|
1237
|
-
endDate: (0,
|
|
2483
|
+
endDate: (0, import_date_fns7.endOfMonth)(thisMonth)
|
|
1238
2484
|
})?.data
|
|
1239
2485
|
);
|
|
1240
|
-
const getMonthName = (pnl) =>
|
|
2486
|
+
const getMonthName = (pnl) => pnl ? (0, import_date_fns7.format)((0, import_date_fns7.parseISO)(pnl.start_date), "LLL") : "";
|
|
1241
2487
|
const summarizePnL = (pnl) => ({
|
|
1242
2488
|
name: getMonthName(pnl),
|
|
1243
2489
|
revenue: pnl?.income.value || 0,
|
|
1244
2490
|
expenses: (pnl?.income.value || 0) - (pnl?.net_profit || 0),
|
|
1245
|
-
selected: !!pnl && (0,
|
|
2491
|
+
selected: !!pnl && (0, import_date_fns7.parseISO)(pnl.start_date).getMonth() >= startSelectionMonth && (0, import_date_fns7.parseISO)(pnl.end_date).getMonth() <= endSelectionMonth
|
|
1246
2492
|
});
|
|
1247
2493
|
const onClick = ({ activeTooltipIndex }) => {
|
|
1248
2494
|
const selection = monthData[activeTooltipIndex || -1];
|
|
1249
2495
|
if (selection) {
|
|
1250
2496
|
const { start_date: startDate, end_date: endDate } = selection;
|
|
1251
2497
|
changeDateRange({
|
|
1252
|
-
startDate: (0,
|
|
1253
|
-
endDate: (0,
|
|
2498
|
+
startDate: (0, import_date_fns7.parseISO)(startDate),
|
|
2499
|
+
endDate: (0, import_date_fns7.parseISO)(endDate)
|
|
1254
2500
|
});
|
|
1255
2501
|
}
|
|
1256
2502
|
};
|
|
1257
|
-
const data = (0,
|
|
2503
|
+
const data = (0, import_react33.useMemo)(
|
|
1258
2504
|
() => monthData.map(summarizePnL),
|
|
1259
2505
|
[
|
|
1260
2506
|
startSelectionMonth,
|
|
@@ -1262,8 +2508,8 @@ var ProfitAndLossChart = () => {
|
|
|
1262
2508
|
...monthData.map((m) => m?.net_profit)
|
|
1263
2509
|
]
|
|
1264
2510
|
);
|
|
1265
|
-
const [animateFrom, setAnimateFrom] = (0,
|
|
1266
|
-
return /* @__PURE__ */
|
|
2511
|
+
const [animateFrom, setAnimateFrom] = (0, import_react33.useState)(-1);
|
|
2512
|
+
return /* @__PURE__ */ import_react33.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: 250 }, /* @__PURE__ */ import_react33.default.createElement(
|
|
1267
2513
|
import_recharts.BarChart,
|
|
1268
2514
|
{
|
|
1269
2515
|
margin: { left: 24, right: 24, bottom: 24 },
|
|
@@ -1272,8 +2518,8 @@ var ProfitAndLossChart = () => {
|
|
|
1272
2518
|
barGap,
|
|
1273
2519
|
className: "Layer__profit-and-loss-chart"
|
|
1274
2520
|
},
|
|
1275
|
-
/* @__PURE__ */
|
|
1276
|
-
/* @__PURE__ */
|
|
2521
|
+
/* @__PURE__ */ import_react33.default.createElement(import_recharts.CartesianGrid, { vertical: false }),
|
|
2522
|
+
/* @__PURE__ */ import_react33.default.createElement(
|
|
1277
2523
|
import_recharts.Legend,
|
|
1278
2524
|
{
|
|
1279
2525
|
verticalAlign: "top",
|
|
@@ -1284,8 +2530,8 @@ var ProfitAndLossChart = () => {
|
|
|
1284
2530
|
]
|
|
1285
2531
|
}
|
|
1286
2532
|
),
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
/* @__PURE__ */
|
|
2533
|
+
/* @__PURE__ */ import_react33.default.createElement(import_recharts.XAxis, { dataKey: "name", tickLine: false }),
|
|
2534
|
+
/* @__PURE__ */ import_react33.default.createElement(
|
|
1289
2535
|
import_recharts.Bar,
|
|
1290
2536
|
{
|
|
1291
2537
|
dataKey: "revenue",
|
|
@@ -1294,10 +2540,10 @@ var ProfitAndLossChart = () => {
|
|
|
1294
2540
|
radius: [barSize / 4, barSize / 4, 0, 0],
|
|
1295
2541
|
className: "Layer__profit-and-loss-chart__bar--income"
|
|
1296
2542
|
},
|
|
1297
|
-
/* @__PURE__ */
|
|
2543
|
+
/* @__PURE__ */ import_react33.default.createElement(
|
|
1298
2544
|
import_recharts.LabelList,
|
|
1299
2545
|
{
|
|
1300
|
-
content: /* @__PURE__ */
|
|
2546
|
+
content: /* @__PURE__ */ import_react33.default.createElement(
|
|
1301
2547
|
Indicator,
|
|
1302
2548
|
{
|
|
1303
2549
|
animateFrom,
|
|
@@ -1306,7 +2552,7 @@ var ProfitAndLossChart = () => {
|
|
|
1306
2552
|
)
|
|
1307
2553
|
}
|
|
1308
2554
|
),
|
|
1309
|
-
data.map((entry) => /* @__PURE__ */
|
|
2555
|
+
data.map((entry) => /* @__PURE__ */ import_react33.default.createElement(
|
|
1310
2556
|
import_recharts.Cell,
|
|
1311
2557
|
{
|
|
1312
2558
|
key: entry.name,
|
|
@@ -1314,7 +2560,7 @@ var ProfitAndLossChart = () => {
|
|
|
1314
2560
|
}
|
|
1315
2561
|
))
|
|
1316
2562
|
),
|
|
1317
|
-
/* @__PURE__ */
|
|
2563
|
+
/* @__PURE__ */ import_react33.default.createElement(
|
|
1318
2564
|
import_recharts.Bar,
|
|
1319
2565
|
{
|
|
1320
2566
|
dataKey: "expenses",
|
|
@@ -1323,7 +2569,7 @@ var ProfitAndLossChart = () => {
|
|
|
1323
2569
|
radius: [barSize / 4, barSize / 4, 0, 0],
|
|
1324
2570
|
className: "Layer__profit-and-loss-chart__bar--expenses"
|
|
1325
2571
|
},
|
|
1326
|
-
data.map((entry) => /* @__PURE__ */
|
|
2572
|
+
data.map((entry) => /* @__PURE__ */ import_react33.default.createElement(
|
|
1327
2573
|
import_recharts.Cell,
|
|
1328
2574
|
{
|
|
1329
2575
|
key: entry.name,
|
|
@@ -1335,15 +2581,15 @@ var ProfitAndLossChart = () => {
|
|
|
1335
2581
|
};
|
|
1336
2582
|
|
|
1337
2583
|
// src/components/ProfitAndLossDatePicker/ProfitAndLossDatePicker.tsx
|
|
1338
|
-
var
|
|
2584
|
+
var import_react34 = __toESM(require("react"));
|
|
1339
2585
|
|
|
1340
2586
|
// src/icons/ChevronLeft.tsx
|
|
1341
|
-
var
|
|
2587
|
+
var React40 = __toESM(require("react"));
|
|
1342
2588
|
var ChevronLeft = ({
|
|
1343
2589
|
strokeColor,
|
|
1344
2590
|
size,
|
|
1345
2591
|
...props
|
|
1346
|
-
}) => /* @__PURE__ */
|
|
2592
|
+
}) => /* @__PURE__ */ React40.createElement(
|
|
1347
2593
|
"svg",
|
|
1348
2594
|
{
|
|
1349
2595
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -1353,7 +2599,7 @@ var ChevronLeft = ({
|
|
|
1353
2599
|
viewBox: "0 0 24 24",
|
|
1354
2600
|
...props
|
|
1355
2601
|
},
|
|
1356
|
-
/* @__PURE__ */
|
|
2602
|
+
/* @__PURE__ */ React40.createElement(
|
|
1357
2603
|
"path",
|
|
1358
2604
|
{
|
|
1359
2605
|
stroke: strokeColor ?? "#000",
|
|
@@ -1366,43 +2612,68 @@ var ChevronLeft = ({
|
|
|
1366
2612
|
);
|
|
1367
2613
|
var ChevronLeft_default = ChevronLeft;
|
|
1368
2614
|
|
|
2615
|
+
// src/icons/ChevronRight.tsx
|
|
2616
|
+
var React41 = __toESM(require("react"));
|
|
2617
|
+
var ChavronRight = ({ size, ...props }) => /* @__PURE__ */ React41.createElement(
|
|
2618
|
+
"svg",
|
|
2619
|
+
{
|
|
2620
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2621
|
+
width: size || 24,
|
|
2622
|
+
height: size || 24,
|
|
2623
|
+
fill: "none",
|
|
2624
|
+
viewBox: "0 0 24 24",
|
|
2625
|
+
...props
|
|
2626
|
+
},
|
|
2627
|
+
/* @__PURE__ */ React41.createElement(
|
|
2628
|
+
"path",
|
|
2629
|
+
{
|
|
2630
|
+
stroke: "#000",
|
|
2631
|
+
strokeLinecap: "round",
|
|
2632
|
+
strokeLinejoin: "round",
|
|
2633
|
+
strokeWidth: 2,
|
|
2634
|
+
d: "m9 18 6-6-6-6"
|
|
2635
|
+
}
|
|
2636
|
+
)
|
|
2637
|
+
);
|
|
2638
|
+
var ChevronRight_default = ChavronRight;
|
|
2639
|
+
|
|
1369
2640
|
// src/components/ProfitAndLossDatePicker/ProfitAndLossDatePicker.tsx
|
|
1370
|
-
var
|
|
2641
|
+
var import_date_fns8 = require("date-fns");
|
|
1371
2642
|
var ProfitAndLossDatePicker = () => {
|
|
1372
|
-
const { changeDateRange, dateRange } = (0,
|
|
2643
|
+
const { changeDateRange, dateRange } = (0, import_react34.useContext)(ProfitAndLoss.Context);
|
|
1373
2644
|
const date = dateRange.startDate;
|
|
1374
|
-
const label = (0,
|
|
2645
|
+
const label = (0, import_date_fns8.format)(date, "LLLL y");
|
|
1375
2646
|
const change = (duration) => {
|
|
1376
|
-
const newDate = (0,
|
|
2647
|
+
const newDate = (0, import_date_fns8.add)(date, duration);
|
|
1377
2648
|
changeDateRange({
|
|
1378
|
-
startDate: (0,
|
|
1379
|
-
endDate: (0,
|
|
2649
|
+
startDate: (0, import_date_fns8.startOfMonth)(newDate),
|
|
2650
|
+
endDate: (0, import_date_fns8.endOfMonth)(newDate)
|
|
1380
2651
|
});
|
|
1381
2652
|
};
|
|
1382
2653
|
const previousMonth = () => change({ months: -1 });
|
|
1383
2654
|
const nextMonth = () => change({ months: 1 });
|
|
1384
|
-
return /* @__PURE__ */
|
|
2655
|
+
return /* @__PURE__ */ import_react34.default.createElement("div", { className: "Layer__profit-and-loss-date-picker" }, /* @__PURE__ */ import_react34.default.createElement(
|
|
1385
2656
|
"button",
|
|
1386
2657
|
{
|
|
1387
2658
|
"aria-label": "View Previous Month",
|
|
1388
2659
|
className: "Layer__profit-and-loss-date-picker__button",
|
|
1389
2660
|
onClick: previousMonth
|
|
1390
2661
|
},
|
|
1391
|
-
/* @__PURE__ */
|
|
2662
|
+
/* @__PURE__ */ import_react34.default.createElement(
|
|
1392
2663
|
ChevronLeft_default,
|
|
1393
2664
|
{
|
|
1394
2665
|
className: "Layer__profit-and-loss-date-picker__button-icon",
|
|
1395
2666
|
size: 18
|
|
1396
2667
|
}
|
|
1397
2668
|
)
|
|
1398
|
-
), /* @__PURE__ */
|
|
2669
|
+
), /* @__PURE__ */ import_react34.default.createElement("span", { className: "Layer__profit-and-loss-date-picker__label" }, label), /* @__PURE__ */ import_react34.default.createElement(
|
|
1399
2670
|
"button",
|
|
1400
2671
|
{
|
|
1401
2672
|
"aria-label": "View Next Month",
|
|
1402
2673
|
className: "Layer__profit-and-loss-date-picker__button",
|
|
1403
2674
|
onClick: nextMonth
|
|
1404
2675
|
},
|
|
1405
|
-
/* @__PURE__ */
|
|
2676
|
+
/* @__PURE__ */ import_react34.default.createElement(
|
|
1406
2677
|
ChevronRight_default,
|
|
1407
2678
|
{
|
|
1408
2679
|
className: "Layer__profit-and-loss-date-picker__button-icon",
|
|
@@ -1413,35 +2684,53 @@ var ProfitAndLossDatePicker = () => {
|
|
|
1413
2684
|
};
|
|
1414
2685
|
|
|
1415
2686
|
// src/components/ProfitAndLossSummaries/ProfitAndLossSummaries.tsx
|
|
1416
|
-
var
|
|
1417
|
-
var import_date_fns8 = require("date-fns");
|
|
2687
|
+
var import_react35 = __toESM(require("react"));
|
|
1418
2688
|
var ProfitAndLossSummaries = () => {
|
|
1419
|
-
const { data } = (0,
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
const
|
|
1424
|
-
return /* @__PURE__ */
|
|
2689
|
+
const { data: storedData } = (0, import_react35.useContext)(ProfitAndLoss.Context);
|
|
2690
|
+
const data = storedData ? storedData : { income: { value: NaN }, net_profit: NaN };
|
|
2691
|
+
const incomeDirectionClass = (data.income.value ?? NaN) < 0 ? "Layer__profit-and-loss-summaries__amount--negative" : "Layer__profit-and-loss-summaries__amount--pasitive";
|
|
2692
|
+
const expensesDirectionClass = (data?.income?.value ?? NaN) - data.net_profit < 0 ? "Layer__profit-and-loss-summaries__amount--negative" : "Layer__profit-and-loss-summaries__amount--pasitive";
|
|
2693
|
+
const netProfitDirectionClass = data.net_profit < 0 ? "Layer__profit-and-loss-summaries__amount--negative" : "Layer__profit-and-loss-summaries__amount--pasitive";
|
|
2694
|
+
return /* @__PURE__ */ import_react35.default.createElement("div", { className: "Layer__profit-and-loss-summaries" }, /* @__PURE__ */ import_react35.default.createElement("div", { className: "Layer__profit-and-loss-summaries__summary Layer__profit-and-loss-summaries__summary--income" }, /* @__PURE__ */ import_react35.default.createElement("span", { className: "Layer__profit-and-loss-summaries__title" }, "Revenue"), /* @__PURE__ */ import_react35.default.createElement(
|
|
2695
|
+
"span",
|
|
2696
|
+
{
|
|
2697
|
+
className: `Layer__profit-and-loss-summaries__amount ${incomeDirectionClass}`
|
|
2698
|
+
},
|
|
2699
|
+
centsToDollars(Math.abs(data?.income?.value ?? NaN))
|
|
2700
|
+
)), /* @__PURE__ */ import_react35.default.createElement("div", { className: "Layer__profit-and-loss-summaries__summary Layer__profit-and-loss-summaries__summary--expenses" }, /* @__PURE__ */ import_react35.default.createElement("span", { className: "Layer__profit-and-loss-summaries__title" }, "Expenses"), /* @__PURE__ */ import_react35.default.createElement(
|
|
2701
|
+
"span",
|
|
2702
|
+
{
|
|
2703
|
+
className: `Layer__profit-and-loss-summaries__amount ${expensesDirectionClass}`
|
|
2704
|
+
},
|
|
2705
|
+
centsToDollars(Math.abs((data.income.value ?? 0) - data.net_profit))
|
|
2706
|
+
)), /* @__PURE__ */ import_react35.default.createElement("div", { className: "Layer__profit-and-loss-summaries__summary Layer__profit-and-loss-summaries__summary--net-profit" }, /* @__PURE__ */ import_react35.default.createElement("span", { className: "Layer__profit-and-loss-summaries__title" }, "Net Profit"), /* @__PURE__ */ import_react35.default.createElement(
|
|
2707
|
+
"span",
|
|
2708
|
+
{
|
|
2709
|
+
className: `Layer__profit-and-loss-summaries__amount ${netProfitDirectionClass}`
|
|
2710
|
+
},
|
|
2711
|
+
centsToDollars(Math.abs(data.net_profit))
|
|
2712
|
+
)));
|
|
1425
2713
|
};
|
|
1426
2714
|
|
|
1427
2715
|
// src/components/ProfitAndLossTable/ProfitAndLossTable.tsx
|
|
1428
|
-
var
|
|
2716
|
+
var import_react37 = __toESM(require("react"));
|
|
1429
2717
|
|
|
1430
2718
|
// src/components/ProfitAndLossRow/ProfitAndLossRow.tsx
|
|
1431
|
-
var
|
|
2719
|
+
var import_react36 = __toESM(require("react"));
|
|
1432
2720
|
var ProfitAndLossRow = ({
|
|
1433
2721
|
variant,
|
|
1434
2722
|
lineItem,
|
|
1435
2723
|
depth = 0,
|
|
1436
2724
|
maxDepth = 1,
|
|
1437
|
-
direction = "DEBIT" /* DEBIT
|
|
2725
|
+
direction = "DEBIT" /* DEBIT */,
|
|
2726
|
+
summarize = true
|
|
1438
2727
|
}) => {
|
|
1439
2728
|
if (!lineItem) {
|
|
1440
2729
|
return null;
|
|
1441
2730
|
}
|
|
1442
|
-
const { value, display_name, line_items
|
|
1443
|
-
const
|
|
1444
|
-
const amount = value
|
|
2731
|
+
const { value, display_name, line_items } = lineItem;
|
|
2732
|
+
const [expanded, setExpanded] = (0, import_react36.useState)(true);
|
|
2733
|
+
const amount = value ?? 0;
|
|
1445
2734
|
const amountString = centsToDollars(Math.abs(amount));
|
|
1446
2735
|
const labelClasses = [
|
|
1447
2736
|
"Layer__profit-and-loss-row",
|
|
@@ -1451,87 +2740,154 @@ var ProfitAndLossRow = ({
|
|
|
1451
2740
|
"Layer__profit-and-loss-row",
|
|
1452
2741
|
"Layer__profit-and-loss-row__value"
|
|
1453
2742
|
];
|
|
2743
|
+
const positive = amount === 0 || direction === "CREDIT" /* CREDIT */ && amount > 0 || direction === "DEBIT" /* DEBIT */ && amount < 0;
|
|
1454
2744
|
valueClasses.push(
|
|
1455
|
-
|
|
2745
|
+
positive ? "Layer__profit-and-loss-row__value--amount-positive" : "Layer__profit-and-loss-row__value--amount-negative"
|
|
1456
2746
|
);
|
|
1457
2747
|
labelClasses.push(`Layer__profit-and-loss-row__label--depth-${depth}`);
|
|
1458
2748
|
valueClasses.push(`Layer__profit-and-loss-row__value--depth-${depth}`);
|
|
1459
|
-
|
|
1460
|
-
|
|
2749
|
+
variant && labelClasses.push(`Layer__profit-and-loss-row__label--variant-${variant}`);
|
|
2750
|
+
variant && valueClasses.push(`Layer__profit-and-loss-row__value--variant-${variant}`);
|
|
2751
|
+
const toggleExpanded = () => setExpanded(!expanded);
|
|
2752
|
+
const canGoDeeper = depth < maxDepth;
|
|
2753
|
+
const hasChildren = (line_items?.length ?? 0) > 0;
|
|
2754
|
+
const displayChildren = hasChildren && canGoDeeper;
|
|
2755
|
+
labelClasses.push(
|
|
2756
|
+
`Layer__profit-and-loss-row__label--display-children-${displayChildren}`
|
|
1461
2757
|
);
|
|
1462
|
-
|
|
1463
|
-
`Layer__profit-and-loss-row__value--
|
|
2758
|
+
valueClasses.push(
|
|
2759
|
+
`Layer__profit-and-loss-row__value--display-children-${displayChildren}`
|
|
1464
2760
|
);
|
|
1465
|
-
|
|
1466
|
-
|
|
2761
|
+
displayChildren && expanded && labelClasses.push("Layer__profit-and-loss-row__label--expanded");
|
|
2762
|
+
displayChildren && expanded && valueClasses.push("Layer__profit-and-loss-row__value--expanded");
|
|
2763
|
+
return /* @__PURE__ */ import_react36.default.createElement(import_react36.default.Fragment, null, /* @__PURE__ */ import_react36.default.createElement("div", { className: labelClasses.join(" "), onClick: toggleExpanded }, /* @__PURE__ */ import_react36.default.createElement(ChevronDown_default, { size: 16 }), display_name), /* @__PURE__ */ import_react36.default.createElement("div", { className: valueClasses.join(" ") }, amountString), canGoDeeper && hasChildren && /* @__PURE__ */ import_react36.default.createElement(
|
|
2764
|
+
"div",
|
|
1467
2765
|
{
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
2766
|
+
className: `Layer__profit-and-loss-row__children ${expanded && "Layer__profit-and-loss-row__children--expanded"}`
|
|
2767
|
+
},
|
|
2768
|
+
/* @__PURE__ */ import_react36.default.createElement("div", { className: "Layer__balance-sheet-row__children--content" }, (line_items || []).map((line_item) => /* @__PURE__ */ import_react36.default.createElement(
|
|
2769
|
+
ProfitAndLossRow,
|
|
2770
|
+
{
|
|
2771
|
+
key: line_item.display_name,
|
|
2772
|
+
lineItem: line_item,
|
|
2773
|
+
depth: depth + 1,
|
|
2774
|
+
maxDepth,
|
|
2775
|
+
direction
|
|
2776
|
+
}
|
|
2777
|
+
)), summarize && /* @__PURE__ */ import_react36.default.createElement(
|
|
2778
|
+
ProfitAndLossRow,
|
|
2779
|
+
{
|
|
2780
|
+
key: display_name,
|
|
2781
|
+
lineItem: { value, display_name: `Total of ${display_name}` },
|
|
2782
|
+
variant: "summation",
|
|
2783
|
+
depth: depth + 1,
|
|
2784
|
+
maxDepth
|
|
2785
|
+
}
|
|
2786
|
+
))
|
|
2787
|
+
));
|
|
2788
|
+
};
|
|
2789
|
+
|
|
2790
|
+
// src/components/ProfitAndLossTable/empty_profit_and_loss_report.ts
|
|
2791
|
+
var empty_profit_and_loss_report_default = {
|
|
2792
|
+
type: "Profit_And_Loss",
|
|
2793
|
+
business_id: "",
|
|
2794
|
+
start_date: "",
|
|
2795
|
+
end_date: "",
|
|
2796
|
+
income: {
|
|
2797
|
+
name: "INCOME",
|
|
2798
|
+
display_name: "Income",
|
|
2799
|
+
value: NaN,
|
|
2800
|
+
line_items: null
|
|
2801
|
+
},
|
|
2802
|
+
cost_of_goods_sold: {
|
|
2803
|
+
display_name: "Cost of Goods Sold",
|
|
2804
|
+
name: "COGS",
|
|
2805
|
+
value: NaN,
|
|
2806
|
+
line_items: null
|
|
2807
|
+
},
|
|
2808
|
+
gross_profit: NaN,
|
|
2809
|
+
expenses: {
|
|
2810
|
+
name: "EXPENSES",
|
|
2811
|
+
display_name: "Expenses",
|
|
2812
|
+
value: NaN,
|
|
2813
|
+
line_items: null
|
|
2814
|
+
},
|
|
2815
|
+
profit_before_taxes: NaN,
|
|
2816
|
+
taxes: {
|
|
2817
|
+
name: "TAXES",
|
|
2818
|
+
display_name: "Taxes",
|
|
2819
|
+
value: NaN,
|
|
2820
|
+
line_items: null
|
|
2821
|
+
},
|
|
2822
|
+
net_profit: NaN,
|
|
2823
|
+
other_outflows: {
|
|
2824
|
+
name: "OTHER_OUTFLOWS",
|
|
2825
|
+
display_name: "Other outflows",
|
|
2826
|
+
value: NaN,
|
|
2827
|
+
line_items: null
|
|
2828
|
+
},
|
|
2829
|
+
personal_expenses: {
|
|
2830
|
+
name: "PERSONAL",
|
|
2831
|
+
display_name: "Personal expenses",
|
|
2832
|
+
value: NaN,
|
|
2833
|
+
line_items: null
|
|
2834
|
+
},
|
|
2835
|
+
fully_categorized: false
|
|
1475
2836
|
};
|
|
1476
2837
|
|
|
1477
2838
|
// src/components/ProfitAndLossTable/ProfitAndLossTable.tsx
|
|
1478
2839
|
var ProfitAndLossTable = () => {
|
|
1479
|
-
const { data, isLoading } = (0,
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
{
|
|
1483
|
-
lineItem: data.income,
|
|
1484
|
-
direction: "CREDIT" /* CREDIT */
|
|
1485
|
-
}
|
|
1486
|
-
), /* @__PURE__ */ import_react20.default.createElement(
|
|
2840
|
+
const { data: actualData, isLoading } = (0, import_react37.useContext)(ProfitAndLoss.Context);
|
|
2841
|
+
const data = !actualData || isLoading ? empty_profit_and_loss_report_default : actualData;
|
|
2842
|
+
return /* @__PURE__ */ import_react37.default.createElement(import_react37.default.Fragment, null, /* @__PURE__ */ import_react37.default.createElement("div", { className: "Layer__profit-and-loss-table" }, /* @__PURE__ */ import_react37.default.createElement(ProfitAndLossRow, { lineItem: data.income, direction: "CREDIT" /* CREDIT */ }), /* @__PURE__ */ import_react37.default.createElement(
|
|
1487
2843
|
ProfitAndLossRow,
|
|
1488
2844
|
{
|
|
1489
2845
|
lineItem: data.cost_of_goods_sold,
|
|
1490
2846
|
direction: "DEBIT" /* DEBIT */
|
|
1491
2847
|
}
|
|
1492
|
-
), /* @__PURE__ */
|
|
2848
|
+
), /* @__PURE__ */ import_react37.default.createElement(
|
|
1493
2849
|
ProfitAndLossRow,
|
|
1494
2850
|
{
|
|
1495
2851
|
lineItem: {
|
|
1496
2852
|
value: data.gross_profit,
|
|
1497
2853
|
display_name: "Gross Profit"
|
|
1498
2854
|
},
|
|
1499
|
-
variant: "
|
|
2855
|
+
variant: "summation",
|
|
1500
2856
|
direction: "CREDIT" /* CREDIT */
|
|
1501
2857
|
}
|
|
1502
|
-
), /* @__PURE__ */
|
|
2858
|
+
), /* @__PURE__ */ import_react37.default.createElement(
|
|
1503
2859
|
ProfitAndLossRow,
|
|
1504
2860
|
{
|
|
1505
2861
|
lineItem: data.expenses,
|
|
1506
2862
|
direction: "DEBIT" /* DEBIT */
|
|
1507
2863
|
}
|
|
1508
|
-
), /* @__PURE__ */
|
|
2864
|
+
), /* @__PURE__ */ import_react37.default.createElement(
|
|
1509
2865
|
ProfitAndLossRow,
|
|
1510
2866
|
{
|
|
1511
2867
|
lineItem: {
|
|
1512
2868
|
value: data.profit_before_taxes,
|
|
1513
2869
|
display_name: "Profit Before Taxes"
|
|
1514
2870
|
},
|
|
1515
|
-
variant: "
|
|
2871
|
+
variant: "summation",
|
|
1516
2872
|
direction: "CREDIT" /* CREDIT */
|
|
1517
2873
|
}
|
|
1518
|
-
), /* @__PURE__ */
|
|
2874
|
+
), /* @__PURE__ */ import_react37.default.createElement(ProfitAndLossRow, { lineItem: data.taxes, direction: "DEBIT" /* DEBIT */ }), /* @__PURE__ */ import_react37.default.createElement(
|
|
1519
2875
|
ProfitAndLossRow,
|
|
1520
2876
|
{
|
|
1521
2877
|
lineItem: {
|
|
1522
2878
|
value: data.net_profit,
|
|
1523
2879
|
display_name: "Net Profit"
|
|
1524
2880
|
},
|
|
1525
|
-
variant: "
|
|
2881
|
+
variant: "summation",
|
|
1526
2882
|
direction: "CREDIT" /* CREDIT */
|
|
1527
2883
|
}
|
|
1528
|
-
), /* @__PURE__ */
|
|
2884
|
+
)), /* @__PURE__ */ import_react37.default.createElement("div", { className: "Layer__profit-and-loss-table Layer__profit-and-loss-table__outflows" }, /* @__PURE__ */ import_react37.default.createElement(
|
|
1529
2885
|
ProfitAndLossRow,
|
|
1530
2886
|
{
|
|
1531
2887
|
lineItem: data.other_outflows,
|
|
1532
2888
|
direction: "DEBIT" /* DEBIT */
|
|
1533
2889
|
}
|
|
1534
|
-
), /* @__PURE__ */
|
|
2890
|
+
), /* @__PURE__ */ import_react37.default.createElement(
|
|
1535
2891
|
ProfitAndLossRow,
|
|
1536
2892
|
{
|
|
1537
2893
|
lineItem: data.personal_expenses,
|
|
@@ -1542,7 +2898,7 @@ var ProfitAndLossTable = () => {
|
|
|
1542
2898
|
|
|
1543
2899
|
// src/components/ProfitAndLoss/ProfitAndLoss.tsx
|
|
1544
2900
|
var import_date_fns9 = require("date-fns");
|
|
1545
|
-
var PNLContext = (0,
|
|
2901
|
+
var PNLContext = (0, import_react38.createContext)({
|
|
1546
2902
|
data: void 0,
|
|
1547
2903
|
isLoading: true,
|
|
1548
2904
|
error: void 0,
|
|
@@ -1555,7 +2911,7 @@ var PNLContext = (0, import_react21.createContext)({
|
|
|
1555
2911
|
});
|
|
1556
2912
|
var ProfitAndLoss = ({ children }) => {
|
|
1557
2913
|
const contextData = useProfitAndLoss();
|
|
1558
|
-
return /* @__PURE__ */
|
|
2914
|
+
return /* @__PURE__ */ import_react38.default.createElement(PNLContext.Provider, { value: contextData }, /* @__PURE__ */ import_react38.default.createElement("div", { className: "Layer__component Layer__profit-and-loss" }, /* @__PURE__ */ import_react38.default.createElement("h2", { className: "Layer__profit-and-loss__title" }, "Profit & Loss"), children));
|
|
1559
2915
|
};
|
|
1560
2916
|
ProfitAndLoss.Chart = ProfitAndLossChart;
|
|
1561
2917
|
ProfitAndLoss.Context = PNLContext;
|
|
@@ -1564,12 +2920,14 @@ ProfitAndLoss.Summaries = ProfitAndLossSummaries;
|
|
|
1564
2920
|
ProfitAndLoss.Table = ProfitAndLossTable;
|
|
1565
2921
|
|
|
1566
2922
|
// src/providers/LayerProvider/LayerProvider.tsx
|
|
1567
|
-
var
|
|
2923
|
+
var import_react39 = __toESM(require("react"));
|
|
2924
|
+
var import_date_fns10 = require("date-fns");
|
|
1568
2925
|
var import_swr5 = __toESM(require("swr"));
|
|
1569
2926
|
var reducer = (state, action) => {
|
|
1570
2927
|
switch (action.type) {
|
|
1571
2928
|
case "LayerContext.setAuth" /* setAuth */:
|
|
1572
2929
|
case "LayerContext.setCategories" /* setCategories */:
|
|
2930
|
+
case "LayerContext.setTheme" /* setTheme */:
|
|
1573
2931
|
return { ...state, ...action.payload };
|
|
1574
2932
|
default:
|
|
1575
2933
|
return state;
|
|
@@ -1578,11 +2936,13 @@ var reducer = (state, action) => {
|
|
|
1578
2936
|
var LayerEnvironment = {
|
|
1579
2937
|
production: {
|
|
1580
2938
|
url: "not defined yet",
|
|
1581
|
-
scope: "not defined yet"
|
|
2939
|
+
scope: "not defined yet",
|
|
2940
|
+
apiUrl: "not defined yet"
|
|
1582
2941
|
},
|
|
1583
2942
|
staging: {
|
|
1584
2943
|
url: "https://auth.layerfi.com/oauth2/token",
|
|
1585
|
-
scope: "https://sandbox.layerfi.com/sandbox"
|
|
2944
|
+
scope: "https://sandbox.layerfi.com/sandbox",
|
|
2945
|
+
apiUrl: "https://sandbox.layerfi.com"
|
|
1586
2946
|
}
|
|
1587
2947
|
};
|
|
1588
2948
|
var LayerProvider = ({
|
|
@@ -1590,8 +2950,9 @@ var LayerProvider = ({
|
|
|
1590
2950
|
appSecret,
|
|
1591
2951
|
businessId,
|
|
1592
2952
|
children,
|
|
1593
|
-
|
|
1594
|
-
environment = "production"
|
|
2953
|
+
businessAccessToken,
|
|
2954
|
+
environment = "production",
|
|
2955
|
+
theme
|
|
1595
2956
|
}) => {
|
|
1596
2957
|
const defaultSWRConfig = {
|
|
1597
2958
|
revalidateInterval: 0,
|
|
@@ -1599,47 +2960,234 @@ var LayerProvider = ({
|
|
|
1599
2960
|
revalidateOnReconnect: false,
|
|
1600
2961
|
revalidateIfStale: false
|
|
1601
2962
|
};
|
|
1602
|
-
const { url, scope } = LayerEnvironment[environment];
|
|
1603
|
-
const [state, dispatch] = (0,
|
|
1604
|
-
auth: {
|
|
2963
|
+
const { url, scope, apiUrl } = LayerEnvironment[environment];
|
|
2964
|
+
const [state, dispatch] = (0, import_react39.useReducer)(reducer, {
|
|
2965
|
+
auth: {
|
|
2966
|
+
access_token: "",
|
|
2967
|
+
token_type: "",
|
|
2968
|
+
expires_in: 0,
|
|
2969
|
+
expires_at: new Date(2e3, 1, 1)
|
|
2970
|
+
},
|
|
1605
2971
|
businessId,
|
|
1606
|
-
categories: []
|
|
2972
|
+
categories: [],
|
|
2973
|
+
apiUrl,
|
|
2974
|
+
theme
|
|
1607
2975
|
});
|
|
1608
|
-
const { data: auth } = (0, import_swr5.default)(
|
|
1609
|
-
"authenticate",
|
|
2976
|
+
const { data: auth } = appId !== void 0 && appSecret !== void 0 ? (0, import_swr5.default)(
|
|
2977
|
+
businessAccessToken === void 0 && appId !== void 0 && appSecret !== void 0 && (0, import_date_fns10.isBefore)(state.auth.expires_at, /* @__PURE__ */ new Date()) && "authenticate",
|
|
1610
2978
|
Layer.authenticate({
|
|
1611
2979
|
appId,
|
|
1612
2980
|
appSecret,
|
|
1613
2981
|
authenticationUrl: url,
|
|
1614
|
-
scope
|
|
1615
|
-
clientId
|
|
2982
|
+
scope
|
|
1616
2983
|
}),
|
|
1617
2984
|
defaultSWRConfig
|
|
1618
|
-
);
|
|
1619
|
-
(0,
|
|
1620
|
-
if (
|
|
1621
|
-
dispatch({
|
|
2985
|
+
) : { data: void 0 };
|
|
2986
|
+
(0, import_react39.useEffect)(() => {
|
|
2987
|
+
if (businessAccessToken) {
|
|
2988
|
+
dispatch({
|
|
2989
|
+
type: "LayerContext.setAuth" /* setAuth */,
|
|
2990
|
+
payload: {
|
|
2991
|
+
auth: {
|
|
2992
|
+
access_token: businessAccessToken,
|
|
2993
|
+
token_type: "Bearer",
|
|
2994
|
+
expires_in: 3600,
|
|
2995
|
+
expires_at: (0, import_date_fns10.add)(/* @__PURE__ */ new Date(), { seconds: 3600 })
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
});
|
|
2999
|
+
} else if (auth?.access_token) {
|
|
3000
|
+
dispatch({
|
|
3001
|
+
type: "LayerContext.setAuth" /* setAuth */,
|
|
3002
|
+
payload: {
|
|
3003
|
+
auth: {
|
|
3004
|
+
...auth,
|
|
3005
|
+
expires_at: (0, import_date_fns10.add)(/* @__PURE__ */ new Date(), { seconds: auth.expires_in })
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
});
|
|
1622
3009
|
}
|
|
1623
|
-
}, [auth?.access_token]);
|
|
3010
|
+
}, [businessAccessToken, auth?.access_token]);
|
|
1624
3011
|
const { data: categories } = (0, import_swr5.default)(
|
|
1625
3012
|
businessId && auth?.access_token && `categories-${businessId}`,
|
|
1626
|
-
Layer.getCategories(auth?.access_token, { params: { businessId } }),
|
|
3013
|
+
Layer.getCategories(apiUrl, auth?.access_token, { params: { businessId } }),
|
|
1627
3014
|
defaultSWRConfig
|
|
1628
3015
|
);
|
|
1629
|
-
(0,
|
|
1630
|
-
if (
|
|
3016
|
+
(0, import_react39.useEffect)(() => {
|
|
3017
|
+
if (categories?.data?.categories?.length) {
|
|
1631
3018
|
dispatch({
|
|
1632
3019
|
type: "LayerContext.setCategories" /* setCategories */,
|
|
1633
3020
|
payload: { categories: categories.data.categories || [] }
|
|
1634
3021
|
});
|
|
1635
3022
|
}
|
|
1636
3023
|
}, [categories?.data?.categories?.length]);
|
|
1637
|
-
|
|
3024
|
+
const setTheme = (theme2) => dispatch({
|
|
3025
|
+
type: "LayerContext.setTheme" /* setTheme */,
|
|
3026
|
+
payload: { theme: theme2 }
|
|
3027
|
+
});
|
|
3028
|
+
return /* @__PURE__ */ import_react39.default.createElement(import_swr5.SWRConfig, { value: defaultSWRConfig }, /* @__PURE__ */ import_react39.default.createElement(LayerContext.Provider, { value: { ...state, setTheme } }, children));
|
|
3029
|
+
};
|
|
3030
|
+
|
|
3031
|
+
// src/components/ChartOfAccounts/ChartOfAccounts.tsx
|
|
3032
|
+
var import_react42 = __toESM(require("react"));
|
|
3033
|
+
|
|
3034
|
+
// src/hooks/useChartOfAccounts/useChartOfAccounts.tsx
|
|
3035
|
+
var import_swr6 = __toESM(require("swr"));
|
|
3036
|
+
var useChartOfAccounts = () => {
|
|
3037
|
+
const { auth, businessId, apiUrl } = useLayerContext();
|
|
3038
|
+
const { data, isLoading, error, mutate } = (0, import_swr6.default)(
|
|
3039
|
+
businessId && auth?.access_token && `chart-of-accounts-${businessId}`,
|
|
3040
|
+
Layer.getChartOfAccounts(apiUrl, auth?.access_token, {
|
|
3041
|
+
params: { businessId }
|
|
3042
|
+
})
|
|
3043
|
+
);
|
|
3044
|
+
const create = (newAccount) => Layer.createAccount(apiUrl, auth?.access_token, {
|
|
3045
|
+
params: { businessId },
|
|
3046
|
+
body: newAccount
|
|
3047
|
+
}).then(({ data: data2 }) => (mutate(), data2));
|
|
3048
|
+
return { data: data?.data, isLoading, error, create };
|
|
3049
|
+
};
|
|
3050
|
+
|
|
3051
|
+
// src/components/ChartOfAccountsNewForm/ChartOfAccountsNewForm.tsx
|
|
3052
|
+
var import_react40 = __toESM(require("react"));
|
|
3053
|
+
var import_react_select2 = __toESM(require("react-select"));
|
|
3054
|
+
var flattenAccounts = (accounts) => accounts.flatMap((a) => [a, flattenAccounts(a.subAccounts || [])]).flat().filter((id) => id);
|
|
3055
|
+
var ChartOfAccountsNewForm = () => {
|
|
3056
|
+
const { data, create: createAccount2 } = useChartOfAccounts();
|
|
3057
|
+
const accountOptions = (0, import_react40.useMemo)(
|
|
3058
|
+
() => flattenAccounts(data?.accounts || []).sort(
|
|
3059
|
+
(a, b) => a?.name && b?.name ? a.name.localeCompare(b.name) : 0
|
|
3060
|
+
),
|
|
3061
|
+
[data?.accounts?.length]
|
|
3062
|
+
);
|
|
3063
|
+
const [name, setName] = (0, import_react40.useState)("");
|
|
3064
|
+
const [description, setDescription] = (0, import_react40.useState)("");
|
|
3065
|
+
const [normality, setNormality] = (0, import_react40.useState)("DEBIT" /* DEBIT */);
|
|
3066
|
+
const [parentAccount, setParentAccount] = (0, import_react40.useState)(
|
|
3067
|
+
data?.accounts[0]
|
|
3068
|
+
);
|
|
3069
|
+
const save = () => {
|
|
3070
|
+
createAccount2({
|
|
3071
|
+
name,
|
|
3072
|
+
normality,
|
|
3073
|
+
parent_id: {
|
|
3074
|
+
type: "AccountId",
|
|
3075
|
+
id: parentAccount?.id || ""
|
|
3076
|
+
},
|
|
3077
|
+
description
|
|
3078
|
+
});
|
|
3079
|
+
};
|
|
3080
|
+
return /* @__PURE__ */ import_react40.default.createElement("div", { className: "Layer__chart-of-accounts-new-form" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "Layer__chart-of-accounts-new-form__field" }, /* @__PURE__ */ import_react40.default.createElement("span", null, "Name"), /* @__PURE__ */ import_react40.default.createElement(
|
|
3081
|
+
"input",
|
|
3082
|
+
{
|
|
3083
|
+
name: "name",
|
|
3084
|
+
value: name,
|
|
3085
|
+
onChange: (event) => setName(event.target.value)
|
|
3086
|
+
}
|
|
3087
|
+
)), /* @__PURE__ */ import_react40.default.createElement("div", { className: "Layer__chart-of-accounts-new-form__field" }, /* @__PURE__ */ import_react40.default.createElement("span", null, "Description"), /* @__PURE__ */ import_react40.default.createElement(
|
|
3088
|
+
"input",
|
|
3089
|
+
{
|
|
3090
|
+
name: "description",
|
|
3091
|
+
value: description,
|
|
3092
|
+
onChange: (event) => setDescription(event.target.value)
|
|
3093
|
+
}
|
|
3094
|
+
)), /* @__PURE__ */ import_react40.default.createElement("div", { className: "Layer__chart-of-accounts-new-form__field" }, /* @__PURE__ */ import_react40.default.createElement("span", null, "Normality"), /* @__PURE__ */ import_react40.default.createElement(
|
|
3095
|
+
import_react_select2.default,
|
|
3096
|
+
{
|
|
3097
|
+
isSearchable: false,
|
|
3098
|
+
onChange: (value) => value && setNormality(value.value),
|
|
3099
|
+
options: [
|
|
3100
|
+
{ label: "Credit", value: "CREDIT" /* CREDIT */ },
|
|
3101
|
+
{ label: "Debit", value: "DEBIT" /* DEBIT */ }
|
|
3102
|
+
]
|
|
3103
|
+
}
|
|
3104
|
+
)), /* @__PURE__ */ import_react40.default.createElement("div", { className: "Layer__chart-of-accounts-new-form__field" }, /* @__PURE__ */ import_react40.default.createElement("span", null, "Parent Account"), /* @__PURE__ */ import_react40.default.createElement(
|
|
3105
|
+
import_react_select2.default,
|
|
3106
|
+
{
|
|
3107
|
+
isSearchable: true,
|
|
3108
|
+
value: parentAccount,
|
|
3109
|
+
onChange: (value) => value && setParentAccount(value),
|
|
3110
|
+
getOptionLabel: (a) => a.name,
|
|
3111
|
+
getOptionValue: (a) => a.id,
|
|
3112
|
+
options: accountOptions
|
|
3113
|
+
}
|
|
3114
|
+
)), /* @__PURE__ */ import_react40.default.createElement("div", { className: "Layer__chart-of-accounts-new-form__field Layer__chart-of-accounts-new-form__field--actions" }, /* @__PURE__ */ import_react40.default.createElement("button", { onClick: save }, "Save")));
|
|
3115
|
+
};
|
|
3116
|
+
|
|
3117
|
+
// src/components/ChartOfAccountsRow/ChartOfAccountsRow.tsx
|
|
3118
|
+
var import_react41 = __toESM(require("react"));
|
|
3119
|
+
var ChartOfAccountsRow = ({ account, depth = 0 }) => {
|
|
3120
|
+
const classNames12 = [
|
|
3121
|
+
"Layer__chart-of-accounts-row__table-cell",
|
|
3122
|
+
depth > 0 && `Layer__chart-of-accounts-row__table-cell--depth-${depth}`
|
|
3123
|
+
];
|
|
3124
|
+
const className = classNames12.filter((id) => id).join(" ");
|
|
3125
|
+
const amountClassName = account.balance < 0 ? "Layer__chart-of-accounts-row__table-cell--amount-negative" : "Layer__chart-of-accounts-row__table-cell--amount-positive";
|
|
3126
|
+
return /* @__PURE__ */ import_react41.default.createElement(import_react41.default.Fragment, null, /* @__PURE__ */ import_react41.default.createElement(
|
|
3127
|
+
"div",
|
|
3128
|
+
{
|
|
3129
|
+
className: `${className} Layer__chart-of-accounts-row__table-cell--name`
|
|
3130
|
+
},
|
|
3131
|
+
account.name
|
|
3132
|
+
), /* @__PURE__ */ import_react41.default.createElement(
|
|
3133
|
+
"div",
|
|
3134
|
+
{
|
|
3135
|
+
className: `${className} Layer__chart-of-accounts-row__table-cell--type`
|
|
3136
|
+
},
|
|
3137
|
+
"Assets"
|
|
3138
|
+
), /* @__PURE__ */ import_react41.default.createElement(
|
|
3139
|
+
"div",
|
|
3140
|
+
{
|
|
3141
|
+
className: `${className} Layer__chart-of-accounts-row__table-cell--subtype`
|
|
3142
|
+
},
|
|
3143
|
+
"Cash"
|
|
3144
|
+
), /* @__PURE__ */ import_react41.default.createElement(
|
|
3145
|
+
"div",
|
|
3146
|
+
{
|
|
3147
|
+
className: `${className} Layer__chart-of-accounts-row__table-cell--balance ${amountClassName}`
|
|
3148
|
+
},
|
|
3149
|
+
centsToDollars(Math.abs(account.balance || 0))
|
|
3150
|
+
), /* @__PURE__ */ import_react41.default.createElement(
|
|
3151
|
+
"div",
|
|
3152
|
+
{
|
|
3153
|
+
className: `${className} Layer__chart-of-accounts-row__table-cell--actions`
|
|
3154
|
+
},
|
|
3155
|
+
/* @__PURE__ */ import_react41.default.createElement("button", { className: "Layer__chart-of-accounts-row__view-entries-button" }, "View Entries")
|
|
3156
|
+
), (account.subAccounts || []).map((subAccount) => /* @__PURE__ */ import_react41.default.createElement(
|
|
3157
|
+
ChartOfAccountsRow,
|
|
3158
|
+
{
|
|
3159
|
+
key: subAccount.id,
|
|
3160
|
+
account: subAccount,
|
|
3161
|
+
depth: depth + 1
|
|
3162
|
+
}
|
|
3163
|
+
)));
|
|
3164
|
+
};
|
|
3165
|
+
|
|
3166
|
+
// src/components/ChartOfAccounts/ChartOfAccounts.tsx
|
|
3167
|
+
var ChartOfAccounts = () => {
|
|
3168
|
+
const { data, isLoading } = useChartOfAccounts();
|
|
3169
|
+
const [showingForm, setShowingForm] = (0, import_react42.useState)(false);
|
|
3170
|
+
return /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__component Layer__chart-of-accounts" }, !data || isLoading ? "Loading." : /* @__PURE__ */ import_react42.default.createElement(import_react42.default.Fragment, null, /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__chart-of-accounts__header" }, /* @__PURE__ */ import_react42.default.createElement("h2", { className: "Layer__chart-of-accounts__title" }, "Chart of Accounts"), /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__chart-of-accounts__actions" }, /* @__PURE__ */ import_react42.default.createElement("button", { className: "Layer__chart-of-accounts__download-button" }, /* @__PURE__ */ import_react42.default.createElement(DownloadCloud_default, null), "Download"), /* @__PURE__ */ import_react42.default.createElement(
|
|
3171
|
+
"button",
|
|
3172
|
+
{
|
|
3173
|
+
className: "Layer__chart-of-accounts__edit-accounts-button",
|
|
3174
|
+
onClick: () => setShowingForm(!showingForm)
|
|
3175
|
+
},
|
|
3176
|
+
"Edit Accounts"
|
|
3177
|
+
))), showingForm && /* @__PURE__ */ import_react42.default.createElement(ChartOfAccountsNewForm, null), /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__chart-of-accounts__table" }, /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__chart-of-accounts__table-cell Layer__chart-of-accounts__table-cell--header" }, "Name"), /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__chart-of-accounts__table-cell Layer__chart-of-accounts__table-cell--header" }, "Type"), /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__chart-of-accounts__table-cell Layer__chart-of-accounts__table-cell--header" }, "Sub-Type"), /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__chart-of-accounts__table-cell Layer__chart-of-accounts__table-cell--header Layer__chart-of-accounts__table-cell--header-balance" }, "Balance"), /* @__PURE__ */ import_react42.default.createElement("div", { className: "Layer__chart-of-accounts__table-cell Layer__chart-of-accounts__table-cell--header" }), data.accounts.map((account) => /* @__PURE__ */ import_react42.default.createElement(
|
|
3178
|
+
ChartOfAccountsRow,
|
|
3179
|
+
{
|
|
3180
|
+
key: account.id,
|
|
3181
|
+
account,
|
|
3182
|
+
depth: 0
|
|
3183
|
+
}
|
|
3184
|
+
)))));
|
|
1638
3185
|
};
|
|
1639
3186
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1640
3187
|
0 && (module.exports = {
|
|
1641
3188
|
BalanceSheet,
|
|
1642
3189
|
BankTransactions,
|
|
3190
|
+
ChartOfAccounts,
|
|
1643
3191
|
Hello,
|
|
1644
3192
|
LayerProvider,
|
|
1645
3193
|
ProfitAndLoss
|