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