@layerfi/components 0.1.132-alpha.3 → 0.1.132-alpha.5

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.
@@ -278,7 +278,7 @@ var getIntlLocale = (locale) => {
278
278
  };
279
279
  var package_default = {
280
280
  name: "@layerfi/components",
281
- version: "0.1.132-alpha.3",
281
+ version: "0.1.132-alpha.5",
282
282
  description: "Layer React Components",
283
283
  main: "dist/cjs/index.cjs",
284
284
  module: "dist/esm/index.mjs",
@@ -8030,6 +8030,9 @@ var getLeafCategories$1 = (categories) => {
8030
8030
  return getLeafCategories$1(category.subCategories);
8031
8031
  });
8032
8032
  };
8033
+ var flattenCategories$2 = (categories) => {
8034
+ return categories.flatMap((category) => [category, ...category.subCategories ? flattenCategories$2(category.subCategories) : []]);
8035
+ };
8033
8036
  //#endregion
8034
8037
  //#region src/schemas/customer.ts
8035
8038
  var CustomerStatusSchema = effect.Schema.Literal("ACTIVE", "ARCHIVED");
@@ -8742,6 +8745,7 @@ var CategorizationRuleSchema = effect_index.Schema.Struct({
8742
8745
  suggestion2: (0, effect_index.pipe)(effect_index.Schema.propertySignature(effect_index.Schema.NullishOr(AccountIdentifierSchema)), effect_index.Schema.fromKey("suggestion_2")),
8743
8746
  suggestion3: (0, effect_index.pipe)(effect_index.Schema.propertySignature(effect_index.Schema.NullishOr(AccountIdentifierSchema)), effect_index.Schema.fromKey("suggestion_3")),
8744
8747
  counterpartyFilter: (0, effect_index.pipe)(effect_index.Schema.propertySignature(effect_index.Schema.NullishOr(BankTransactionCounterpartySchema)), effect_index.Schema.fromKey("counterparty_filter")),
8748
+ readableTransactionDescriptionFilter: (0, effect_index.pipe)(effect_index.Schema.propertySignature(effect_index.Schema.NullishOr(effect_index.Schema.String)), effect_index.Schema.fromKey("readable_transaction_description_filter")),
8745
8749
  bankDirectionFilter: (0, effect_index.pipe)(effect_index.Schema.propertySignature(effect_index.Schema.NullishOr(BankDirectionFilterSchema)), effect_index.Schema.fromKey("bank_direction_filter")),
8746
8750
  createdAt: (0, effect_index.pipe)(effect_index.Schema.propertySignature(effect_index.Schema.Date), effect_index.Schema.fromKey("created_at")),
8747
8751
  updatedAt: (0, effect_index.pipe)(effect_index.Schema.propertySignature(effect_index.Schema.Date), effect_index.Schema.fromKey("updated_at")),
@@ -23608,10 +23612,13 @@ var getCategorizationRuleDirectionLabel = (bankDirectionFilter, t) => {
23608
23612
  const entry = DIRECTION_CONFIG.find((c) => c.value === bankDirectionFilter);
23609
23613
  return entry ? t(entry.i18nKey, entry.defaultValue) : t("categorizationRules:label.any_direction", "Any direction");
23610
23614
  };
23615
+ var getCategorizationRuleCounterpartyLabel = (rule) => {
23616
+ var _ref, _rule$counterpartyFil, _rule$counterpartyFil2;
23617
+ return (_ref = (_rule$counterpartyFil = (_rule$counterpartyFil2 = rule.counterpartyFilter) === null || _rule$counterpartyFil2 === void 0 ? void 0 : _rule$counterpartyFil2.name) !== null && _rule$counterpartyFil !== void 0 ? _rule$counterpartyFil : rule.readableTransactionDescriptionFilter) !== null && _ref !== void 0 ? _ref : void 0;
23618
+ };
23611
23619
  //#endregion
23612
23620
  //#region src/components/CategorizationRules/CategorizationRulesMobileList/CategorizationRulesMobileList.tsx
23613
23621
  var CategorizationRuleMobileListItem = ({ rule, options, onDeletePress }) => {
23614
- var _rule$counterpartyFil;
23615
23622
  const { t } = (0, react_i18next.useTranslation)();
23616
23623
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
23617
23624
  justify: "space-between",
@@ -23625,7 +23632,7 @@ var CategorizationRuleMobileListItem = ({ rule, options, onDeletePress }) => {
23625
23632
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
23626
23633
  weight: "bold",
23627
23634
  ellipsis: true,
23628
- children: (_rule$counterpartyFil = rule.counterpartyFilter) === null || _rule$counterpartyFil === void 0 ? void 0 : _rule$counterpartyFil.name
23635
+ children: getCategorizationRuleCounterpartyLabel(rule)
23629
23636
  }),
23630
23637
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
23631
23638
  gap: "3xs",
@@ -23970,13 +23977,10 @@ var CategorizationRulesTable = ({ data, isLoading, isError, paginationProps, opt
23970
23977
  {
23971
23978
  id: CategorizationRuleColumns.Counterparty,
23972
23979
  header: t("common:label.counterparty", "Counterparty"),
23973
- cell: (row) => {
23974
- var _row$original$counter;
23975
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
23976
- ellipsis: true,
23977
- children: (_row$original$counter = row.original.counterpartyFilter) === null || _row$original$counter === void 0 ? void 0 : _row$original$counter.name
23978
- });
23979
- }
23980
+ cell: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
23981
+ ellipsis: true,
23982
+ children: getCategorizationRuleCounterpartyLabel(row.original)
23983
+ })
23980
23984
  },
