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