diff --git a/packages/desktop-client/src/components/FinancesApp.tsx b/packages/desktop-client/src/components/FinancesApp.tsx
index fa50fbe7e3..f61e6f1b1b 100644
--- a/packages/desktop-client/src/components/FinancesApp.tsx
+++ b/packages/desktop-client/src/components/FinancesApp.tsx
@@ -17,7 +17,6 @@ import { GlobalKeys } from './GlobalKeys';
import { MobileNavTabs } from './mobile/MobileNavTabs';
import { TransactionEdit } from './mobile/transactions/TransactionEdit';
import { Notifications } from './Notifications';
-import { ManagePayeesPage } from './payees/ManagePayeesPage';
import { Reports } from './reports';
import { LoadingIndicator } from './reports/LoadingIndicator';
import { NarrowAlternate, WideComponent } from './responsive';
@@ -267,7 +266,10 @@ export function FinancesApp() {
}
/>
- } />
+ }
+ />
}
@@ -346,6 +348,7 @@ export function FinancesApp() {
} />
} />
} />
+ } />
diff --git a/packages/desktop-client/src/components/mobile/MobileNavTabs.tsx b/packages/desktop-client/src/components/mobile/MobileNavTabs.tsx
index 7268e33798..11106bc6ac 100644
--- a/packages/desktop-client/src/components/mobile/MobileNavTabs.tsx
+++ b/packages/desktop-client/src/components/mobile/MobileNavTabs.tsx
@@ -123,8 +123,8 @@ export function MobileNavTabs() {
Icon: SvgCalendar3,
},
{
- name: t('Payees (Soon)'),
- path: '/payees/soon',
+ name: t('Payees'),
+ path: '/payees',
style: navTabStyle,
Icon: SvgStoreFront,
},
diff --git a/packages/desktop-client/src/components/mobile/payees/MobilePayeesPage.tsx b/packages/desktop-client/src/components/mobile/payees/MobilePayeesPage.tsx
new file mode 100644
index 0000000000..876d81cc78
--- /dev/null
+++ b/packages/desktop-client/src/components/mobile/payees/MobilePayeesPage.tsx
@@ -0,0 +1,73 @@
+import React, { useCallback, useMemo, useState } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import { styles } from '@actual-app/components/styles';
+import { theme } from '@actual-app/components/theme';
+import { View } from '@actual-app/components/view';
+
+import { getNormalisedString } from 'loot-core/shared/normalisation';
+import { type PayeeEntity } from 'loot-core/types/models';
+
+import { PayeesList } from './PayeesList';
+
+import { Search } from '@desktop-client/components/common/Search';
+import { MobilePageHeader, Page } from '@desktop-client/components/Page';
+import { usePayees } from '@desktop-client/hooks/usePayees';
+import { useSelector } from '@desktop-client/redux';
+
+export function MobilePayeesPage() {
+ const { t } = useTranslation();
+ const payees = usePayees();
+ const [filter, setFilter] = useState('');
+ const isLoading = useSelector(
+ s => s.payees.isPayeesLoading || s.payees.isCommonPayeesLoading,
+ );
+
+ const filteredPayees: PayeeEntity[] = useMemo(() => {
+ if (!filter) return payees;
+ const norm = getNormalisedString(filter);
+ return payees.filter(p => getNormalisedString(p.name).includes(norm));
+ }, [payees, filter]);
+
+ const onSearchChange = useCallback((value: string) => {
+ setFilter(value);
+ }, []);
+
+ const handlePayeePress = useCallback((_payee: PayeeEntity) => {
+ // Intentionally no-op for now
+ }, []);
+
+ return (
+ } padding={0}>
+
+
+
+
+
+ );
+}
diff --git a/packages/desktop-client/src/components/mobile/payees/PayeesList.tsx b/packages/desktop-client/src/components/mobile/payees/PayeesList.tsx
new file mode 100644
index 0000000000..4d12f5e9ad
--- /dev/null
+++ b/packages/desktop-client/src/components/mobile/payees/PayeesList.tsx
@@ -0,0 +1,86 @@
+import { Trans } from 'react-i18next';
+
+import { AnimatedLoading } from '@actual-app/components/icons/AnimatedLoading';
+import { Text } from '@actual-app/components/text';
+import { theme } from '@actual-app/components/theme';
+import { View } from '@actual-app/components/view';
+
+import { type PayeeEntity } from 'loot-core/types/models';
+
+import { PayeesListItem } from './PayeesListItem';
+
+import { MOBILE_NAV_HEIGHT } from '@desktop-client/components/mobile/MobileNavTabs';
+
+type PayeesListProps = {
+ payees: PayeeEntity[];
+ isLoading?: boolean;
+ onPayeePress: (payee: PayeeEntity) => void;
+};
+
+export function PayeesList({
+ payees,
+ isLoading = false,
+ onPayeePress,
+}: PayeesListProps) {
+ if (isLoading && payees.length === 0) {
+ return (
+
+
+
+ );
+ }
+
+ if (payees.length === 0) {
+ return (
+
+
+ No payees found.
+
+
+ );
+ }
+
+ return (
+
+ {payees.map(payee => (
+ onPayeePress(payee)}
+ />
+ ))}
+ {isLoading && (
+
+
+
+ )}
+
+ );
+}
diff --git a/packages/desktop-client/src/components/mobile/payees/PayeesListItem.tsx b/packages/desktop-client/src/components/mobile/payees/PayeesListItem.tsx
new file mode 100644
index 0000000000..2227a8c6c8
--- /dev/null
+++ b/packages/desktop-client/src/components/mobile/payees/PayeesListItem.tsx
@@ -0,0 +1,59 @@
+import React from 'react';
+
+import { Button } from '@actual-app/components/button';
+import { SvgBookmark } from '@actual-app/components/icons/v1';
+import { theme } from '@actual-app/components/theme';
+
+import { type PayeeEntity } from 'loot-core/types/models';
+
+type PayeesListItemProps = {
+ payee: PayeeEntity;
+ onPress: () => void;
+};
+
+export function PayeesListItem({ payee, onPress }: PayeesListItemProps) {
+ return (
+
+ );
+}
diff --git a/packages/desktop-client/src/components/responsive/narrow.ts b/packages/desktop-client/src/components/responsive/narrow.ts
index 45c82ae19b..e0b48a0244 100644
--- a/packages/desktop-client/src/components/responsive/narrow.ts
+++ b/packages/desktop-client/src/components/responsive/narrow.ts
@@ -7,3 +7,4 @@ export { MobileRulesPage as Rules } from '../mobile/rules/MobileRulesPage';
export { MobileRuleEditPage as RuleEdit } from '../mobile/rules/MobileRuleEditPage';
export { CategoryPage as Category } from '../mobile/budget/CategoryPage';
+export { MobilePayeesPage as Payees } from '../mobile/payees/MobilePayeesPage';
diff --git a/packages/desktop-client/src/components/responsive/wide.ts b/packages/desktop-client/src/components/responsive/wide.ts
index b95d1f5260..fe7f63f325 100644
--- a/packages/desktop-client/src/components/responsive/wide.ts
+++ b/packages/desktop-client/src/components/responsive/wide.ts
@@ -9,6 +9,7 @@ export { Account } from '../accounts/Account';
export { ManageRulesPage as Rules } from '../ManageRulesPage';
export { ManageRulesPage as RuleEdit } from '../ManageRulesPage';
+export { ManagePayeesPage as Payees } from '../payees/ManagePayeesPage';
export { UserDirectoryPage } from '../admin/UserDirectory/UserDirectoryPage';
diff --git a/upcoming-release-notes/5767.md b/upcoming-release-notes/5767.md
new file mode 100644
index 0000000000..dce46237ce
--- /dev/null
+++ b/upcoming-release-notes/5767.md
@@ -0,0 +1,7 @@
+---
+category: Features
+authors: [MatissJanis]
+---
+
+Create a mobile payees list page with search and filtering capabilities.
+