23981
23985
  {
23982
23986
  id: CategorizationRuleColumns.Direction,
@@ -24067,7 +24071,7 @@ var CategorizationRulesHeader = ({ onGoBack }) => {
24067
24071
  };
24068
24072
  var resolveVariant$1 = ({ width }) => width < BREAKPOINTS.TABLET ? "Mobile" : "Desktop";
24069
24073
  var ResponsiveCategorizationRulesView = () => {
24070
- var _selectedRule$counter, _selectedRule$counter2;
24074
+ var _ref;
24071
24075
  const { t } = (0, react_i18next.useTranslation)();
24072
24076
  const [selectedRule, setSelectedRule] = (0, react.useState)(null);
24073
24077
  const [showDeletionConfirmationModal, setShowDeletionConfirmationModal] = (0, react.useState)(false);
@@ -24077,7 +24081,7 @@ var ResponsiveCategorizationRulesView = () => {
24077
24081
  const { data: categories, isLoading: categoriesAreLoading } = useCategories({ mode: CategoriesListMode.All });
24078
24082
  const options = (0, react.useMemo)(() => {
24079
24083
  if (!categories) return [];
24080
- return getLeafCategories$1(categories);
24084
+ return flattenCategories$2(categories);
24081
24085
  }, [categories]);
24082
24086
  const { data, hasMore, isLoading: rulesAreLoading, isError, size, setSize } = useListCategorizationRules({});
24083
24087
  const categorizationRules = (0, react.useMemo)(() => data === null || data === void 0 ? void 0 : data.flatMap(({ data }) => data), [data]);
@@ -24123,66 +24127,69 @@ var ResponsiveCategorizationRulesView = () => {
24123
24127
  ]);
24124
24128
  const isLoading = data === void 0 || rulesAreLoading || categoriesAreLoading;
24125
24129
  const { toBankTransactionsTable } = useBankTransactionsNavigation();
24130
+ const DesktopView = (0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BaseDetailView, {
24131
+ slots: {
24132
+ Header: CategorizationRulesHeader,
24133
+ BackIcon: BackArrow
24134
+ },
24135
+ name: "CategorizationRulesDrawer",
24136
+ onGoBack: toBankTransactionsTable,
24137
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CategorizationRulesTable, {
24138
+ data: categorizationRules,
24139
+ isLoading,
24140
+ isError,
24141
+ paginationProps,
24142
+ options,
24143
+ onDeleteRule,
24144
+ slots: {
24145
+ EmptyState: CategorizationRulesEmptyState,
24146
+ ErrorState: CategorizationRulesErrorState
24147
+ }
24148
+ })
24149
+ }), [
24150
+ toBankTransactionsTable,
24151
+ categorizationRules,
24152
+ isLoading,
24153
+ isError,
24154
+ paginationProps,
24155
+ options,
24156
+ onDeleteRule
24157
+ ]);
24158
+ const MobileView = (0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(VStack, {
24159
+ gap: "md",
24160
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CategorizationRulesHeader, { onGoBack: toBankTransactionsTable }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CategorizationRulesMobileList, {
24161
+ data: categorizationRules,
24162
+ isLoading,
24163
+ isError,
24164
+ paginationProps,
24165
+ options,
24166
+ onDeleteRule,
24167
+ slots: {
24168
+ EmptyState: CategorizationRulesEmptyState,
24169
+ ErrorState: CategorizationRulesErrorState
24170
+ }
24171
+ })]
24172
+ }), [
24173
+ toBankTransactionsTable,
24174
+ categorizationRules,
24175
+ isLoading,
24176
+ isError,
24177
+ paginationProps,
24178
+ options,
24179
+ onDeleteRule
24180
+ ]);
24181
+ const selectedRuleCounterpartyLabel = (_ref = selectedRule && getCategorizationRuleCounterpartyLabel(selectedRule)) !== null && _ref !== void 0 ? _ref : t("bankTransactions:label.selected_counterparty", "this counterparty");
24126
24182
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponsiveComponent, {
24127
24183
  resolveVariant: resolveVariant$1,
24128
24184
  slots: {
24129
- Desktop: (0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BaseDetailView, {
24130
- slots: {
24131
- Header: CategorizationRulesHeader,
24132
- BackIcon: BackArrow
24133
- },
24134
- name: "CategorizationRulesDrawer",
24135
- onGoBack: toBankTransactionsTable,
24136
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CategorizationRulesTable, {
24137
- data: categorizationRules,
24138
- isLoading,
24139
- isError,
24140
- paginationProps,
24141
- options,
24142
- onDeleteRule,
24143
- slots: {
24144
- EmptyState: CategorizationRulesEmptyState,
24145
- ErrorState: CategorizationRulesErrorState
24146
- }
24147
- })
24148
- }), [
24149
- toBankTransactionsTable,
24150
- categorizationRules,
24151
- isLoading,
24152
- isError,
24153
- paginationProps,
24154
- options,
24155
- onDeleteRule
24156
- ]),
24157
- Mobile: (0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(VStack, {
24158
- gap: "md",
24159
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CategorizationRulesHeader, { onGoBack: toBankTransactionsTable }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CategorizationRulesMobileList, {
24160
- data: categorizationRules,
24161
- isLoading,
24162
- isError,
24163
- paginationProps,
24164
- options,
24165
- onDeleteRule,
24166
- slots: {
24167
- EmptyState: CategorizationRulesEmptyState,
24168
- ErrorState: CategorizationRulesErrorState
24169
- }
24170
- })]
24171
- }), [
24172
- toBankTransactionsTable,
24173
- categorizationRules,
24174
- isLoading,
24175
- isError,
24176
- paginationProps,
24177
- options,
24178
- onDeleteRule
24179
- ])
24185
+ Desktop: DesktopView,
24186
+ Mobile: MobileView
24180
24187
  }
