gsintegrations 0.0.494 → 0.0.496

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.
@@ -59729,7 +59729,7 @@ var ReceiptIcon = createSvgIcon( /*#__PURE__*/require$$2$1.jsx("path", {
59729
59729
  d: "M18 17H6v-2h12zm0-4H6v-2h12zm0-4H6V7h12zM3 22l1.5-1.5L6 22l1.5-1.5L9 22l1.5-1.5L12 22l1.5-1.5L15 22l1.5-1.5L18 22l1.5-1.5L21 22V2l-1.5 1.5L18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2 4.5 3.5 3 2z"
59730
59730
  }), 'Receipt');
59731
59731
 
59732
- var ReceiptLongIcon = createSvgIcon([/*#__PURE__*/require$$2$1.jsx("path", {
59732
+ var ReceiptLong = createSvgIcon([/*#__PURE__*/require$$2$1.jsx("path", {
59733
59733
  d: "M19.5 3.5 18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2v14H3v3c0 1.66 1.34 3 3 3h12c1.66 0 3-1.34 3-3V2zM19 19c0 .55-.45 1-1 1s-1-.45-1-1v-3H8V5h11z"
59734
59734
  }, "0"), /*#__PURE__*/require$$2$1.jsx("path", {
59735
59735
  d: "M9 7h6v2H9zm7 0h2v2h-2zm-7 3h6v2H9zm7 0h2v2h-2z"
@@ -59747,10 +59747,6 @@ var Save$1 = createSvgIcon( /*#__PURE__*/require$$2$1.jsx("path", {
59747
59747
  d: "M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3m3-10H5V5h10z"
59748
59748
  }), 'Save');
59749
59749
 
59750
- var SavingsIcon = createSvgIcon( /*#__PURE__*/require$$2$1.jsx("path", {
59751
- d: "m19.83 7.5-2.27-2.27c.07-.42.18-.81.32-1.15.08-.18.12-.37.12-.58 0-.83-.67-1.5-1.5-1.5-1.64 0-3.09.79-4 2h-5C4.46 4 2 6.46 2 9.5S4.5 21 4.5 21H10v-2h2v2h5.5l1.68-5.59 2.82-.94V7.5zM13 9H8V7h5zm3 2c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1"
59752
- }), 'Savings');
59753
-
59754
59750
  var Schedule = createSvgIcon([/*#__PURE__*/require$$2$1.jsx("path", {
59755
59751
  d: "M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8"
59756
59752
  }, "0"), /*#__PURE__*/require$$2$1.jsx("path", {
@@ -144524,8 +144520,53 @@ const parseMonthValue = (value) => {
144524
144520
  return new Date(year, month - 1, 1);
144525
144521
  };
144526
144522
  const toMonthValue = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
144527
- const FinancialSummaryHeader = ({ embedded = false, variant = "balance", balanceLabel, isLoading = false, periodLabel, periodInputValue, periodInputMin, periodInputMax, onPeriodInputChange, detailLines = [], onEdit, onAdd, addLabel = "Adicionar", addQuotaFeature, canExport = false, isExporting = false, onExport, }) => {
144528
- var _a, _b;
144523
+ const MovementTotalButton = ({ kind, label, amount, selected, color, compact, onSelect, }) => (React$1.createElement(Box$1, { component: "button", type: "button", "aria-pressed": selected, "aria-label": label, "data-testid": kind === "income" ? "financial-movement-income" : "financial-movement-outcome", onClick: () => onSelect(kind), sx: {
144524
+ flex: 1,
144525
+ minWidth: 0,
144526
+ minHeight: 44,
144527
+ display: "flex",
144528
+ alignItems: "center",
144529
+ gap: 1,
144530
+ px: 1.25,
144531
+ py: compact ? 0.5 : 1,
144532
+ border: 0,
144533
+ borderRadius: 1.5,
144534
+ cursor: "pointer",
144535
+ textAlign: "left",
144536
+ color: "secondary.contrastText",
144537
+ bgcolor: selected ? color : alpha(color, 0.45),
144538
+ "&:hover": {
144539
+ bgcolor: selected ? color : alpha(color, 0.62),
144540
+ },
144541
+ "&:focus-visible": {
144542
+ outline: "2px solid",
144543
+ outlineColor: "secondary.contrastText",
144544
+ outlineOffset: 2,
144545
+ },
144546
+ } },
144547
+ React$1.createElement(Box$1, { "aria-hidden": true, sx: {
144548
+ width: 28,
144549
+ height: 28,
144550
+ borderRadius: "50%",
144551
+ bgcolor: "rgba(255,255,255,0.2)",
144552
+ display: "flex",
144553
+ alignItems: "center",
144554
+ justifyContent: "center",
144555
+ flexShrink: 0,
144556
+ } }, kind === "income" ? (React$1.createElement(ArrowUpward, { fontSize: "small" })) : (React$1.createElement(ArrowDownward, { fontSize: "small" }))),
144557
+ React$1.createElement(Box$1, { sx: { minWidth: 0 } },
144558
+ compact ? null : (React$1.createElement(Typography$1, { variant: "caption", sx: { display: "block", lineHeight: 1.2, opacity: 0.92 } }, label)),
144559
+ React$1.createElement(Typography$1, { component: "span", "data-testid": kind === "income" ? "financial-income-total" : "financial-outcome-total", sx: {
144560
+ display: "block",
144561
+ fontWeight: 700,
144562
+ fontSize: compact ? "0.875rem" : "1rem",
144563
+ lineHeight: 1.2,
144564
+ whiteSpace: "nowrap",
144565
+ overflow: "hidden",
144566
+ textOverflow: "ellipsis",
144567
+ } }, amount))));
144568
+ const FinancialSummaryHeader = ({ embedded = false, variant = "balance", balanceLabel, movementKind = "income", incomeTotalLabel, outcomeTotalLabel, onMovementKindChange, isLoading = false, periodLabel, periodInputValue, periodInputMin, periodInputMax, onPeriodInputChange, detailLines = [], onEdit, onAdd, addLabel = "Adicionar", addQuotaFeature, canExport = false, isExporting = false, onExport, }) => {
144569
+ var _a, _b, _c, _d;
144529
144570
  const theme = useTheme$1();
144530
144571
  const periodButtonRef = React$1.useRef(null);
144531
144572
  const heroRef = React$1.useRef(null);
@@ -144576,7 +144617,14 @@ const FinancialSummaryHeader = ({ embedded = false, variant = "balance", balance
144576
144617
  const node = heroRef.current;
144577
144618
  if (!node)
144578
144619
  return;
144579
- const measure = () => setSpacerHeight(node.offsetHeight);
144620
+ const measure = () => {
144621
+ const spacer = node.nextElementSibling;
144622
+ const spacerDocTop = spacer
144623
+ ? spacer.getBoundingClientRect().top + window.scrollY
144624
+ : 0;
144625
+ const nextHeight = Math.max(0, Math.round(node.offsetHeight - spacerDocTop));
144626
+ setSpacerHeight(nextHeight);
144627
+ };
144580
144628
  const observer = new ResizeObserver(measure);
144581
144629
  observer.observe(node);
144582
144630
  measure();
@@ -144587,11 +144635,16 @@ const FinancialSummaryHeader = ({ embedded = false, variant = "balance", balance
144587
144635
  const showAdd = Boolean(onAdd);
144588
144636
  const showPeriod = Boolean(onPeriodInputChange);
144589
144637
  const isMonthlyFee = variant === "monthlyFee";
144638
+ const showMovementSwitch = variant === "movements" && Boolean(onMovementKindChange);
144639
+ const incomeAmount = incomeTotalLabel !== null && incomeTotalLabel !== void 0 ? incomeTotalLabel : (movementKind === "income" ? balanceLabel : "R$ 0,00");
144640
+ const outcomeAmount = outcomeTotalLabel !== null && outcomeTotalLabel !== void 0 ? outcomeTotalLabel : (movementKind === "outcome" ? balanceLabel : "R$ 0,00");
144590
144641
  const overline = variant === "monthlyFee"
144591
144642
  ? "Mensalidade"
144592
144643
  : variant === "movements"
144593
144644
  ? "Lançamentos"
144594
- : "Resumo Financeiro";
144645
+ : variant === "accounts"
144646
+ ? "Contas"
144647
+ : "Resumo Financeiro";
144595
144648
  const periodDate = parseMonthValue(periodInputValue);
144596
144649
  return (React$1.createElement(LocalizationProvider, { dateAdapter: AdapterDateFns, adapterLocale: ptBR$1, localeText: ptBR.components.MuiLocalizationProvider.defaultProps.localeText },
144597
144650
  React$1.createElement(Box$1, { ref: heroRef, "data-testid": "financial-dashboard-hero", "data-collapsed": isExpanded ? "false" : "true", sx: {
@@ -144620,9 +144673,8 @@ const FinancialSummaryHeader = ({ embedded = false, variant = "balance", balance
144620
144673
  } },
144621
144674
  React$1.createElement(Box$1, { "data-testid": "financial-dashboard-hero-content", sx: {
144622
144675
  display: "flex",
144623
- justifyContent: "space-between",
144624
- gap: 2,
144625
- alignItems: isExpanded ? "flex-start" : "center",
144676
+ flexDirection: "column",
144677
+ gap: showMovementSwitch ? 1.5 : 0,
144626
144678
  width: "100%",
144627
144679
  maxWidth: theme.breakpoints.values.md,
144628
144680
  mx: "auto",
@@ -144630,69 +144682,79 @@ const FinancialSummaryHeader = ({ embedded = false, variant = "balance", balance
144630
144682
  px: PAGE_LIST_CONTAINER_SPACING.px,
144631
144683
  pl: embedded ? { xs: 7, md: 2 } : undefined,
144632
144684
  } },
144633
- React$1.createElement(Box$1, { sx: { flex: 1, minWidth: 0 } },
144634
- React$1.createElement(Collapse$1, { in: isExpanded, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard },
144635
- React$1.createElement(Typography$1, { variant: "overline", sx: { opacity: 0.8, letterSpacing: "0.08em" } }, overline),
144636
- variant === "balance" ? (React$1.createElement(Typography$1, { variant: "body2", sx: { opacity: 0.9, mt: 1 } }, "Saldo da casa")) : null),
144637
- isLoading ? (React$1.createElement(Skeleton$1, { width: isExpanded ? 180 : 120, height: isExpanded ? 48 : 28, sx: { bgcolor: "rgba(255,255,255,0.16)", my: 0.5 } })) : (React$1.createElement(Typography$1, { component: "p", "data-testid": "financial-dashboard-balance", sx: {
144638
- fontSize: isExpanded ? { xs: "2rem", sm: "2.5rem" } : "1.125rem",
144639
- fontWeight: 700,
144640
- lineHeight: 1.15,
144641
- letterSpacing: "-0.03em",
144642
- my: isExpanded ? 0.5 : 0,
144643
- transition: `font-size ${ANIMATION_DURATION.normal}ms ${ANIMATION_EASING.standard}`,
144644
- } }, balanceLabel)),
144645
- isMonthlyFee && detailLines.length > 0 ? (React$1.createElement(Collapse$1, { in: isExpanded, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard },
144646
- React$1.createElement(Stack$1, { spacing: 1, sx: { mt: 1.5 } }, detailLines.map((line) => (React$1.createElement(Box$1, { key: line.label },
144647
- React$1.createElement(Typography$1, { variant: "caption", sx: { opacity: 0.75 } }, line.label),
144648
- React$1.createElement(Typography$1, { variant: "body2", sx: { fontWeight: 600 } }, line.value))))))) : null,
144649
- periodLabel ? (React$1.createElement(Typography$1, { variant: "body2", "data-testid": "financial-period-label", sx: { opacity: isExpanded ? 1 : 0.85 } }, periodLabel)) : null),
144650
- showPeriod || showExport || showEdit || showAdd ? (React$1.createElement(Stack$1, { spacing: 2, alignItems: "center", sx: { flexShrink: 0, ml: "auto" } },
144651
- showPeriod ? (React$1.createElement(React$1.Fragment, null,
144652
- React$1.createElement(IconButton$1, { ref: periodButtonRef, type: "button", "aria-label": "Selecionar per\u00EDodo", "data-testid": "financial-period-button", onClick: openPeriodPicker, sx: {
144653
- width: 44,
144654
- height: 44,
144655
- color: "secondary.contrastText",
144656
- bgcolor: "rgba(255,255,255,0.12)",
144657
- "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144658
- } },
144659
- React$1.createElement(CalendarMonth$1, null)),
144660
- React$1.createElement(Popover$1, { open: periodPickerOpen, anchorEl: periodButtonRef.current, onClose: () => setPeriodPickerOpen(false), anchorOrigin: { vertical: "bottom", horizontal: "right" }, transformOrigin: { vertical: "top", horizontal: "right" } },
144661
- React$1.createElement(DateCalendar, { views: ["year", "month"], openTo: "month", value: periodDate, minDate: (_a = parseMonthValue(periodInputMin || "2000-01")) !== null && _a !== void 0 ? _a : undefined, maxDate: (_b = parseMonthValue(periodInputMax || "2100-12")) !== null && _b !== void 0 ? _b : undefined, onChange: selectPeriod, "data-testid": "financial-period-calendar" })))) : null,
144662
- React$1.createElement(Collapse$1, { in: isExpanded && showAdd, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard, unmountOnExit: true }, addQuotaFeature ? (React$1.createElement(QuotaGuard, { feature: addQuotaFeature, behavior: "hide" },
144663
- React$1.createElement(IconButton$1, { type: "button", "aria-label": addLabel, onClick: onAdd, "data-testid": "financial-summary-add", sx: {
144664
- width: 44,
144665
- height: 44,
144666
- color: "secondary.contrastText",
144667
- bgcolor: "rgba(255,255,255,0.12)",
144668
- "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144669
- } },
144670
- React$1.createElement(Add$1, null)))) : (React$1.createElement(IconButton$1, { type: "button", "aria-label": addLabel, onClick: onAdd, "data-testid": "financial-summary-add", sx: {
144671
- width: 44,
144672
- height: 44,
144673
- color: "secondary.contrastText",
144674
- bgcolor: "rgba(255,255,255,0.12)",
144675
- "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144676
- } },
144677
- React$1.createElement(Add$1, null)))),
144678
- React$1.createElement(Collapse$1, { in: isExpanded && showEdit, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard, unmountOnExit: true },
144679
- React$1.createElement(IconButton$1, { type: "button", "aria-label": "Editar mensalidade", onClick: onEdit, "data-testid": "financial-monthly-fee-edit", sx: {
144680
- width: 44,
144681
- height: 44,
144682
- color: "secondary.contrastText",
144683
- bgcolor: "rgba(255,255,255,0.12)",
144684
- "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144685
- } },
144686
- React$1.createElement(EditIcon, null))),
144687
- React$1.createElement(Collapse$1, { in: isExpanded && showExport, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard, unmountOnExit: true },
144688
- React$1.createElement(IconButton$1, { "aria-label": isExporting ? "Exportando relatório" : "Exportar relatório", onClick: onExport, disabled: isExporting, "data-testid": "financial-report-export-button", sx: {
144685
+ React$1.createElement(Box$1, { sx: {
144686
+ display: "flex",
144687
+ justifyContent: "space-between",
144688
+ gap: 2,
144689
+ alignItems: isExpanded ? "flex-start" : "center",
144690
+ width: "100%",
144691
+ } },
144692
+ React$1.createElement(Box$1, { sx: { flex: 1, minWidth: 0 } },
144693
+ React$1.createElement(Collapse$1, { in: isExpanded, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard },
144694
+ React$1.createElement(Typography$1, { variant: "overline", sx: { opacity: 0.8, letterSpacing: "0.08em" } }, overline),
144695
+ variant === "balance" || variant === "accounts" ? (React$1.createElement(Typography$1, { variant: "body2", sx: { opacity: 0.9, mt: 1 } }, variant === "accounts" ? "Saldo das contas" : "Saldo da casa")) : null),
144696
+ showMovementSwitch ? null : isLoading ? (React$1.createElement(Skeleton$1, { width: isExpanded ? 180 : 120, height: isExpanded ? 48 : 28, sx: { bgcolor: "rgba(255,255,255,0.16)", my: 0.5 } })) : (React$1.createElement(Typography$1, { component: "p", "data-testid": "financial-dashboard-balance", sx: {
144697
+ fontSize: isExpanded ? { xs: "2rem", sm: "2.5rem" } : "1.125rem",
144698
+ fontWeight: 700,
144699
+ lineHeight: 1.15,
144700
+ letterSpacing: "-0.03em",
144701
+ my: isExpanded ? 0.5 : 0,
144702
+ transition: `font-size ${ANIMATION_DURATION.normal}ms ${ANIMATION_EASING.standard}`,
144703
+ } }, balanceLabel)),
144704
+ isMonthlyFee && detailLines.length > 0 ? (React$1.createElement(Collapse$1, { in: isExpanded, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard },
144705
+ React$1.createElement(Stack$1, { spacing: 1, sx: { mt: 1.5 } }, detailLines.map((line) => (React$1.createElement(Box$1, { key: line.label },
144706
+ React$1.createElement(Typography$1, { variant: "caption", sx: { opacity: 0.75 } }, line.label),
144707
+ React$1.createElement(Typography$1, { variant: "body2", sx: { fontWeight: 600 } }, line.value))))))) : null,
144708
+ periodLabel ? (React$1.createElement(Typography$1, { variant: "body2", "data-testid": "financial-period-label", sx: { opacity: isExpanded ? 1 : 0.85 } }, periodLabel)) : null),
144709
+ showPeriod || showExport || showEdit || showAdd ? (React$1.createElement(Stack$1, { spacing: 2, alignItems: "center", sx: { flexShrink: 0, ml: "auto" } },
144710
+ showPeriod ? (React$1.createElement(React$1.Fragment, null,
144711
+ React$1.createElement(IconButton$1, { ref: periodButtonRef, type: "button", "aria-label": "Selecionar per\u00EDodo", "data-testid": "financial-period-button", onClick: openPeriodPicker, sx: {
144712
+ width: 44,
144713
+ height: 44,
144714
+ color: "secondary.contrastText",
144715
+ bgcolor: "rgba(255,255,255,0.12)",
144716
+ "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144717
+ } },
144718
+ React$1.createElement(CalendarMonth$1, null)),
144719
+ React$1.createElement(Popover$1, { open: periodPickerOpen, anchorEl: periodButtonRef.current, onClose: () => setPeriodPickerOpen(false), anchorOrigin: { vertical: "bottom", horizontal: "right" }, transformOrigin: { vertical: "top", horizontal: "right" } },
144720
+ React$1.createElement(DateCalendar, { views: ["year", "month"], openTo: "month", value: periodDate, minDate: (_a = parseMonthValue(periodInputMin || "2000-01")) !== null && _a !== void 0 ? _a : undefined, maxDate: (_b = parseMonthValue(periodInputMax || "2100-12")) !== null && _b !== void 0 ? _b : undefined, onChange: selectPeriod, "data-testid": "financial-period-calendar" })))) : null,
144721
+ React$1.createElement(Collapse$1, { in: isExpanded && showAdd, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard, unmountOnExit: true }, addQuotaFeature ? (React$1.createElement(QuotaGuard, { feature: addQuotaFeature, behavior: "hide" },
144722
+ React$1.createElement(IconButton$1, { type: "button", "aria-label": addLabel, onClick: onAdd, "data-testid": "financial-summary-add", sx: {
144723
+ width: 44,
144724
+ height: 44,
144725
+ color: "secondary.contrastText",
144726
+ bgcolor: "rgba(255,255,255,0.12)",
144727
+ "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144728
+ } },
144729
+ React$1.createElement(Add$1, null)))) : (React$1.createElement(IconButton$1, { type: "button", "aria-label": addLabel, onClick: onAdd, "data-testid": "financial-summary-add", sx: {
144689
144730
  width: 44,
144690
144731
  height: 44,
144691
144732
  color: "secondary.contrastText",
144692
144733
  bgcolor: "rgba(255,255,255,0.12)",
144693
144734
  "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144694
144735
  } },
144695
- React$1.createElement(FileDownloadIcon, null))))) : null)),
144736
+ React$1.createElement(Add$1, null)))),
144737
+ React$1.createElement(Collapse$1, { in: isExpanded && showEdit, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard, unmountOnExit: true },
144738
+ React$1.createElement(IconButton$1, { type: "button", "aria-label": "Editar mensalidade", onClick: onEdit, "data-testid": "financial-monthly-fee-edit", sx: {
144739
+ width: 44,
144740
+ height: 44,
144741
+ color: "secondary.contrastText",
144742
+ bgcolor: "rgba(255,255,255,0.12)",
144743
+ "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144744
+ } },
144745
+ React$1.createElement(EditIcon, null))),
144746
+ React$1.createElement(Collapse$1, { in: isExpanded && showExport, timeout: ANIMATION_DURATION.normal, easing: ANIMATION_EASING.standard, unmountOnExit: true },
144747
+ React$1.createElement(IconButton$1, { "aria-label": isExporting ? "Exportando relatório" : "Exportar relatório", onClick: onExport, disabled: isExporting, "data-testid": "financial-report-export-button", sx: {
144748
+ width: 44,
144749
+ height: 44,
144750
+ color: "secondary.contrastText",
144751
+ bgcolor: "rgba(255,255,255,0.12)",
144752
+ "&:hover": { bgcolor: "rgba(255,255,255,0.2)" },
144753
+ } },
144754
+ React$1.createElement(FileDownloadIcon, null))))) : null),
144755
+ showMovementSwitch && onMovementKindChange ? (React$1.createElement(Box$1, { sx: { display: "flex", gap: 1, width: "100%" } },
144756
+ React$1.createElement(MovementTotalButton, { kind: "income", label: "Contribui\u00E7\u00F5es", amount: incomeAmount, selected: movementKind === "income", color: (_d = (_c = theme.brand) === null || _c === void 0 ? void 0 : _c.green) !== null && _d !== void 0 ? _d : "#6F8C3A", compact: !isExpanded, onSelect: onMovementKindChange }),
144757
+ React$1.createElement(MovementTotalButton, { kind: "outcome", label: "Gastos", amount: outcomeAmount, selected: movementKind === "outcome", color: theme.palette.error.main, compact: !isExpanded, onSelect: onMovementKindChange }))) : null)),
144696
144758
  React$1.createElement(Box$1, { sx: { height: spacerHeight } })));
144697
144759
  };
144698
144760
 
@@ -145928,7 +145990,7 @@ const FinancialBottomNav = ({ audience, activeTab, showMensalidade = false, onNa
145928
145990
  id: "movements",
145929
145991
  label: "Lançamentos",
145930
145992
  testId: "financial-nav-movements",
145931
- icon: React$1.createElement(ReceiptLongIcon, null),
145993
+ icon: React$1.createElement(ReceiptLong, null),
145932
145994
  onClick: onNavigateMovements,
145933
145995
  },
145934
145996
  {
@@ -146030,65 +146092,97 @@ const FinancialAppShell = ({ audience, activeTab, showBottomNav = true, showMens
146030
146092
  showBottomNav ? (React$1.createElement(FinancialBottomNav, { audience: audience, activeTab: activeTab, showMensalidade: showMensalidade, onNavigateHome: onNavigateHome, onNavigateMovements: onNavigateMovements, onNavigateAccounts: onNavigateAccounts, onNavigateMonthlyFee: onNavigateMonthlyFee })) : null)));
146031
146093
  };
146032
146094
 
146095
+ const SEARCH_DEBOUNCE_MS$3 = 1000;
146096
+ const SEARCH_MIN_CHARS$3 = 2;
146033
146097
  const formatCurrency$3 = (value) => new Intl.NumberFormat("pt-BR", {
146034
146098
  style: "currency",
146035
146099
  currency: "BRL",
146036
- }).format(Number(value));
146100
+ }).format(Number(value) || 0);
146101
+ const accountDetail = (account) => {
146102
+ const place = account.accountType === "CASH"
146103
+ ? "Caixa"
146104
+ : [
146105
+ account.agency ? `Agência ${account.agency}` : "",
146106
+ account.account ? `Conta ${account.account}` : "",
146107
+ ]
146108
+ .filter(Boolean)
146109
+ .join(" · ");
146110
+ return [place, account.pixKey].filter(Boolean).join(" · ");
146111
+ };
146112
+ function EmptyState$2({ message }) {
146113
+ return (React$1.createElement(Box$1, { role: "status", sx: { py: 4, textAlign: "center" } },
146114
+ React$1.createElement(Typography$1, { variant: "body1", color: "text.secondary" }, message)));
146115
+ }
146037
146116
  const AccountListItem = React$1.memo(({ account, isLastItem, onSelect, }) => {
146038
- var _a, _b;
146039
- const theme = useTheme$1();
146040
- const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
146041
- const currentBalance = parseFloat(account.currentBalance);
146042
- return (React$1.createElement(ListItem$1, { "data-testid": `financial-account-list-item-${account.id}`, sx: {
146043
- width: "100%",
146044
- borderBottom: isLastItem ? "none" : `1px solid ${theme.palette.divider}`,
146045
- cursor: "pointer",
146046
- "&:hover": { backgroundColor: theme.palette.action.hover },
146047
- }, onClick: () => onSelect(account.id) },
146048
- React$1.createElement(ListItemAvatar$1, null,
146049
- React$1.createElement(Avatar$1, { alt: account.name, src: (_a = account.image) !== null && _a !== void 0 ? _a : undefined, sx: {
146050
- bgcolor: theme.palette.primary.main,
146051
- color: theme.palette.primary.contrastText,
146052
- } }, account.accountType === "CASH" ? (React$1.createElement(SavingsIcon, { fontSize: isMobile ? "medium" : "large" })) : (React$1.createElement(AccountBalanceIcon, { fontSize: isMobile ? "medium" : "large" })))),
146053
- React$1.createElement(ListItemText$1, { primary: account.name, secondary: React$1.createElement(Box$1, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } },
146054
- account.accountType === "BANK" ? (React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary" },
146055
- "Ag\u00EAncia: ",
146056
- account.agency,
146057
- " | Conta: ",
146058
- account.account)) : null,
146059
- React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary" },
146060
- "Saldo atual: ",
146061
- formatCurrency$3(currentBalance)),
146062
- account.pixKey ? (React$1.createElement(Chip$1, { label: `PIX: ${(_b = account.pixKeyType) !== null && _b !== void 0 ? _b : "Chave"}`, size: "small", color: "primary", variant: "outlined" })) : null) }),
146063
- React$1.createElement(ListItemSecondaryAction$1, null,
146064
- React$1.createElement(ChevronRight$2, { color: "action" }))));
146117
+ const detail = accountDetail(account);
146118
+ return (React$1.createElement(React$1.Fragment, null,
146119
+ React$1.createElement(ListItem$1, { "data-testid": `financial-account-list-item-${account.id}`, onClick: () => onSelect(account.id), onKeyDown: (event) => {
146120
+ if (event.key === "Enter" || event.key === " ") {
146121
+ event.preventDefault();
146122
+ onSelect(account.id);
146123
+ }
146124
+ }, tabIndex: 0, "aria-label": `Selecionar conta: ${account.name}`, sx: {
146125
+ display: "flex",
146126
+ px: 0,
146127
+ minHeight: 44,
146128
+ cursor: "pointer",
146129
+ "&:hover, &:focus": { backgroundColor: "action.hover" },
146130
+ } },
146131
+ React$1.createElement(Box$1, { sx: { flex: 1, minWidth: 0 } },
146132
+ React$1.createElement(Box$1, { sx: {
146133
+ display: "flex",
146134
+ justifyContent: "space-between",
146135
+ gap: 2,
146136
+ alignItems: "baseline",
146137
+ } },
146138
+ React$1.createElement(Typography$1, { variant: "subtitle1", noWrap: true }, account.name),
146139
+ React$1.createElement(Typography$1, { variant: "subtitle1", sx: { fontWeight: 600, flexShrink: 0 } }, formatCurrency$3(account.currentBalance))),
146140
+ detail ? (React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary" }, detail)) : null)),
146141
+ !isLastItem ? React$1.createElement(Divider$1, { component: "li" }) : null));
146065
146142
  });
146066
146143
  AccountListItem.displayName = "AccountListItem";
146067
146144
  const FinancialAccountsPage = ({ accounts, onBack, onSelectAccount, onAddAccount, }) => {
146068
- useTheme$1();
146069
146145
  const { embedded } = useFinancialChrome();
146070
- const isEmpty = accounts.length === 0;
146071
- const rows = React$1.useMemo(() => accounts.map((account, index) => (React$1.createElement(AccountListItem, { key: account.id, account: account, isLastItem: index === accounts.length - 1, onSelect: onSelectAccount }))), [accounts, onSelectAccount]);
146072
- const handleAdd = React$1.useCallback(() => {
146073
- onAddAccount();
146074
- }, [onAddAccount]);
146146
+ const [searchInput, setSearchInput] = React$1.useState("");
146147
+ const [searchTerm, setSearchTerm] = React$1.useState("");
146148
+ React$1.useEffect(() => {
146149
+ const normalized = searchInput.trim().toLowerCase();
146150
+ if (normalized.length < SEARCH_MIN_CHARS$3) {
146151
+ setSearchTerm("");
146152
+ return;
146153
+ }
146154
+ const timeout = window.setTimeout(() => setSearchTerm(normalized), SEARCH_DEBOUNCE_MS$3);
146155
+ return () => window.clearTimeout(timeout);
146156
+ }, [searchInput]);
146157
+ const balanceLabel = React$1.useMemo(() => {
146158
+ const total = accounts.reduce((sum, account) => {
146159
+ const value = Number(account.currentBalance);
146160
+ return sum + (Number.isFinite(value) ? value : 0);
146161
+ }, 0);
146162
+ return formatCurrency$3(total);
146163
+ }, [accounts]);
146164
+ const visibleAccounts = React$1.useMemo(() => {
146165
+ if (!searchTerm)
146166
+ return accounts;
146167
+ return accounts.filter((account) => account.name.toLowerCase().includes(searchTerm));
146168
+ }, [accounts, searchTerm]);
146075
146169
  return (React$1.createElement(Box$1, { sx: { minHeight: embedded ? "auto" : "100vh", bgcolor: "background.default" } },
146076
- embedded ? null : (React$1.createElement(PageHeader$2, { title: "Contas", onBack: onBack, onAdd: handleAdd, addLabel: "Adicionar", showAddButton: true, hideAddButtonOnMobile: true })),
146077
- React$1.createElement(Container$1, { maxWidth: "md", sx: PAGE_LIST_CONTAINER_SPACING },
146078
- embedded ? (React$1.createElement(Box$1, { sx: { display: "flex", justifyContent: "flex-end", mb: 1 } },
146079
- React$1.createElement(Button$1, { variant: "outlined", startIcon: React$1.createElement(Add$1, null), onClick: handleAdd, "data-testid": "financial-account-add-button" }, "Adicionar conta"))) : null,
146080
- isEmpty ? (React$1.createElement(Box$1, { sx: {
146081
- display: "flex",
146082
- flexDirection: "column",
146083
- alignItems: "center",
146084
- textAlign: "center",
146085
- py: EMPTY_STATE_VERTICAL_PADDING,
146086
- px: EMPTY_STATE_PADDING,
146087
- } },
146088
- React$1.createElement(AccountBalanceIcon, { sx: { fontSize: 64, color: "text.disabled", mb: 1 } }),
146089
- React$1.createElement(Typography$1, { variant: "h6", sx: { fontWeight: 600, mb: 1 } }, "Nenhuma conta cadastrada"),
146090
- React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary", sx: { mb: 3, maxWidth: 320 } }, "Cadastre a caixinha ou uma conta para acompanhar o saldo da casa."),
146091
- React$1.createElement(Button$1, { "data-testid": "financial-account-empty-add-button", variant: "contained", startIcon: React$1.createElement(Add$1, null), onClick: handleAdd, sx: { borderRadius: RADIUS.default, px: CARD_PADDING } }, "Adicionar Conta"))) : (React$1.createElement(List$1, { "data-testid": "financial-accounts-list", sx: { pb: LIST_CONTENT_BOTTOM_PADDING } }, rows)))));
146170
+ embedded ? null : (React$1.createElement(PageHeader$2, { title: "Contas", onBack: onBack, showAddButton: false })),
146171
+ React$1.createElement(FinancialSummaryHeader, { embedded: embedded, variant: "accounts", balanceLabel: balanceLabel, onAdd: onAddAccount, addLabel: "Adicionar conta" }),
146172
+ React$1.createElement(Container$1, { maxWidth: "md", sx: Object.assign(Object.assign({}, PAGE_LIST_CONTAINER_SPACING), { pb: LIST_CONTENT_BOTTOM_PADDING }) },
146173
+ React$1.createElement(TextField$1, { fullWidth: true, placeholder: "Buscar conta", value: searchInput, onChange: (event) => setSearchInput(event.target.value), inputProps: { "aria-label": "Buscar conta" }, InputProps: {
146174
+ startAdornment: (React$1.createElement(InputAdornment$1, { position: "start" },
146175
+ React$1.createElement(Search$1, { sx: { color: "text.secondary" } }))),
146176
+ }, sx: {
146177
+ mb: 2,
146178
+ width: "100%",
146179
+ "& .MuiOutlinedInput-root": {
146180
+ borderRadius: RADIUS.default,
146181
+ minHeight: 44,
146182
+ backgroundColor: "background.paper",
146183
+ },
146184
+ } }),
146185
+ visibleAccounts.length === 0 ? (React$1.createElement(EmptyState$2, { message: searchTerm ? "Nenhuma conta encontrada" : "Nenhuma conta cadastrada" })) : (React$1.createElement(List$1, { "data-testid": "financial-accounts-list", sx: { py: 0 } }, visibleAccounts.map((account, index) => (React$1.createElement(AccountListItem, { key: account.id, account: account, isLastItem: index === visibleAccounts.length - 1, onSelect: onSelectAccount }))))))));
146092
146186
  };
146093
146187
 
146094
146188
  const FinancialMonthlyFeePage = ({ formatCurrency, monthlyFee, dueDay, paymentMethod, receivingAccount, onBack, onEdit, summary, receiptForm, children, }) => {
@@ -147230,22 +147324,11 @@ const useIncomeListPage = (props) => {
147230
147324
 
147231
147325
  /* eslint-disable @typescript-eslint/no-explicit-any */
147232
147326
  /* eslint-disable @typescript-eslint/no-empty-function */
147233
- /**
147234
- * Accessible, actionable empty state for incomes
147235
- */
147236
- function EmptyState$1({ onAdd, isMobile, }) {
147237
- return (React$1.createElement(Box$1, { role: "region", "aria-labelledby": "income-empty-title", sx: {
147238
- py: EMPTY_STATE_VERTICAL_PADDING,
147239
- display: "flex",
147240
- flexDirection: "column",
147241
- alignItems: "center",
147242
- gap: 2,
147243
- textAlign: "center",
147244
- } },
147245
- React$1.createElement(ReceiptLongIcon, { sx: { fontSize: 56, color: "text.secondary" }, "aria-hidden": true }),
147246
- React$1.createElement(Typography$1, { id: "income-empty-title", variant: "h6" }, "Nenhuma contribui\u00E7\u00E3o registrada"),
147247
- React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary", sx: { maxWidth: 440 } }, "Registre sua primeira contribui\u00E7\u00E3o para acompanhar o saldo e controlar as doa\u00E7\u00F5es e receitas do m\u00EAs. Voc\u00EA pode adicionar uma contribui\u00E7\u00E3o agora mesmo."),
147248
- React$1.createElement(Button$1, { variant: "contained", color: "primary", startIcon: React$1.createElement(Add$1, null), onClick: onAdd !== null && onAdd !== void 0 ? onAdd : (() => { }), "aria-label": "Adicionar nova contribui\u00E7\u00E3o", sx: { mt: 1, px: 3 }, size: isMobile ? "medium" : "large" }, "Adicionar Contribui\u00E7\u00E3o")));
147327
+ const SEARCH_DEBOUNCE_MS$2 = 1000;
147328
+ const SEARCH_MIN_CHARS$2 = 2;
147329
+ function EmptyState$1({ message }) {
147330
+ return (React$1.createElement(Box$1, { role: "status", sx: { py: 4, textAlign: "center" } },
147331
+ React$1.createElement(Typography$1, { variant: "body1", color: "text.secondary" }, message)));
147249
147332
  }
147250
147333
  /**
147251
147334
  * Presentation-only list item component (memoized)
@@ -147255,10 +147338,8 @@ const IncomeListItem = React$1.memo(function IncomeListItem({ item, idx, isLastI
147255
147338
  const dateLabel = formatDate(item.date);
147256
147339
  const formattedAmount = formatCurrency(item.amount);
147257
147340
  const accountName = getAccountName(item);
147258
- const { category, subcategory } = item;
147259
147341
  const settlementStatus = (_a = item.settlementStatus) !== null && _a !== void 0 ? _a : "CONSOLIDATED";
147260
- const settlementLabel = settlementStatus === "PROJECTED" ? "Aguardando Pagamento" : "Pago";
147261
- const settlementColor = settlementStatus === "PROJECTED" ? "warning" : "success";
147342
+ const settlementLabel = settlementStatus === "PROJECTED" ? "Aguardando pagamento" : "Pago";
147262
147343
  const nextSettlementStatus = settlementStatus === "PROJECTED" ? "CONSOLIDATED" : "PROJECTED";
147263
147344
  const settlementActionLabel = settlementStatus === "PROJECTED"
147264
147345
  ? "Marcar como Pago"
@@ -147269,48 +147350,39 @@ const IncomeListItem = React$1.memo(function IncomeListItem({ item, idx, isLastI
147269
147350
  onSelect(item.id);
147270
147351
  };
147271
147352
  return (React$1.createElement(React$1.Fragment, { key: (_d = item.id) !== null && _d !== void 0 ? _d : keyFallback },
147272
- React$1.createElement(ListItem$1, { alignItems: "flex-start", onClick: handleSelect, onKeyDown: (e) => {
147353
+ React$1.createElement(ListItem$1, { alignItems: "center", onClick: handleSelect, onKeyDown: (e) => {
147273
147354
  if ((e.key === "Enter" || e.key === " ") && onSelect && item.id) {
147274
147355
  e.preventDefault();
147275
147356
  onSelect(item.id);
147276
147357
  }
147277
147358
  }, tabIndex: onSelect ? 0 : -1, "aria-label": onSelect ? `Selecionar contribuição: ${item.description}` : undefined, sx: {
147359
+ display: "flex",
147360
+ gap: 1,
147361
+ px: 0,
147278
147362
  cursor: onSelect ? "pointer" : undefined,
147279
147363
  "&:hover, &:focus": onSelect
147280
147364
  ? { backgroundColor: "action.hover" }
147281
147365
  : undefined,
147282
147366
  } },
147283
- React$1.createElement(ListItemText$1, { primary: React$1.createElement(Box$1, { sx: {
147284
- display: "flex",
147285
- alignItems: "flex-start",
147286
- flexDirection: "column",
147287
- gap: 1,
147288
- } },
147289
- React$1.createElement(Typography$1, { variant: "subtitle1" }, item.description),
147290
- category && subcategory && (React$1.createElement(Typography$1, { variant: "caption", color: "text.secondary" },
147291
- "\u2022 ",
147292
- category,
147293
- " / ",
147294
- subcategory)),
147295
- React$1.createElement(Chip$1, { size: "small", label: settlementLabel, color: settlementColor, variant: settlementStatus === "PROJECTED" ? "outlined" : "filled" })), secondary: React$1.createElement(Box$1, { sx: {
147367
+ React$1.createElement(Box$1, { sx: { flex: 1, minWidth: 0 } },
147368
+ React$1.createElement(Box$1, { sx: {
147296
147369
  display: "flex",
147297
- flexDirection: "column",
147298
- gap: 0.25,
147370
+ justifyContent: "space-between",
147371
+ gap: 2,
147372
+ alignItems: "baseline",
147299
147373
  } },
147300
- React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary" }, accountName),
147301
- React$1.createElement(Typography$1, { variant: "caption", color: "text.secondary" }, dateLabel)) }),
147302
- React$1.createElement(ListItemSecondaryAction$1, null,
147303
- React$1.createElement(Stack$1, { spacing: 1, alignItems: "flex-end" },
147304
- React$1.createElement(Typography$1, { variant: "subtitle1", sx: { fontWeight: 600 } }, formattedAmount),
147305
- canConfirmTransactions && item.id && onToggleSettlementStatus ? (React$1.createElement(IconButton$1, { "aria-label": settlementActionLabel, disabled: Boolean(isUpdatingSettlementStatus), onClick: (event) => {
147306
- event.stopPropagation();
147307
- item.id &&
147308
- onToggleSettlementStatus(item.id, nextSettlementStatus);
147309
- }, sx: { width: 44, height: 44 } }, settlementStatus === "PROJECTED" ? React$1.createElement(Check$1, null) : React$1.createElement(UndoIcon, null))) : null))),
147310
- !isLastItem && React$1.createElement(Divider$1, { component: "li", variant: "inset" })));
147374
+ React$1.createElement(Typography$1, { variant: "subtitle1", noWrap: true }, item.description),
147375
+ React$1.createElement(Typography$1, { variant: "subtitle1", sx: { fontWeight: 600, flexShrink: 0 } }, formattedAmount)),
147376
+ React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary" }, [accountName, dateLabel, settlementLabel].filter(Boolean).join(" · "))),
147377
+ canConfirmTransactions && item.id && onToggleSettlementStatus ? (React$1.createElement(IconButton$1, { "aria-label": settlementActionLabel, disabled: Boolean(isUpdatingSettlementStatus), onClick: (event) => {
147378
+ event.stopPropagation();
147379
+ item.id &&
147380
+ onToggleSettlementStatus(item.id, nextSettlementStatus);
147381
+ }, sx: { width: 44, height: 44, flexShrink: 0 } }, settlementStatus === "PROJECTED" ? React$1.createElement(Check$1, null) : React$1.createElement(UndoIcon, null))) : null),
147382
+ !isLastItem && React$1.createElement(Divider$1, { component: "li" })));
147311
147383
  });
147312
- const IncomeListPage = ({ onBack, onAdd, onSelect, periodLabel, periodInputValue, periodInputMin, periodInputMax, showPeriodFilter, onPeriodInputChange, canConfirmTransactions, isUpdatingSettlementStatus, onToggleSettlementStatus, movementKind, onMovementKindChange, data, }) => {
147313
- const { data: { dataSource, isMobile, theme }, fns: { formatCurrency, formatDate, getAccountName }, } = useIncomeListPage({ data });
147384
+ const IncomeListPage = ({ onBack, onAdd, onSelect, periodLabel, periodInputValue, periodInputMin, periodInputMax, showPeriodFilter, onPeriodInputChange, canConfirmTransactions, isUpdatingSettlementStatus, onToggleSettlementStatus, movementKind, onMovementKindChange, incomeTotalLabel, outcomeTotalLabel, data, }) => {
147385
+ const { data: { dataSource, theme }, fns: { formatCurrency, formatDate, getAccountName }, } = useIncomeListPage({ data });
147314
147386
  const { embedded } = useFinancialChrome();
147315
147387
  const totalAmountNumber = React$1.useMemo(() => {
147316
147388
  const val = typeof dataSource.totalAmount === "string"
@@ -147336,48 +147408,64 @@ const IncomeListPage = ({ onBack, onAdd, onSelect, periodLabel, periodInputValue
147336
147408
  currency: "BRL",
147337
147409
  });
147338
147410
  const incomes = React$1.useMemo(() => (Array.isArray(dataSource.incomes) ? dataSource.incomes : []), [dataSource.incomes]);
147411
+ const [searchInput, setSearchInput] = React$1.useState("");
147412
+ const [searchTerm, setSearchTerm] = React$1.useState("");
147413
+ React$1.useEffect(() => {
147414
+ const trimmed = searchInput.trim();
147415
+ if (trimmed.length < SEARCH_MIN_CHARS$2) {
147416
+ setSearchTerm("");
147417
+ return;
147418
+ }
147419
+ const timeoutId = window.setTimeout(() => {
147420
+ setSearchTerm(trimmed.toLowerCase());
147421
+ }, SEARCH_DEBOUNCE_MS$2);
147422
+ return () => window.clearTimeout(timeoutId);
147423
+ }, [searchInput]);
147424
+ const visibleIncomes = React$1.useMemo(() => {
147425
+ if (!searchTerm)
147426
+ return incomes;
147427
+ return incomes.filter((item) => item.description.toLowerCase().includes(searchTerm));
147428
+ }, [incomes, searchTerm]);
147339
147429
  return (React$1.createElement(Box$1, { sx: {
147340
147430
  display: "flex",
147341
147431
  flexDirection: "column",
147342
147432
  minHeight: embedded ? "auto" : "100vh",
147343
147433
  backgroundColor: theme.palette.background.default,
147344
147434
  position: "relative",
147345
- //pb: isMobile ? 2 : 0,
147346
147435
  } },
147347
147436
  embedded ? null : (React$1.createElement(PageHeader$2, { title: "Contribui\u00E7\u00F5es", onBack: onBack, showAddButton: false })),
147348
- React$1.createElement(FinancialSummaryHeader, { embedded: embedded, variant: "movements", balanceLabel: amountLabel, periodLabel: periodLabel || metricPeriodLabel, periodInputValue: periodInputValue, periodInputMin: periodInputMin, periodInputMax: periodInputMax, onPeriodInputChange: showPeriodFilter === false ? undefined : onPeriodInputChange, onAdd: onAdd, addLabel: "Adicionar contribui\u00E7\u00E3o", addQuotaFeature: "incomes" }),
147437
+ React$1.createElement(FinancialSummaryHeader, { embedded: embedded, variant: "movements", balanceLabel: amountLabel, periodLabel: periodLabel || metricPeriodLabel, periodInputValue: periodInputValue, periodInputMin: periodInputMin, periodInputMax: periodInputMax, onPeriodInputChange: showPeriodFilter === false ? undefined : onPeriodInputChange, onAdd: onAdd, addLabel: "Adicionar contribui\u00E7\u00E3o", addQuotaFeature: "incomes", movementKind: movementKind !== null && movementKind !== void 0 ? movementKind : "income", incomeTotalLabel: incomeTotalLabel !== null && incomeTotalLabel !== void 0 ? incomeTotalLabel : amountLabel, outcomeTotalLabel: outcomeTotalLabel, onMovementKindChange: onMovementKindChange }),
147349
147438
  React$1.createElement(Container$1, { maxWidth: "md", sx: Object.assign(Object.assign({}, PAGE_LIST_CONTAINER_SPACING), { pb: LIST_CONTENT_BOTTOM_PADDING }) },
147350
- onMovementKindChange ? (React$1.createElement(Box$1, { sx: { mb: 2 } },
147351
- React$1.createElement(FinancialMovementSegment, { value: movementKind !== null && movementKind !== void 0 ? movementKind : "income", onChange: onMovementKindChange }))) : null,
147352
- incomes.length === 0 ? (React$1.createElement(Box$1, { sx: {
147439
+ React$1.createElement(TextField$1, { fullWidth: true, placeholder: "Buscar lan\u00E7amento", value: searchInput, onChange: (event) => setSearchInput(event.target.value), inputProps: { "aria-label": "Buscar lançamento" }, InputProps: {
147440
+ startAdornment: (React$1.createElement(InputAdornment$1, { position: "start" },
147441
+ React$1.createElement(Search$1, { sx: { color: "text.secondary" } }))),
147442
+ }, sx: {
147443
+ mb: 2,
147353
147444
  width: "100%",
147354
- bgcolor: "background.paper",
147355
- borderRadius: RADIUS.default,
147356
- boxShadow: "none",
147357
- border: 1,
147358
- borderColor: "divider",
147359
- overflow: "hidden",
147360
- display: "flex",
147361
- alignItems: "center",
147362
- justifyContent: "center",
147363
- p: EMPTY_STATE_PADDING,
147364
- } },
147365
- React$1.createElement(EmptyState$1, { onAdd: onAdd, isMobile: isMobile }))) : (React$1.createElement(List$1, { sx: {
147445
+ "& .MuiOutlinedInput-root": {
147446
+ borderRadius: RADIUS.default,
147447
+ minHeight: 44,
147448
+ backgroundColor: "background.paper",
147449
+ },
147450
+ } }),
147451
+ visibleIncomes.length === 0 ? (React$1.createElement(EmptyState$1, { message: searchTerm
147452
+ ? "Nenhum lançamento encontrado"
147453
+ : "Nenhuma contribuição registrada" })) : (React$1.createElement(List$1, { sx: {
147366
147454
  width: "100%",
147367
147455
  bgcolor: "transparent",
147368
147456
  borderRadius: 0,
147369
147457
  boxShadow: "none",
147370
147458
  border: "none",
147371
147459
  overflow: "hidden",
147372
- } }, incomes.map((inc, idx) => {
147460
+ } }, visibleIncomes.map((inc, idx) => {
147373
147461
  var _a, _b;
147374
- return (React$1.createElement(IncomeListItem, { key: `${(_a = inc.date) !== null && _a !== void 0 ? _a : ""}-${idx}-${(_b = inc.amount) !== null && _b !== void 0 ? _b : ""}`, item: inc, idx: idx, isLastItem: idx === incomes.length - 1, formatCurrency: formatCurrency, formatDate: formatDate, getAccountName: getAccountName, onSelect: onSelect, canConfirmTransactions: canConfirmTransactions, isUpdatingSettlementStatus: isUpdatingSettlementStatus, onToggleSettlementStatus: onToggleSettlementStatus }));
147462
+ return (React$1.createElement(IncomeListItem, { key: `${(_a = inc.date) !== null && _a !== void 0 ? _a : ""}-${idx}-${(_b = inc.amount) !== null && _b !== void 0 ? _b : ""}`, item: inc, idx: idx, isLastItem: idx === visibleIncomes.length - 1, formatCurrency: formatCurrency, formatDate: formatDate, getAccountName: getAccountName, onSelect: onSelect, canConfirmTransactions: canConfirmTransactions, isUpdatingSettlementStatus: isUpdatingSettlementStatus, onToggleSettlementStatus: onToggleSettlementStatus }));
147375
147463
  }))))));
147376
147464
  };
147377
147465
  var IncomeListPage$1 = React$1.memo(IncomeListPage);
147378
147466
 
147379
- const SEARCH_DEBOUNCE_MS = 1000;
147380
- const SEARCH_MIN_CHARS = 2;
147467
+ const SEARCH_DEBOUNCE_MS$1 = 1000;
147468
+ const SEARCH_MIN_CHARS$1 = 2;
147381
147469
  const useMonthlyFeePaymentsManagementPage = (props) => {
147382
147470
  const { terreiroId, competenceMonth, requests = [], reminderStatus = null, canDispatchReminders = false, isLoading = false, isReviewing = false, isDispatchingReminders = false, error, onBack, onCompetenceMonthChange, onApprove, onReject, onDispatchReminders, } = props;
147383
147471
  const [statusFilter, setStatusFilter] = React$1.useState("ALL");
@@ -147424,13 +147512,13 @@ const useMonthlyFeePaymentsManagementPage = (props) => {
147424
147512
  }, []);
147425
147513
  React$1.useEffect(() => {
147426
147514
  const trimmed = searchInput.trim();
147427
- if (trimmed.length < SEARCH_MIN_CHARS) {
147515
+ if (trimmed.length < SEARCH_MIN_CHARS$1) {
147428
147516
  setSearchTerm("");
147429
147517
  return;
147430
147518
  }
147431
147519
  const timeoutId = window.setTimeout(() => {
147432
147520
  setSearchTerm(trimmed);
147433
- }, SEARCH_DEBOUNCE_MS);
147521
+ }, SEARCH_DEBOUNCE_MS$1);
147434
147522
  return () => {
147435
147523
  window.clearTimeout(timeoutId);
147436
147524
  };
@@ -147816,24 +147904,11 @@ const useOutcomeListPage = (props) => {
147816
147904
 
147817
147905
  /* eslint-disable @typescript-eslint/no-explicit-any */
147818
147906
  /* eslint-disable @typescript-eslint/no-empty-function */
147819
- /**
147820
- * Simple, focused empty state UI
147821
- * - encourages the user to add a new outcome
147822
- * - accessible labels + localized Portuguese copy consistent with page
147823
- */
147824
- function EmptyState({ onAdd, isMobile, }) {
147825
- return (React$1.createElement(Box$1, { role: "region", "aria-labelledby": "outcome-empty-title", sx: {
147826
- py: EMPTY_STATE_VERTICAL_PADDING,
147827
- display: "flex",
147828
- flexDirection: "column",
147829
- alignItems: "center",
147830
- gap: 2,
147831
- textAlign: "center",
147832
- } },
147833
- React$1.createElement(ReceiptLongIcon, { sx: { fontSize: 56, color: "text.secondary" }, "aria-hidden": true }),
147834
- React$1.createElement(Typography$1, { id: "outcome-empty-title", variant: "h6" }, "Nenhum gasto registrado"),
147835
- React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary", sx: { maxWidth: 440 } }, "Registre seu primeiro gasto para acompanhar as despesas do m\u00EAs e organizar seu caixa. Voc\u00EA pode adicionar um gasto agora mesmo."),
147836
- React$1.createElement(Button$1, { variant: "contained", color: "primary", startIcon: React$1.createElement(Add$1, null), onClick: onAdd !== null && onAdd !== void 0 ? onAdd : (() => { }), "aria-label": "Adicionar novo gasto", sx: { mt: 1, px: 3 }, size: isMobile ? "medium" : "large" }, "Adicionar Gastos")));
147907
+ const SEARCH_DEBOUNCE_MS = 1000;
147908
+ const SEARCH_MIN_CHARS = 2;
147909
+ function EmptyState({ message }) {
147910
+ return (React$1.createElement(Box$1, { role: "status", sx: { py: 4, textAlign: "center" } },
147911
+ React$1.createElement(Typography$1, { variant: "body1", color: "text.secondary" }, message)));
147837
147912
  }
147838
147913
  /**
147839
147914
  * Presentation-only list item component
@@ -147846,11 +147921,9 @@ const OutcomeListItem = React$1.memo(function OutcomeListItem({ item, idx, isLas
147846
147921
  const dueDateLabel = item.dueDate ? formatDate(item.dueDate) : "";
147847
147922
  const formattedAmount = formatCurrency(item.amount);
147848
147923
  const accountName = getAccountName(item);
147849
- const { category, subcategory } = item;
147850
- const categoryLabel = category && subcategory ? `${category} / ${subcategory}` : category;
147851
147924
  const settlementStatus = (_a = item.settlementStatus) !== null && _a !== void 0 ? _a : "CONSOLIDATED";
147852
- const settlementLabel = settlementStatus === "PROJECTED" ? "Aguardando Pagamento" : "Pago";
147853
- const settlementColor = settlementStatus === "PROJECTED" ? "warning" : "success";
147925
+ const settlementLabel = settlementStatus === "PROJECTED" ? "Aguardando pagamento" : "Pago";
147926
+ const whenLabel = dueDateLabel ? `vencimento em ${dueDateLabel}` : dateLabel;
147854
147927
  const nextSettlementStatus = settlementStatus === "PROJECTED" ? "CONSOLIDATED" : "PROJECTED";
147855
147928
  const settlementActionLabel = settlementStatus === "PROJECTED"
147856
147929
  ? "Marcar como Pago"
@@ -147861,52 +147934,42 @@ const OutcomeListItem = React$1.memo(function OutcomeListItem({ item, idx, isLas
147861
147934
  onSelect(item.id);
147862
147935
  };
147863
147936
  return (React$1.createElement(React$1.Fragment, { key: (_d = item.id) !== null && _d !== void 0 ? _d : keyFallback },
147864
- React$1.createElement(ListItem$1, { alignItems: "flex-start", onClick: handleSelect, onKeyDown: (e) => {
147937
+ React$1.createElement(ListItem$1, { alignItems: "center", onClick: handleSelect, onKeyDown: (e) => {
147865
147938
  if ((e.key === "Enter" || e.key === " ") && onSelect && item.id) {
147866
147939
  e.preventDefault();
147867
147940
  onSelect(item.id);
147868
147941
  }
147869
147942
  }, tabIndex: onSelect ? 0 : -1, "aria-label": onSelect ? `Selecionar gasto: ${item.description}` : undefined, sx: {
147943
+ display: "flex",
147944
+ gap: 1,
147945
+ px: 0,
147870
147946
  cursor: onSelect ? "pointer" : undefined,
147871
147947
  "&:hover, &:focus": onSelect
147872
147948
  ? { backgroundColor: "action.hover" }
147873
147949
  : undefined,
147874
147950
  } },
147875
- React$1.createElement(ListItemText$1, { primary: React$1.createElement(Box$1, { sx: {
147876
- display: "flex",
147877
- alignItems: "flex-start",
147878
- flexDirection: "column",
147879
- gap: 1,
147880
- } },
147881
- React$1.createElement(Typography$1, { variant: "subtitle1" }, item.description),
147882
- item.category && (React$1.createElement(Typography$1, { variant: "caption", color: "text.secondary" },
147883
- "\u2022 ",
147884
- categoryLabel)),
147885
- React$1.createElement(Chip$1, { size: "small", label: settlementLabel, color: settlementColor, variant: settlementStatus === "PROJECTED" ? "outlined" : "filled" })), secondary: React$1.createElement(Box$1, { sx: {
147951
+ React$1.createElement(Box$1, { sx: { flex: 1, minWidth: 0 } },
147952
+ React$1.createElement(Box$1, { sx: {
147886
147953
  display: "flex",
147887
- flexDirection: "column",
147888
- gap: 0.25,
147954
+ justifyContent: "space-between",
147955
+ gap: 2,
147956
+ alignItems: "baseline",
147889
147957
  } },
147890
- React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary" }, accountName),
147891
- lodashExports.isEmpty(dueDateLabel) ? (React$1.createElement(Typography$1, { variant: "caption", color: "text.secondary" }, dateLabel)) : null,
147892
- dueDateLabel ? (React$1.createElement(Typography$1, { variant: "caption", color: "text.secondary" },
147893
- "vencimento em ",
147894
- dueDateLabel)) : null) }),
147895
- React$1.createElement(ListItemSecondaryAction$1, null,
147896
- React$1.createElement(Stack$1, { spacing: 1, alignItems: "flex-end" },
147897
- React$1.createElement(Typography$1, { variant: "subtitle1", sx: { fontWeight: 600 } }, formattedAmount),
147898
- canConfirmTransactions && item.id && onToggleSettlementStatus ? (React$1.createElement(IconButton$1, { "aria-label": settlementActionLabel, disabled: Boolean(isUpdatingSettlementStatus), onClick: (event) => {
147899
- event.stopPropagation();
147900
- if (!item.id)
147901
- return;
147902
- onToggleSettlementStatus(item.id, nextSettlementStatus);
147903
- }, sx: { width: 44, height: 44 } }, settlementStatus === "PROJECTED" ? React$1.createElement(Check$1, null) : React$1.createElement(UndoIcon, null))) : null))),
147958
+ React$1.createElement(Typography$1, { variant: "subtitle1", noWrap: true }, item.description),
147959
+ React$1.createElement(Typography$1, { variant: "subtitle1", sx: { fontWeight: 600, flexShrink: 0 } }, formattedAmount)),
147960
+ React$1.createElement(Typography$1, { variant: "body2", color: "text.secondary" }, [accountName, whenLabel, settlementLabel].filter(Boolean).join(" · "))),
147961
+ canConfirmTransactions && item.id && onToggleSettlementStatus ? (React$1.createElement(IconButton$1, { "aria-label": settlementActionLabel, disabled: Boolean(isUpdatingSettlementStatus), onClick: (event) => {
147962
+ event.stopPropagation();
147963
+ if (!item.id)
147964
+ return;
147965
+ onToggleSettlementStatus(item.id, nextSettlementStatus);
147966
+ }, sx: { width: 44, height: 44, flexShrink: 0 } }, settlementStatus === "PROJECTED" ? React$1.createElement(Check$1, null) : React$1.createElement(UndoIcon, null))) : null),
147904
147967
  !isLastItem && React$1.createElement(Divider$1, { component: "li" })));
147905
147968
  });
147906
- const OutcomeListPage = ({ onSelect, onBack, onAdd, periodLabel, periodInputValue, periodInputMin, periodInputMax, showPeriodFilter, onPeriodInputChange, canConfirmTransactions, isUpdatingSettlementStatus, onToggleSettlementStatus, movementKind, onMovementKindChange, data, }) => {
147907
- const theme = useTheme$1(); // still used for card color & shadows
147969
+ const OutcomeListPage = ({ onSelect, onBack, onAdd, periodLabel, periodInputValue, periodInputMin, periodInputMax, showPeriodFilter, onPeriodInputChange, canConfirmTransactions, isUpdatingSettlementStatus, onToggleSettlementStatus, movementKind, onMovementKindChange, incomeTotalLabel, outcomeTotalLabel, data, }) => {
147970
+ const theme = useTheme$1();
147908
147971
  const { embedded } = useFinancialChrome();
147909
- const { data: { dataSource, isMobile }, fns: { formatCurrency, formatDate, getAccountName }, } = useOutcomeListPage({ data });
147972
+ const { data: { dataSource }, fns: { formatCurrency, formatDate, getAccountName }, } = useOutcomeListPage({ data });
147910
147973
  const totalAmountNumber = typeof dataSource.totalAmount === "string"
147911
147974
  ? parseFloat(dataSource.totalAmount)
147912
147975
  : dataSource.totalAmount;
@@ -147916,6 +147979,24 @@ const OutcomeListPage = ({ onSelect, onBack, onAdd, periodLabel, periodInputValu
147916
147979
  currency: "BRL",
147917
147980
  });
147918
147981
  const outcomes = React$1.useMemo(() => (Array.isArray(dataSource.outcomes) ? dataSource.outcomes : []), [dataSource.outcomes]);
147982
+ const [searchInput, setSearchInput] = React$1.useState("");
147983
+ const [searchTerm, setSearchTerm] = React$1.useState("");
147984
+ React$1.useEffect(() => {
147985
+ const trimmed = searchInput.trim();
147986
+ if (trimmed.length < SEARCH_MIN_CHARS) {
147987
+ setSearchTerm("");
147988
+ return;
147989
+ }
147990
+ const timeoutId = window.setTimeout(() => {
147991
+ setSearchTerm(trimmed.toLowerCase());
147992
+ }, SEARCH_DEBOUNCE_MS);
147993
+ return () => window.clearTimeout(timeoutId);
147994
+ }, [searchInput]);
147995
+ const visibleOutcomes = React$1.useMemo(() => {
147996
+ if (!searchTerm)
147997
+ return outcomes;
147998
+ return outcomes.filter((item) => item.description.toLowerCase().includes(searchTerm));
147999
+ }, [outcomes, searchTerm]);
147919
148000
  return (React$1.createElement(Box$1, { sx: {
147920
148001
  display: "flex",
147921
148002
  flexDirection: "column",
@@ -147925,33 +148006,30 @@ const OutcomeListPage = ({ onSelect, onBack, onAdd, periodLabel, periodInputValu
147925
148006
  pb: 0,
147926
148007
  } },
147927
148008
  embedded ? null : (React$1.createElement(PageHeader$2, { title: "Gastos", onBack: onBack, showAddButton: false })),
147928
- React$1.createElement(FinancialSummaryHeader, { embedded: embedded, variant: "movements", balanceLabel: amountLabel, periodLabel: periodLabel, periodInputValue: periodInputValue, periodInputMin: periodInputMin, periodInputMax: periodInputMax, onPeriodInputChange: showPeriodFilter === false ? undefined : onPeriodInputChange, onAdd: onAdd, addLabel: "Adicionar gasto", addQuotaFeature: "outcomes" }),
148009
+ React$1.createElement(FinancialSummaryHeader, { embedded: embedded, variant: "movements", balanceLabel: amountLabel, periodLabel: periodLabel, periodInputValue: periodInputValue, periodInputMin: periodInputMin, periodInputMax: periodInputMax, onPeriodInputChange: showPeriodFilter === false ? undefined : onPeriodInputChange, onAdd: onAdd, addLabel: "Adicionar gasto", addQuotaFeature: "outcomes", movementKind: movementKind !== null && movementKind !== void 0 ? movementKind : "outcome", incomeTotalLabel: incomeTotalLabel, outcomeTotalLabel: outcomeTotalLabel !== null && outcomeTotalLabel !== void 0 ? outcomeTotalLabel : amountLabel, onMovementKindChange: onMovementKindChange }),
147929
148010
  React$1.createElement(Container$1, { maxWidth: "md", sx: Object.assign(Object.assign({}, PAGE_LIST_CONTAINER_SPACING), { pb: LIST_CONTENT_BOTTOM_PADDING }) },
147930
- onMovementKindChange ? (React$1.createElement(Box$1, { sx: { mb: 2 } },
147931
- React$1.createElement(FinancialMovementSegment, { value: movementKind !== null && movementKind !== void 0 ? movementKind : "outcome", onChange: onMovementKindChange }))) : null,
147932
- outcomes.length === 0 ? (React$1.createElement(Box$1, { sx: {
148011
+ React$1.createElement(TextField$1, { fullWidth: true, placeholder: "Buscar lan\u00E7amento", value: searchInput, onChange: (event) => setSearchInput(event.target.value), inputProps: { "aria-label": "Buscar lançamento" }, InputProps: {
148012
+ startAdornment: (React$1.createElement(InputAdornment$1, { position: "start" },
148013
+ React$1.createElement(Search$1, { sx: { color: "text.secondary" } }))),
148014
+ }, sx: {
148015
+ mb: 2,
147933
148016
  width: "100%",
147934
- bgcolor: "background.paper",
147935
- borderRadius: RADIUS.default,
147936
- boxShadow: "none",
147937
- border: 1,
147938
- borderColor: "divider",
147939
- overflow: "hidden",
147940
- display: "flex",
147941
- alignItems: "center",
147942
- justifyContent: "center",
147943
- p: EMPTY_STATE_PADDING,
147944
- } },
147945
- React$1.createElement(EmptyState, { onAdd: onAdd, isMobile: isMobile }))) : (React$1.createElement(List$1, { "aria-label": "Lista de gastos", sx: {
148017
+ "& .MuiOutlinedInput-root": {
148018
+ borderRadius: RADIUS.default,
148019
+ minHeight: 44,
148020
+ backgroundColor: "background.paper",
148021
+ },
148022
+ } }),
148023
+ visibleOutcomes.length === 0 ? (React$1.createElement(EmptyState, { message: searchTerm ? "Nenhum lançamento encontrado" : "Nenhum gasto registrado" })) : (React$1.createElement(List$1, { "aria-label": "Lista de gastos", sx: {
147946
148024
  width: "100%",
147947
148025
  bgcolor: "transparent",
147948
148026
  borderRadius: 0,
147949
148027
  boxShadow: "none",
147950
148028
  border: "none",
147951
148029
  overflow: "hidden",
147952
- } }, outcomes.map((out, idx) => {
148030
+ } }, visibleOutcomes.map((out, idx) => {
147953
148031
  var _a, _b;
147954
- return (React$1.createElement(OutcomeListItem, { key: `${(_a = out.date) !== null && _a !== void 0 ? _a : ""}-${idx}-${(_b = out.amount) !== null && _b !== void 0 ? _b : ""}`, item: out, idx: idx, isLastItem: idx === outcomes.length - 1, formatCurrency: formatCurrency, formatDate: formatDate, getAccountName: getAccountName, onSelect: onSelect, canConfirmTransactions: canConfirmTransactions, isUpdatingSettlementStatus: isUpdatingSettlementStatus, onToggleSettlementStatus: onToggleSettlementStatus }));
148032
+ return (React$1.createElement(OutcomeListItem, { key: `${(_a = out.date) !== null && _a !== void 0 ? _a : ""}-${idx}-${(_b = out.amount) !== null && _b !== void 0 ? _b : ""}`, item: out, idx: idx, isLastItem: idx === visibleOutcomes.length - 1, formatCurrency: formatCurrency, formatDate: formatDate, getAccountName: getAccountName, onSelect: onSelect, canConfirmTransactions: canConfirmTransactions, isUpdatingSettlementStatus: isUpdatingSettlementStatus, onToggleSettlementStatus: onToggleSettlementStatus }));
147955
148033
  }))))));
147956
148034
  };
147957
148035
  var OutcomeListPage$1 = React$1.memo(OutcomeListPage);