braid-ui 1.0.53 → 1.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -8435,12 +8435,6 @@ var formatCurrency2 = (value) => {
8435
8435
  minimumFractionDigits: 2
8436
8436
  }).format(numValue);
8437
8437
  };
8438
- var TRANSACTION_TYPES = [
8439
- { value: "transfer", label: "Transfer", icon: lucideReact.ArrowLeftRight },
8440
- { value: "adjustment", label: "Adjustment", icon: lucideReact.Settings },
8441
- { value: "ach", label: "ACH", icon: lucideReact.Building2 },
8442
- { value: "wire", label: "Wire", icon: lucideReact.Zap }
8443
- ];
8444
8438
  var ADJUSTMENT_DIRECTION_OPTIONS = [
8445
8439
  { value: "debit", label: "Debit" },
8446
8440
  { value: "credit", label: "Credit" }
@@ -8473,13 +8467,18 @@ var NewTransactionView = ({
8473
8467
  onCounterpartySearchChange,
8474
8468
  onCounterpartySelect,
8475
8469
  onCounterpartyDropdownClose,
8470
+ counterpartyHasMore,
8471
+ counterpartyTotalResults,
8472
+ isLoadingMoreCounterparties,
8473
+ onLoadMoreCounterparties,
8476
8474
  receiverAccountLookedUp,
8477
8475
  receiverAccountData,
8478
8476
  isReceiverAccountLoading,
8479
8477
  onReceiverAccountLookup,
8480
8478
  onEditReceiverAccount,
8481
8479
  isReviewReady,
8482
- adjustmentTypeOptions
8480
+ adjustmentTypeOptions,
8481
+ transactionTypeOptions
8483
8482
  }) => {
8484
8483
  const transactionType = form.watch("transactionType");
8485
8484
  const accountNumber = form.watch("accountNumber");
@@ -8529,7 +8528,7 @@ var NewTransactionView = ({
8529
8528
  }
8530
8529
  ] : [];
8531
8530
  const reviewItems = [
8532
- { label: "Transaction Type", value: TRANSACTION_TYPES.find((t) => t.value === transactionType)?.label || "-" },
8531
+ { label: "Transaction Type", value: transactionTypeOptions.find((t) => t.value === transactionType)?.label || "-" },
8533
8532
  { label: "Account Number", value: accountNumber || "-" },
8534
8533
  ...isAdjustment ? [
8535
8534
  { label: "Direction", value: adjustmentDirection === "debit" ? "Debit" : adjustmentDirection === "credit" ? "Credit" : "-" },
@@ -8593,28 +8592,29 @@ var NewTransactionView = ({
8593
8592
  title: "Transaction Type",
8594
8593
  variant: "default",
8595
8594
  className: cn(!accountLookedUp && "opacity-50 pointer-events-none"),
8596
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3 lg:gap-4", children: TRANSACTION_TYPES.map((type) => {
8595
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3 lg:gap-4", children: transactionTypeOptions.map((type) => {
8597
8596
  const Icon2 = type.icon;
8598
8597
  const isSelected = transactionType === type.value;
8598
+ const isDisabled = !accountLookedUp || type.disabled;
8599
8599
  return /* @__PURE__ */ jsxRuntime.jsxs(
8600
8600
  "button",
8601
8601
  {
8602
8602
  type: "button",
8603
- onClick: () => onTransactionTypeChange(type.value),
8604
- disabled: !accountLookedUp,
8603
+ onClick: () => !type.disabled && onTransactionTypeChange(type.value),
8604
+ disabled: isDisabled,
8605
8605
  className: cn(
8606
8606
  "flex flex-col items-center justify-center p-4 lg:p-3 rounded-lg border-2 transition-all",
8607
- "hover:border-primary/50 hover:shadow-md",
8608
- isSelected ? "border-primary bg-primary/5 shadow-sm" : "border-border bg-card"
8607
+ isDisabled ? "opacity-50 cursor-not-allowed border-border bg-muted" : "hover:border-primary/50 hover:shadow-md",
8608
+ isSelected && !type.disabled ? "border-primary bg-primary/5 shadow-sm" : !isDisabled && "border-border bg-card"
8609
8609
  ),
8610
8610
  children: [
8611
8611
  /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: cn(
8612
8612
  "h-6 w-6 lg:h-5 lg:w-5 mb-2",
8613
- isSelected ? "text-primary" : "text-muted-foreground"
8613
+ isSelected && !type.disabled ? "text-primary" : "text-muted-foreground"
8614
8614
  ) }),
8615
8615
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
8616
8616
  "text-sm font-medium",
8617
- isSelected ? "text-primary" : "text-foreground"
8617
+ isSelected && !type.disabled ? "text-primary" : isDisabled ? "text-muted-foreground" : "text-foreground"
8618
8618
  ), children: type.label })
8619
8619
  ]
8620
8620
  },
@@ -8651,19 +8651,41 @@ var NewTransactionView = ({
8651
8651
  ),
8652
8652
  isCounterpartySearching && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) })
