From 98871af6565adc51fa6892da3755704f9dd2c934 Mon Sep 17 00:00:00 2001 From: Fringg Date: Fri, 24 Apr 2026 07:16:53 +0300 Subject: [PATCH] fix: multi-tariff filter now works server-side + trial-only checkbox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Send comma-separated tariff_ids to backend (was only single ID) — server now filters with IN() operator, pagination correct - Remove client-side tariff filtering (server handles it) - Add "Только триал" checkbox filter: amber checkbox, filters users with trial subscriptions client-side - Remove "trial" from status dropdown (was not working via subscription_status server filter) - i18n: trialOnly key (ru + en) --- src/locales/en.json | 1 + src/locales/ru.json | 1 + src/pages/AdminBulkActions.tsx | 48 +++++++++++++++++++++++++++------- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index fa92050..0df84ac 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -2086,6 +2086,7 @@ "allStatuses": "All statuses", "allTariffs": "All tariffs", "allGroups": "All groups", + "trialOnly": "Trial only", "tariffsSelected": "{{count}} tariffs", "selectAll": "Select all", "deselectAll": "Deselect all" diff --git a/src/locales/ru.json b/src/locales/ru.json index dedf504..0e92425 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -3834,6 +3834,7 @@ "allStatuses": "Все статусы", "allTariffs": "Все тарифы", "allGroups": "Все группы", + "trialOnly": "Только триал", "tariffsSelected": "{{count}} тарифов", "selectAll": "Выбрать все", "deselectAll": "Снять все" diff --git a/src/pages/AdminBulkActions.tsx b/src/pages/AdminBulkActions.tsx index 5daaaff..402cf83 100644 --- a/src/pages/AdminBulkActions.tsx +++ b/src/pages/AdminBulkActions.tsx @@ -1403,6 +1403,7 @@ export default function AdminBulkActions() { const [searchInput, setSearchInput] = useState(''); const [committedSearch, setCommittedSearch] = useState(''); const [statusFilter, setStatusFilter] = useState(''); + const [trialOnly, setTrialOnly] = useState(false); const [tariffFilter, setTariffFilter] = useState([]); const [promoGroupFilter, setPromoGroupFilter] = useState(''); @@ -1444,7 +1445,7 @@ export default function AdminBulkActions() { }; if (committedSearch) params.search = committedSearch; if (statusFilter) params.subscription_status = statusFilter; - if (tariffFilter.length === 1) params.tariff_id = tariffFilter[0]; + if (tariffFilter.length > 0) params.tariff_id = tariffFilter.join(','); if (promoGroupFilter) params.promo_group_id = Number(promoGroupFilter); const data = await adminUsersApi.getUsers( @@ -1980,12 +1981,17 @@ export default function AdminBulkActions() { // When multiple tariffs are selected, filter users client-side // (server only supports single tariff_id filter) const filteredUsers = useMemo(() => { - if (tariffFilter.length <= 1) return users; - return users.filter((u) => { - const subs = u.subscriptions ?? []; - return subs.some((s) => s.tariff_id !== null && tariffFilter.includes(s.tariff_id)); - }); - }, [users, tariffFilter]); + let result = users; + + // Trial-only filter: show users with trial subscription + if (trialOnly) { + result = result.filter( + (u) => u.subscription_is_trial || (u.subscriptions ?? []).some((s) => s.status === 'trial'), + ); + } + + return result; + }, [users, trialOnly]); const table = useReactTable({ data: filteredUsers, @@ -2005,7 +2011,6 @@ export default function AdminBulkActions() { { value: '', label: t('admin.bulkActions.filters.allStatuses') }, { value: 'active', label: t('admin.bulkActions.statuses.active') }, { value: 'expired', label: t('admin.bulkActions.statuses.expired') }, - { value: 'trial', label: t('admin.bulkActions.statuses.trial') }, { value: 'limited', label: t('admin.bulkActions.statuses.limited') }, { value: 'disabled', label: t('admin.bulkActions.statuses.disabled') }, ]; @@ -2074,7 +2079,7 @@ export default function AdminBulkActions() { - {/* Filter dropdowns */} + {/* Filter dropdowns + trial toggle */}
+ + {/* Trial filter checkbox */} + {/* Table */}