24181
24188
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BaseConfirmationModal, {
24182
24189
  isOpen: showDeletionConfirmationModal,
24183
24190
  onOpenChange: setShowDeletionConfirmationModal,
24184
24191
  title: t("categorizationRules:prompt.delete_categorization_rule", "Delete categorization rule?"),
24185
- description: t("categorizationRules:label.transaction_no_longer_automatically_categorized", "Transactions will no longer automatically be categorized by this rule. Any transactions previously categorized to {{counterparty}} will not be affected.", { counterparty: (_selectedRule$counter = selectedRule === null || selectedRule === void 0 || (_selectedRule$counter2 = selectedRule.counterpartyFilter) === null || _selectedRule$counter2 === void 0 ? void 0 : _selectedRule$counter2.name) !== null && _selectedRule$counter !== void 0 ? _selectedRule$counter : t("bankTransactions:label.selected_counterparty", "this counterparty") }),
24192
+ description: t("categorizationRules:label.transaction_no_longer_automatically_categorized", "Transactions will no longer automatically be categorized by this rule. Any transactions previously categorized to {{counterparty}} will not be affected.", { counterparty: selectedRuleCounterpartyLabel }),
24186
24193
  onConfirm: archiveCategorizationRule,
24187
24194
  confirmLabel: t("common:action.delete_label", "Delete"),
24188
24195
  cancelLabel: t("common:action.cancel_label", "Cancel"),
@@ -27413,13 +27420,13 @@ var ProfitAndLossChartSelectionIndicator = ({ viewBox, selected }) => {
27413
27420
  const boxWidth = width + 2 * margin;
27414
27421
  const borderRadius = 6;
27415
27422
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
27416
- className: "Layer__profit-and-loss-chart__selection-indicator",
27423
+ className: "Layer__ProfitAndLossChart__SelectionIndicator",
27417
27424
  rx: borderRadius,
27418
27425
  ry: borderRadius,
27419
27426
  x: x - margin,
27420
- y: 16,
27427
+ y: 24,
27421
27428
  width: boxWidth,
27422
- height: "calc(100% - 30px)"
27429
+ height: "calc(100% - 38px)"
27423
27430
  });