8653
8653
  ] }),
8654
- showCounterpartyDropdown && counterpartySearchResults.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute z-50 w-full mt-1 bg-popover border border-border rounded-md shadow-lg max-h-60 overflow-auto", children: counterpartySearchResults.map((result) => /* @__PURE__ */ jsxRuntime.jsxs(
8655
- "button",
8656
- {
8657
- type: "button",
8658
- onClick: () => onCounterpartySelect(result),
8659
- className: "w-full px-3 py-2 text-left hover:bg-accent transition-colors",
8660
- children: [
8661
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-sm", children: result.name }),
8662
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: result.id })
8663
- ]
8664
- },
8665
- result.id
8666
- )) }),
8654
+ showCounterpartyDropdown && counterpartySearchResults.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute z-50 w-full mt-1 bg-popover border border-border rounded-md shadow-lg max-h-60 overflow-hidden flex flex-col", children: [
8655
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 text-xs text-muted-foreground border-b bg-muted/50 flex-shrink-0", children: [
8656
+ "Showing ",
8657
+ counterpartySearchResults.length,
8658
+ " of ",
8659
+ counterpartyTotalResults,
8660
+ " results"
8661
+ ] }),
8662
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-auto flex-1", children: counterpartySearchResults.map((result) => /* @__PURE__ */ jsxRuntime.jsxs(
8663
+ "button",
8664
+ {
8665
+ type: "button",
8666
+ onClick: () => onCounterpartySelect(result),
8667
+ className: "w-full px-3 py-2 text-left hover:bg-accent transition-colors",
8668
+ children: [
8669
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-sm", children: result.name }),
8670
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: result.id })
8671
+ ]
8672
+ },
8673
+ result.id
8674
+ )) }),
8675
+ counterpartyHasMore && /* @__PURE__ */ jsxRuntime.jsx(
8676
+ "button",
8677
+ {
8678
+ type: "button",
8679
+ onClick: onLoadMoreCounterparties,
8680
+ disabled: isLoadingMoreCounterparties,
8681
+ className: "w-full px-3 py-2 text-center text-sm text-primary hover:bg-accent border-t flex-shrink-0 disabled:opacity-50",
8682
+ children: isLoadingMoreCounterparties ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
8683
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }),
8684
+ "Loading..."
8685
+ ] }) : "Load More"
8686
+ }
8687
+ )
8688
+ ] }),
8667
8689
  showCounterpartyDropdown && counterpartySearchResults.length === 0 && !isCounterpartySearching && counterpartyName.length >= 2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute z-50 w-full mt-1 bg-popover border border-border rounded-md shadow-lg p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
8668
8690
  'No counterparties found matching "',
8669
8691
  counterpartyName,
@@ -8866,7 +8888,7 @@ var NewTransactionView = ({
8866
8888
  ] }),
