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