27424
27431
  };
27425
27432
  //#endregion
@@ -27729,7 +27736,8 @@ var transformPnLData = ({ data, compactView, formatMonthName }) => {
27729
27736
  var CHART_MARGINS = {
27730
27737
  left: 12,
27731
27738
  right: 12,
27732
- bottom: 12
27739
+ bottom: 12,
27740
+ top: 24
27733
27741
  };
27734
27742
  var ProfitAndLossChart = ({ tagFilter, hideLegend = false }) => {
27735
27743
  var _getColor$hex, _getColor, _getColor$hex2, _getColor2, _getColor$hex3, _getColor3;
@@ -27803,9 +27811,9 @@ var ProfitAndLossChart = ({ tagFilter, hideLegend = false }) => {
27803
27811
  activationDate
27804
27812
  ]);
27805
27813
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
27806
- className: "Layer__chart-wrapper",
27814
+ className: "Layer__ProfitAndLossChart",
27807
27815
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(recharts.ResponsiveContainer, {
27808
- className: "Layer__chart-container",
27816
+ className: "Layer__ProfitAndLossChart__Container",
27809
27817
  width: "100%",
27810
27818
  height: "100%",
27811
27819
  onResize: (0, react.useCallback)((width) => {
@@ -27817,7 +27825,7 @@ var ProfitAndLossChart = ({ tagFilter, hideLegend = false }) => {
27817
27825
  margin: CHART_MARGINS,
27818
27826
  data: dataOrPlaceholderData,
27819
27827
  onClick,
27820
- className: "Layer__profit-and-loss-chart",
27828
+ className: "Layer__profit-and-loss-chart Layer__ProfitAndLossChart__Chart",
27821
27829
  children: [
27822
27830
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLossChartPatternDefs, {}),
27823
27831
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(recharts.ReferenceLine, {
@@ -27908,7 +27916,6 @@ var DetailedChart = ({ data, isLoading, interactionProps, stylingProps, slots })
27908
27916
  x: x + width / 2,
27909
27917
  textAnchor: "middle",
27910
27918
  verticalAnchor: "middle",
27911
- breakAll: true,
27912
27919
  maxLines: 2,
27913
27920
  width: Math.max(width - 40, 0),
27914
27921
  className: "Layer__DetailedChart__centerLabelTitle",
@@ -29965,7 +29972,7 @@ var SyncingBadge = () => {
29965
29972
  };
29966
29973
  //#endregion
29967
29974
  //#region src/components/ProfitAndLossHeader/ProfitAndLossHeader.tsx
29968
- var ProfitAndLossHeader = ({ text, className, headingClassName, withDatePicker, withDownloadButton, withStatus = true, stringOverrides, dateSelectionMode = "full" }) => {
29975
+ var ProfitAndLossHeader = ({ text, className, headingClassName, withDatePicker, withDownloadButton, withStatus = true, stringOverrides, dateSelectionMode = "full", trailingContent }) => {
29969
29976
  const { t } = (0, react_i18next.useTranslation)();
29970
29977
  const { data: linkedAccounts } = useLinkedAccounts();
29971
29978
  const { activePeriod } = useActiveBookkeepingPeriod();
@@ -29993,10 +30000,15 @@ var ProfitAndLossHeader = ({ text, className, headingClassName, withDatePicker,
29993
30000
  ]
29994
30001
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
29995
30002
  gap: "xs",
29996
- children: [withDatePicker && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CombinedDateRangeSelection, {
29997
- mode: dateSelectionMode,
29998
- showLabels: false
29999
- }), withDownloadButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLossDownloadButton, { stringOverrides: stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.downloadButton })]
30003
+ align: "center",
30004
+ children: [
30005
+ trailingContent,
30006
+ withDatePicker && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CombinedDateRangeSelection, {
30007
+ mode: dateSelectionMode,
30008
+ showLabels: false
30009
+ }),
30010
+ withDownloadButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLossDownloadButton, { stringOverrides: stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.downloadButton })
30011
+ ]
30000
30012
  })]
30001
30013
  });
30002
30014
  };
@@ -44106,8 +44118,8 @@ var ProfitAndLossOverviewDetailedCharts = ({ variant, detailedChartsStringOverri
44106
44118
  label: (detailedChartsStringOverrides === null || detailedChartsStringOverrides === void 0 || (_detailedChartsString2 = detailedChartsStringOverrides.detailedChartStringOverrides) === null || _detailedChartsString2 === void 0 ? void 0 : _detailedChartsString2.expenseToggleLabel) || t("common:label.expenses", "Expenses")
44107
44119
  }];
44108
44120
  }, [detailedChartsStringOverrides, t]);