8867
8889
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between text-sm", children: [
8868
8890
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Type:" }),
8869
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: TRANSACTION_TYPES.find((t) => t.value === transactionType)?.label })
8891
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: transactionTypeOptions.find((t) => t.value === transactionType)?.label })
8870
8892
  ] }),
8871
8893
  requiresCounterparty && counterpartyName && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between text-sm", children: [
8872
8894
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Counterparty:" }),
@@ -14402,6 +14424,11 @@ function NewTransaction() {
14402
14424
  const [counterpartySearchResults, setCounterpartySearchResults] = React15.useState([]);
14403
14425
  const [isCounterpartySearching, setIsCounterpartySearching] = React15.useState(false);
14404
14426
  const [showCounterpartyDropdown, setShowCounterpartyDropdown] = React15.useState(false);
14427
+ const [counterpartySearchPage, setCounterpartySearchPage] = React15.useState(1);
14428
+ const [counterpartyHasMore, setCounterpartyHasMore] = React15.useState(false);
14429
+ const [counterpartyTotalResults, setCounterpartyTotalResults] = React15.useState(0);
14430
+ const [isLoadingMoreCounterparties, setIsLoadingMoreCounterparties] = React15.useState(false);
14431
+ const [currentSearchQuery, setCurrentSearchQuery] = React15.useState("");
14405
14432
  const [confirmationOpen, setConfirmationOpen] = React15.useState(false);
14406
14433
  const [submissionStatus, setSubmissionStatus] = React15.useState(null);
14407
14434
  const [errorMessage, setErrorMessage] = React15.useState("");
@@ -14426,6 +14453,12 @@ function NewTransaction() {
14426
14453
  receiverAccountNumber: ""
14427
14454
  }
14428
14455
  });
14456
+ const transactionTypeOptions = React15.useMemo(() => [
14457
+ { value: "transfer", label: "Transfer", icon: lucideReact.ArrowLeftRight, disabled: false },
14458
+ { value: "adjustment", label: "Adjustment", icon: lucideReact.Settings, disabled: false },
14459
+ { value: "ach", label: "ACH", icon: lucideReact.Building2, disabled: true },
14460
+ { value: "wire", label: "Wire", icon: lucideReact.Zap, disabled: false }
14461
+ ], []);
14429
14462
  const adjustmentDirection = form.watch("adjustmentDirection");