44109
- const chartsWrapperClassName = variant === "accounting" ? "Layer__accounting-overview-profit-and-loss-charts" : "Layer__bookkeeping-overview-profit-and-loss-charts";
44110
- const chartContainerName = variant === "accounting" ? "accounting-overview-profit-and-loss-chart" : "bookkeeping-overview-profit-and-loss-chart";
44121
+ const chartsWrapperClassName = variant === "accounting" ? "Layer__AccountingOverview__ProfitAndLossCharts" : "Layer__BookkeepingOverview__ProfitAndLossCharts";
44122
+ const chartContainerName = variant === "accounting" ? "AccountingOverview__ProfitAndLossChart" : "BookkeepingOverview__ProfitAndLossChart";
44111
44123
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(VStack, {
44112
44124
  className: chartsWrapperClassName,
44113
44125
  gap: "md",
@@ -44148,6 +44160,49 @@ var ProfitAndLossOverviewDetailedCharts = ({ variant, detailedChartsStringOverri
44148
44160
  });
44149
44161
  };
44150
44162
  //#endregion
44163
+ //#region src/components/ProfitAndLossSummaryCard/PnlLegend.tsx
44164
+ var Swatch$1 = ({ className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
44165
+ className: `Layer__PnlLegend__Swatch ${className}`,
44166
+ "aria-hidden": true
44167
+ });
44168
+ var PnlLegend = ({ direction = "row" }) => {
44169
+ const { t } = (0, react_i18next.useTranslation)();
44170
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Stack, {
44171
+ className: "Layer__PnlLegend",
44172
+ direction,
44173
+ align: "start",
44174
+ gap: direction === "row" ? "md" : "2xs",
44175
+ pis: direction === "column" ? "md" : void 0,
44176
+ pbe: direction === "column" ? "md" : void 0,
44177
+ children: [
44178
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
44179
+ gap: "2xs",
44180
+ align: "center",
44181
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Swatch$1, { className: "Layer__PnlLegend__Swatch--income" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
44182
+ size: "sm",
44183
+ children: t("common:label.revenue", "Revenue")
44184
+ })]
44185
+ }),
44186
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
44187
+ gap: "2xs",
44188
+ align: "center",
44189
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Swatch$1, { className: "Layer__PnlLegend__Swatch--expenses" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
44190
+ size: "sm",
44191
+ children: t("common:label.expenses", "Expenses")
44192
+ })]
44193
+ }),
44194
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
44195
+ gap: "2xs",
44196
+ align: "center",
44197
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Swatch$1, { className: "Layer__PnlLegend__Swatch--uncategorized" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
44198
+ size: "sm",
44199
+ children: t("common:label.uncategorized", "Uncategorized")
44200
+ })]
44201
+ })
44202
+ ]
44203
+ });
44204
+ };
44205
+ //#endregion
44151
44206
  //#region src/views/AccountingOverview/AccountingOverview.tsx
44152
44207
  var AccountingOverview = ({ title, showTitle = true, enableOnboarding = false, onboardingStepOverride = void 0, onTransactionsToReviewClick, middleBanner, chartColorsList, stringOverrides, tagFilter = void 0, slotProps }) => {
44153
44208
  var _slotProps$profitAndL, _stringOverrides$prof, _stringOverrides$prof2;
@@ -44162,6 +44217,7 @@ var AccountingOverview = ({ title, showTitle = true, enableOnboarding = false, o
44162
44217
  } : void 0,
44163
44218
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(View, {
44164
44219
  title: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.title) || title || t("overview:label.accounting_overview", "Accounting overview"),
44220
+ viewClassName: "Layer__AccountingOverview",
44165
44221
  showHeader: showTitle,
44166
44222
  header: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header$1, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderRow, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderCol, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalMonthPicker, { truncateMonth: sizeClass === "mobile" }) }) }) }),
44167
44223
  children: [
@@ -44177,11 +44233,19 @@ var AccountingOverview = ({ title, showTitle = true, enableOnboarding = false, o
44177
44233
  }),
44178
44234
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Container, {
44179
44235
  name: "accounting-overview-profit-and-loss",
44236
+ className: "Layer__AccountingOverview__ProfitAndLossContainer",
44180
44237
  asWidget: true,
44181
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLoss.Header, { text: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.header) || t("common:label.profit_loss", "Profit & Loss") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLoss.Chart, { tagFilter: tagFilter ? {
44182
- key: tagFilter.tagKey,
44183
- values: tagFilter.tagValues
44184
- } : void 0 })]
44238
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLoss.Header, {
44239
+ text: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.header) || t("common:label.profit_loss", "Profit & Loss"),
44240
+ className: "Layer__AccountingOverview__ProfitAndLossHeader",
44241
+ trailingContent: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PnlLegend, { direction: "row" })
44242
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLoss.Chart, {
44243
+ tagFilter: tagFilter ? {
44244
+ key: tagFilter.tagKey,
44245
+ values: tagFilter.tagValues
44246
+ } : void 0,
44247
+ hideLegend: true
44248
+ })]
44185
44249
  }),
44186
44250
  middleBanner && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Container, {
44187
44251
  name: "accounting-overview-middle-banner",
@@ -44684,7 +44748,7 @@ var BookkeepingOverview = ({ title, showTitle = true, onClickReconnectAccounts,
44684
44748
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ProfitAndLoss, {
44685
44749
  asContainer: false,
44686
44750
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(View, {
44687
- viewClassName: "Layer__bookkeeping-overview--view",
44751
+ viewClassName: "Layer__bookkeeping-overview--view Layer__BookkeepingOverview",
44688
44752
  title: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.title) || title || t("overview:label.bookkeeping_overview", "Bookkeeping overview"),
44689
44753
  header: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header$1, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderRow, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderCol, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalMonthPicker, { truncateMonth: sizeClass === "mobile" }) }) }) }),
44690
44754
  withSidebar: width > 1100,
@@ -44721,6 +44785,7 @@ var BookkeepingOverview = ({ title, showTitle = true, onClickReconnectAccounts,
44721
44785
  onClick: () => upperElementInFocus.current = false,
44722
44786
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Container, {
44723
44787
  name: "bookkeeping-overview-profit-and-loss",
44788
+ className: "Layer__BookkeepingOverview__ProfitAndLossContainer",
44724
44789
  asWidget: true,
44725
44790
  style: {
44726
44791
  position: "relative",
@@ -44729,7 +44794,8 @@ var BookkeepingOverview = ({ title, showTitle = true, onClickReconnectAccounts,
44729
44794
  children: [
44730
44795
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLoss.Header, {
44731
44796
  text: (stringOverrides === null || stringOverrides === void 0 || (_stringOverrides$prof = stringOverrides.profitAndLoss) === null || _stringOverrides$prof === void 0 ? void 0 : _stringOverrides$prof.header) || t("common:label.profit_loss", "Profit & Loss"),
44732
- withStatus: true
44797
+ withStatus: true,
44798
+ trailingContent: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PnlLegend, { direction: "row" })
44733
44799
  }),
44734
44800
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VStack, {
44735
44801
  pb: "md",
@@ -44740,7 +44806,7 @@ var BookkeepingOverview = ({ title, showTitle = true, onClickReconnectAccounts,
44740
44806
  variants: profitAndLossSummariesVariants
44741
44807
  })
44742
44808
  }),
44743
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLoss.Chart, {})
44809
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProfitAndLoss.Chart, { hideLegend: true })
44744
44810
  ]
44745
44811
  })
44746
44812
  }),
@@ -46852,11 +46918,13 @@ var SummaryCard = ({ slots, children, className }) => {
46852
46918
  });
46853
46919
  };
46854
46920
  //#endregion