14430
14463
  const adjustmentTypeOptions = React15.useMemo(() => {
14431
14464
  if (adjustmentDirection === "credit") {
@@ -14467,37 +14500,60 @@ function NewTransaction() {
14467
14500
  { id: "CP-1234", name: "Global Industries LLC", type: "Business", paymentInstrumentType: "ach" },
14468
14501
  { id: "CP-9012", name: "GlobalCorp Partners", type: "Business", paymentInstrumentType: "both" },
14469
14502
  { id: "CP-3456", name: "Acme Corporation", type: "Business", paymentInstrumentType: "wire" },
14470
- { id: "CP-7890", name: "Tech Innovations Ltd", type: "Business", paymentInstrumentType: "ach" }
14503
+ { id: "CP-7890", name: "Tech Innovations Ltd", type: "Business", paymentInstrumentType: "ach" },
14504
+ { id: "CP-1111", name: "Global Enterprises", type: "Business", paymentInstrumentType: "wire" },
14505
+ { id: "CP-2222", name: "Global Finance Group", type: "Business", paymentInstrumentType: "both" },
14506
+ { id: "CP-3333", name: "Global Trade Inc.", type: "Business", paymentInstrumentType: "wire" },
14507
+ { id: "CP-4444", name: "Global Services Co.", type: "Business", paymentInstrumentType: "ach" },
14508
+ { id: "CP-5555", name: "Global Ventures Ltd", type: "Business", paymentInstrumentType: "both" }
14471
14509
  ];
14510
+ const PAGE_SIZE = 5;
14472
14511
  const isCounterpartyCompatible = (instrumentType, transactionType) => {
14473
14512
  if (instrumentType === "both") return true;
14474
14513
  if (transactionType === "ach" && instrumentType === "ach") return true;
14475
14514
  if (transactionType === "wire" && instrumentType === "wire") return true;
14476
14515
  return false;
14477
14516
  };
14517
+ const filterByTransactionType = (results, txType) => {
14518
+ if (txType === "ach") {
14519
+ return results.filter(
14520
+ (cp) => cp.paymentInstrumentType === "ach" || cp.paymentInstrumentType === "both"
14521
+ );
14522
+ } else if (txType === "wire") {
14523
+ return results.filter(
14524
+ (cp) => cp.paymentInstrumentType === "wire" || cp.paymentInstrumentType === "both"
14525
+ );
14526
+ }
14527
+ return results;
14528
+ };
14478
14529
  const debouncedSearch = React15.useMemo(
14479
- () => lodash.debounce(async (query, txType) => {
14530
+ () => lodash.debounce(async (query, txType, page = 1) => {
14480
14531
  if (query.length < 2) {
14481
14532
  setCounterpartySearchResults([]);
14482
14533
  setShowCounterpartyDropdown(false);
14534
+ setCounterpartyHasMore(false);
14535
+ setCounterpartyTotalResults(0);
14483
14536
  return;
14484
14537
  }
14485
- setIsCounterpartySearching(true);
14538
+ if (page === 1) {
14539
+ setIsCounterpartySearching(true);
14540
+ }
14486
14541
  try {
14487
14542
  await new Promise((resolve) => setTimeout(resolve, 350));
14488
- let results = mockSearchResults.filter(
14543
+ let filteredResults = mockSearchResults.filter(
14489
14544
  (cp) => cp.name.toLowerCase().includes(query.toLowerCase())
14490
14545
  );
14491
- if (txType === "ach") {
14492
- results = results.filter(
14493
- (cp) => cp.paymentInstrumentType === "ach" || cp.paymentInstrumentType === "both"
14494
- );
14495
- } else if (txType === "wire") {
14496
- results = results.filter(
14497
- (cp) => cp.paymentInstrumentType === "wire" || cp.paymentInstrumentType === "both"
14498
- );
14546
+ filteredResults = filterByTransactionType(filteredResults, txType);
14547
+ const startIndex = (page - 1) * PAGE_SIZE;
14548
+ const paginatedResults = filteredResults.slice(startIndex, startIndex + PAGE_SIZE);
14549
+ if (page === 1) {
14550
+ setCounterpartySearchResults(paginatedResults);
14551
+ } else {
14552
+ setCounterpartySearchResults((prev) => [...prev, ...paginatedResults]);
14499
14553
  }
14500
- setCounterpartySearchResults(results);
14554
+ setCounterpartyTotalResults(filteredResults.length);
14555
+ setCounterpartyHasMore(startIndex + PAGE_SIZE < filteredResults.length);
14556
+ setCounterpartySearchPage(page);
14501
14557
  setShowCounterpartyDropdown(true);
14502
14558
  } finally {
14503
14559
  setIsCounterpartySearching(false);
@@ -14512,11 +14568,19 @@ function NewTransaction() {
14512
14568
  }, [debouncedSearch]);
14513
14569
  const handleCounterpartySearchChange = (value) => {
14514
14570
  form.setValue("counterpartyName", value);
14571
+ setCurrentSearchQuery(value);
14572
+ setCounterpartySearchPage(1);
14515
14573
  if (counterpartyLookedUp) {
14516
14574
  setCounterpartyLookedUp(false);
14517
14575
  setCounterpartyData(null);
14518
14576
  }
14519
- debouncedSearch(value, form.getValues("transactionType"));
14577
+ debouncedSearch(value, form.getValues("transactionType"), 1);
14578
+ };
14579
+ const handleLoadMoreCounterparties = async () => {
14580
+ setIsLoadingMoreCounterparties(true);
14581
+ const txType = form.getValues("transactionType");
14582
+ await debouncedSearch(currentSearchQuery, txType, counterpartySearchPage + 1);
14583
+ setIsLoadingMoreCounterparties(false);
14520
14584
  };
14521
14585
  const handleTransactionTypeChange = (newType) => {
14522
14586
  form.setValue("transactionType", newType);
@@ -14572,7 +14636,7 @@ function NewTransaction() {
14572
14636
  form.setValue("counterpartyName", "");
14573
14637
  form.setValue("amount", "");
14574
14638
  form.setValue("description", "");
14575
- form.setValue("adjustmentDirection", "");
14639
+ form.setValue("adjustmentDirection", "debit");
14576
14640
  form.setValue("adjustmentType", "");
14577
14641
  setReceiverAccountLookedUp(false);
14578
14642
  setReceiverAccountData(null);
@@ -14647,6 +14711,22 @@ function NewTransaction() {
14647
14711
  }
14648
14712
  setIsSubmitting(true);
14649
14713
  try {
14714
+ const submissionPayload = {
14715
+ ...data,
14716
+ // Include counterparty details for ACH/Wire transactions
14717
+ ...requiresCounterparty && counterpartyData && {
14718
+ counterpartyId: counterpartyData.counterpartyId,
14719
+ counterpartyType: counterpartyData.counterpartyType,
14720
+ counterpartyPaymentInstrumentType: counterpartyData.paymentInstrumentType
14721
+ },
14722
+ // Include account details
14723
+ accountId: accountData?.customerId,
14724
+ // Include receiver account for transfers
14725
+ ...data.transactionType === "transfer" && receiverAccountData && {
14726
+ receiverAccountId: receiverAccountData.customerId
14727
+ }
14728
+ };
14729
+ console.log("Transaction submission payload:", submissionPayload);
14650
14730
  await new Promise((resolve) => setTimeout(resolve, 1500));
14651
14731
  const hasError = Math.random() > 0.1;
14652
14732
  if (hasError) {
@@ -14676,7 +14756,7 @@ function NewTransaction() {
14676
14756
  amount: "",
14677
14757
  description: "",
14678
14758
  certifyInformation: false,
14679
- adjustmentDirection: "",
14759
+ adjustmentDirection: "debit",
14680
14760
  adjustmentType: "",
14681
14761
  receiverAccountNumber: ""
14682
14762
  });
@@ -14742,6 +14822,10 @@ function NewTransaction() {
14742
14822
  onCounterpartySearchChange: handleCounterpartySearchChange,
14743
14823
  onCounterpartySelect: handleCounterpartySelect,
14744
14824
  onCounterpartyDropdownClose: () => setShowCounterpartyDropdown(false),
14825
+ counterpartyHasMore,
14826
+ counterpartyTotalResults,
14827
+ isLoadingMoreCounterparties,
14828
+ onLoadMoreCounterparties: handleLoadMoreCounterparties,
14745
14829
  onEditCounterparty: handleEditCounterparty,
14746
14830
  onTransactionTypeChange: handleTransactionTypeChange,
14747
14831
  onSubmit: handleSubmit,
@@ -14755,7 +14839,8 @@ function NewTransaction() {
14755
14839
  onReceiverAccountLookup: handleReceiverAccountLookup,
14756
14840
  onEditReceiverAccount: handleEditReceiverAccount,
14757
14841
  isReviewReady,
14758
- adjustmentTypeOptions
14842
+ adjustmentTypeOptions,
14843
+ transactionTypeOptions
14759
14844
  }
14760
14845
  );
14761
14846
  }
@@ -16952,7 +17037,6 @@ exports.Statement = Statement;
16952
17037
  exports.StatementHeader = StatementHeader;
16953
17038
  exports.StatementView = StatementView;
16954
17039
  exports.StatusBadge = StatusBadge;
16955
- exports.TRANSACTION_TYPES = TRANSACTION_TYPES;
16956
17040
  exports.Table = Table;
16957
17041
  exports.TableBody = TableBody;
16958
17042
  exports.TableCaption = TableCaption;