46855
- //#region src/hooks/utils/i18n/useGlobalMonthSubtitle.ts
46856
- var useGlobalMonthSubtitle = () => {
46921
+ //#region src/hooks/utils/i18n/useGlobalDateFormatter.ts
46922
+ var useGlobalDateFormatter = () => {
46857
46923
  const { formatDate } = useIntlFormatter();
46858
- const { date } = useGlobalDate({ dateSelectionMode: "month" });
46859
- return formatDate(date, MonthYearPattern.MonthYear);
46924
+ const { date } = useGlobalDate();
46925
+ return (0, react.useCallback)((format) => {
46926
+ return formatDate(date, format);
46927
+ }, [date, formatDate]);
46860
46928
  };
46861
46929
  //#endregion
46862
46930
  //#region src/components/ui/SummaryCard/ExpandSummaryCardButton.tsx
@@ -46871,9 +46939,9 @@ function ExpandSummaryCardButton({ callback, ariaLabel }) {
46871
46939
  }
46872
46940
  //#endregion
46873
46941
  //#region src/components/ui/SummaryCard/useSummaryCardSlots.tsx
46874
- var useSummaryCardSlots = ({ defaultTitle, legend, interactionProps, stringOverrides }) => {
46942
+ var useSummaryCardSlots = ({ defaultTitle, legend, interactionProps, subtitleDateFormat = DateFormat.MonthYear, stringOverrides }) => {
46875
46943
  const { t } = (0, react_i18next.useTranslation)();
46876
- const subtitle = useGlobalMonthSubtitle();
46944
+ const formatGlobalDate = useGlobalDateFormatter();
46877
46945
  const { onClickExpand } = interactionProps !== null && interactionProps !== void 0 ? interactionProps : {};
46878
46946
  return (0, react.useMemo)(() => {
46879
46947
  var _stringOverrides$titl;
@@ -46883,14 +46951,15 @@ var useSummaryCardSlots = ({ defaultTitle, legend, interactionProps, stringOverr
46883
46951
  }) : void 0;
46884
46952
  return {
46885
46953
  title: (_stringOverrides$titl = stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.title) !== null && _stringOverrides$titl !== void 0 ? _stringOverrides$titl : defaultTitle,
46886
- subtitle,
46954
+ subtitle: formatGlobalDate(subtitleDateFormat),
46887
46955
  legend,
46888
46956
  primaryAction
46889
46957
  };
46890
46958
  }, [
46891
46959
  stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.title,
46892
46960
  defaultTitle,
46893
- subtitle,
46961
+ subtitleDateFormat,
46962
+ formatGlobalDate,
46894
46963
  legend,
46895
46964
  onClickExpand,
46896
46965
  t
@@ -47005,55 +47074,13 @@ var MileageTrackingSummary = ({ stringOverrides, interactionProps } = {}) => {
47005
47074
  slots: useSummaryCardSlots({
47006
47075
  defaultTitle: t("mileageTracking:label.mileage_tracking", "Mileage Tracking"),
47007
47076
  interactionProps,
47008
- stringOverrides
47077
+ stringOverrides,
47078
+ subtitleDateFormat: DateFormat.Year
47009
47079
  }),
47010
47080
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Content$1, {})
47011
47081
  });
47012
47082
  };
47013
47083
  //#endregion
47014
- //#region src/components/ProfitAndLossSummaryCard/PnlLegend.tsx
47015
- var Swatch$1 = ({ className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
47016
- className: `Layer__PnlLegend__Swatch ${className}`,
47017
- "aria-hidden": true
47018
- });
47019
- var PnlLegend = ({ direction = "row" }) => {
47020
- const { t } = (0, react_i18next.useTranslation)();
47021
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Stack, {
47022
- className: "Layer__PnlLegend",
47023
- direction,
47024
- align: "start",
47025
- gap: direction === "row" ? "md" : "2xs",
47026
- pis: direction === "column" ? "md" : void 0,
47027
- pbe: direction === "column" ? "md" : void 0,
47028
- children: [
47029
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
47030
- gap: "2xs",
47031
- align: "center",
47032
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Swatch$1, { className: "Layer__PnlLegend__Swatch--income" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
47033
- size: "sm",
47034
- children: t("common:label.revenue", "Revenue")
47035
- })]
47036
- }),
47037
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
47038
- gap: "2xs",
47039
- align: "center",
47040
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Swatch$1, { className: "Layer__PnlLegend__Swatch--expenses" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
47041
- size: "sm",
47042
- children: t("common:label.expenses", "Expenses")
47043
- })]
47044
- }),
47045
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
47046
- gap: "2xs",
47047
- align: "center",
47048
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Swatch$1, { className: "Layer__PnlLegend__Swatch--uncategorized" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
47049
- size: "sm",
47050
- children: t("common:label.uncategorized", "Uncategorized")
47051
- })]
47052
- })
47053
- ]
47054
- });
47055
- };
47056
- //#endregion
47057
47084
  //#region src/components/ProfitAndLossSummaryCard/ProfitAndLossSummaryCard.tsx
47058
47085
  var ProfitAndLossSummaryCard = ({ interactionProps, stringOverrides, className }) => {
47059
47086
  const { t } = (0, react_i18next.useTranslation)();
@@ -47235,33 +47262,39 @@ var getOnboardingBannerState = ({ isLoading, hasLinkedAccounts, hasSavedTaxProfi
47235
47262
  var NoBankAccountsLinkedBanner = () => {
47236
47263
  const { addConnection } = (0, react.useContext)(LinkedAccountsContext);
47237
47264
  const { isMobile } = useSizeClass();
47265
+ const { t } = (0, react_i18next.useTranslation)();
47238
47266
  const handleLinkBankAccounts = (0, react.useCallback)(() => {
47239
47267
  addConnection("PLAID");
47240
47268
  }, [addConnection]);
47269
+ const Icon = isMobile ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Info, { size: 16 });
47270
+ const title = t("linkedAccounts:label.link_your_bank_accounts", "Link your bank accounts");
47241
47271
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Banner, {
47242
- title: "Link your bank accounts",
47243
- description: "Linking your bank accounts allows us to load your bank transactions and automatically categorize them.",
47272
+ title,
47273
+ description: t("linkedAccounts:label.link_your_bank_accounts_description", "Linking your bank accounts allows us to load your bank transactions and automatically categorize them."),
47244
47274
  slots: {
47245
- Icon: isMobile ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Info, { size: 16 }),
47275
+ Icon,
47246
47276
  Button: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button$1, {
47247
47277
  onPress: handleLinkBankAccounts,
47248
47278
  variant: "outlined-light",
47249
- children: "Link your bank accounts"
47279
+ children: title
47250
47280
  })
47251
47281
  }
47252
47282
  });
47253
47283
  };
47254
47284
  var NoTaxProfileBanner = ({ onSetupTaxProfile }) => {
47255
47285
  const { isMobile } = useSizeClass();
47286
+ const { t } = (0, react_i18next.useTranslation)();
47287
+ const Icon = isMobile ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Info, { size: 16 });
47288
+ const title = t("linkedAccounts:label.setup_your_tax_profile", "Set up your tax profile");
47256
47289
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Banner, {
47257
- title: "Set up your tax profile",
47258
- description: "Configuring your tax profile allows us to provide you with tax estimates and avoid any surprises come tax time.",
47290
+ title,
47291
+ description: t("linkedAccounts:label.setup_your_tax_profile_description", "Configuring your tax profile allows us to provide you with tax estimates and avoid any surprises come tax time."),
47259
47292
  slots: {
47260
- Icon: isMobile ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Info, { size: 16 }),
47293
+ Icon,
47261
47294
  Button: onSetupTaxProfile ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button$1, {
47262
47295
  onPress: onSetupTaxProfile,
47263
47296
  variant: "outlined-light",
47264
- children: "Setup your tax profile"
47297
+ children: title
47265
47298
  }) : null
47266
47299
  }
47267
47300
  });
@@ -47879,7 +47912,8 @@ var TaxEstimatesSummaryCard = ({ mode = TaxEstimatesSummaryCardMode.PieChart, in
47879
47912
  const slots = useSummaryCardSlots({
47880
47913
  defaultTitle,
47881
47914
  interactionProps,
47882
- stringOverrides
47915
+ stringOverrides,
47916
+ subtitleDateFormat: DateFormat.Year
47883
47917
  });
47884
47918
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SummaryCard, {
47885
47919
  className: (0, classnames.default)("Layer__TaxEstimatesSummaryCard", isSummaryCardLayout && "Layer__TaxEstimatesSummaryCard--summaryCard"),
@@ -48351,11 +48385,11 @@ var taxDetailsRowFields = {
48351
48385
  var TaxDetailsRowSchema = effect.Schema.Struct(_objectSpread2(_objectSpread2({}, taxDetailsRowFields), {}, { breakdown: effect.Schema.optional(effect.Schema.Array(effect.Schema.suspend(() => TaxDetailsRowSchema))) }));
48352
48386
  var TaxDetailsMetaSchema = effect.Schema.Struct({
48353
48387
  year: effect.Schema.Number,
48388
+ state: TransformedTaxSummaryStateSchema,
48354
48389
  filingStatus: (0, effect.pipe)(effect.Schema.propertySignature(effect.Schema.String), effect.Schema.fromKey("filing_status"))
48355
48390
  });
48356
48391
  var TaxDetailsSchema = effect.Schema.Struct({
48357
48392
  type: effect.Schema.String,
48358
- state: TransformedTaxSummaryStateSchema,
48359
48393
  meta: TaxDetailsMetaSchema,
48360
48394
  rows: effect.Schema.Array(TaxDetailsRowSchema)
48361
48395
  });