chore: remove student tabs, actions and related code from user management
- Remove '学员待审批' and '学员管理' tabs from user management page - Remove studentView, studentRewardAmount, studentRewardLoading states and functions - Remove assignStudent, saveStudentRewardAmount, loadStudentRewardAmount - Remove pending approval (同意/拒绝) actions in operations column - Remove through/reject/unset student menu items - Clean up UsersActions to only show '添加用户' button - Remove student_view query params from API calls
This commit is contained in:
parent
9bb3b9dda9
commit
1474917163
|
|
@ -20,178 +20,29 @@ For commercial licensing, please contact support@quantumnous.com
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
InputNumber,
|
|
||||||
Modal,
|
|
||||||
Select,
|
|
||||||
Space,
|
|
||||||
Typography,
|
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import { useState } from 'react';
|
|
||||||
import { API, showError } from '../../../helpers';
|
|
||||||
|
|
||||||
const UsersActions = ({
|
const UsersActions = ({
|
||||||
setShowAddUser,
|
setShowAddUser,
|
||||||
t,
|
t,
|
||||||
studentView,
|
|
||||||
studentRewardAmount,
|
|
||||||
studentRewardLoading,
|
|
||||||
setStudentRewardAmount,
|
|
||||||
saveStudentRewardAmount,
|
|
||||||
assignStudent,
|
|
||||||
}) => {
|
}) => {
|
||||||
const [assignVisible, setAssignVisible] = useState(false);
|
|
||||||
const [searchingUser, setSearchingUser] = useState(false);
|
|
||||||
const [candidateUsers, setCandidateUsers] = useState([]);
|
|
||||||
const [selectedUserId, setSelectedUserId] = useState('');
|
|
||||||
|
|
||||||
// Add new user
|
|
||||||
const handleAddUser = () => {
|
const handleAddUser = () => {
|
||||||
setShowAddUser(true);
|
setShowAddUser(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openAssignModal = () => {
|
|
||||||
setCandidateUsers([]);
|
|
||||||
setSelectedUserId('');
|
|
||||||
setAssignVisible(true);
|
|
||||||
loadAllUsersForSelect();
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadAllUsersForSelect = async () => {
|
|
||||||
setSearchingUser(true);
|
|
||||||
try {
|
|
||||||
const all = [];
|
|
||||||
let page = 0;
|
|
||||||
let total = 0;
|
|
||||||
do {
|
|
||||||
const res = await API.get(`/api/user/?p=${page}&page_size=100`);
|
|
||||||
const { success, message, data } = res.data;
|
|
||||||
if (!success) {
|
|
||||||
showError(message || t('加载用户失败'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const items = data?.items || [];
|
|
||||||
total = data?.total || 0;
|
|
||||||
all.push(...items);
|
|
||||||
page += 1;
|
|
||||||
} while (all.length < total);
|
|
||||||
setCandidateUsers(all);
|
|
||||||
} catch (error) {
|
|
||||||
showError(t('加载用户失败'));
|
|
||||||
} finally {
|
|
||||||
setSearchingUser(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSelectSearch = async (keyword) => {
|
|
||||||
const kw = String(keyword || '').trim();
|
|
||||||
if (!kw) {
|
|
||||||
loadAllUsersForSelect();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSearchingUser(true);
|
|
||||||
try {
|
|
||||||
const res = await API.get(
|
|
||||||
`/api/user/search?keyword=${encodeURIComponent(kw)}&p=0&page_size=50`,
|
|
||||||
);
|
|
||||||
const { success, message, data } = res.data;
|
|
||||||
if (!success) {
|
|
||||||
showError(message || t('搜索用户失败'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setCandidateUsers(data?.items || []);
|
|
||||||
} catch (error) {
|
|
||||||
showError(t('搜索用户失败'));
|
|
||||||
} finally {
|
|
||||||
setSearchingUser(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAssignConfirm = async () => {
|
|
||||||
const ok = await assignStudent(selectedUserId);
|
|
||||||
if (ok) {
|
|
||||||
setAssignVisible(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='flex gap-2 w-full md:w-auto order-2 md:order-1 items-center'>
|
<div className='flex gap-2 w-full md:w-auto order-2 md:order-1 items-center'>
|
||||||
{studentView === 'all' && (
|
<Button
|
||||||
<Button
|
className='w-full md:w-auto'
|
||||||
className='w-full md:w-auto'
|
onClick={handleAddUser}
|
||||||
onClick={handleAddUser}
|
size='small'
|
||||||
size='small'
|
>
|
||||||
>
|
{t('添加用户')}
|
||||||
{t('添加用户')}
|
</Button>
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{studentView === 'students' && (
|
|
||||||
<>
|
|
||||||
<Space spacing={6} align='center'>
|
|
||||||
<Typography.Text type='tertiary' size='small'>
|
|
||||||
{t('赠送金额')}
|
|
||||||
</Typography.Text>
|
|
||||||
<InputNumber
|
|
||||||
size='small'
|
|
||||||
min={0}
|
|
||||||
precision={2}
|
|
||||||
suffix='USD'
|
|
||||||
value={studentRewardAmount}
|
|
||||||
onChange={(val) => setStudentRewardAmount(Number(val) || 0)}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
size='small'
|
|
||||||
loading={studentRewardLoading}
|
|
||||||
onClick={() => saveStudentRewardAmount(studentRewardAmount)}
|
|
||||||
>
|
|
||||||
{t('保存额度')}
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
<Button
|
|
||||||
className='w-full md:w-auto'
|
|
||||||
onClick={openAssignModal}
|
|
||||||
size='small'
|
|
||||||
>
|
|
||||||
{t('添加学员')}
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal
|
|
||||||
visible={assignVisible}
|
|
||||||
title={t('添加学员')}
|
|
||||||
onCancel={() => setAssignVisible(false)}
|
|
||||||
onOk={handleAssignConfirm}
|
|
||||||
okText={t('确认')}
|
|
||||||
cancelText={t('取消')}
|
|
||||||
confirmLoading={searchingUser}
|
|
||||||
>
|
|
||||||
<div className='space-y-3'>
|
|
||||||
<div>
|
|
||||||
<Typography.Text size='small' type='tertiary'>
|
|
||||||
{t('选择用户')}
|
|
||||||
</Typography.Text>
|
|
||||||
<Select
|
|
||||||
style={{ width: '100%', marginTop: 6 }}
|
|
||||||
placeholder={t('下拉选择全部用户,支持输入手机号/用户名搜索')}
|
|
||||||
value={selectedUserId}
|
|
||||||
filter
|
|
||||||
loading={searchingUser}
|
|
||||||
searchPosition='dropdown'
|
|
||||||
onSearch={handleSelectSearch}
|
|
||||||
optionList={candidateUsers.map((u) => ({
|
|
||||||
label: `${u.username} (${u.phone || '—'}) #${u.id}`,
|
|
||||||
value: u.id,
|
|
||||||
}))}
|
|
||||||
onChange={(val) => setSelectedUserId(val)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default UsersActions;
|
export default UsersActions;
|
||||||
|
|
@ -287,7 +287,6 @@ const renderOperations = (
|
||||||
showResetTwoFAModal,
|
showResetTwoFAModal,
|
||||||
showUserSubscriptionsModal,
|
showUserSubscriptionsModal,
|
||||||
manageUser,
|
manageUser,
|
||||||
studentView,
|
|
||||||
t,
|
t,
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
|
|
@ -295,28 +294,6 @@ const renderOperations = (
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (studentView === 'pending') {
|
|
||||||
return (
|
|
||||||
<Space>
|
|
||||||
<Button
|
|
||||||
type='primary'
|
|
||||||
size='small'
|
|
||||||
onClick={() => manageUser(record.id, 'approve_student', record)}
|
|
||||||
>
|
|
||||||
{t('同意')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type='danger'
|
|
||||||
theme='light'
|
|
||||||
size='small'
|
|
||||||
onClick={() => manageUser(record.id, 'reject_student', record)}
|
|
||||||
>
|
|
||||||
{t('拒绝')}
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const moreMenu = [
|
const moreMenu = [
|
||||||
{
|
{
|
||||||
node: 'item',
|
node: 'item',
|
||||||
|
|
@ -339,38 +316,6 @@ const renderOperations = (
|
||||||
{
|
{
|
||||||
node: 'divider',
|
node: 'divider',
|
||||||
},
|
},
|
||||||
...(record.student_status === 1
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
name: t('通过学员'),
|
|
||||||
onClick: () => manageUser(record.id, 'approve_student', record),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
name: t('拒绝学员'),
|
|
||||||
type: 'danger',
|
|
||||||
onClick: () => manageUser(record.id, 'reject_student', record),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: 'divider',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
...((record.is_student === 1 || record.is_student === true) &&
|
|
||||||
record.role < USER_ROLES.ADMIN
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
name: t('撤销学员'),
|
|
||||||
type: 'danger',
|
|
||||||
onClick: () => manageUser(record.id, 'unset_student', record),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: 'divider',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
|
|
||||||
{
|
{
|
||||||
node: 'item',
|
node: 'item',
|
||||||
|
|
@ -469,7 +414,6 @@ export const getUsersColumns = ({
|
||||||
showResetTwoFAModal,
|
showResetTwoFAModal,
|
||||||
showUserSubscriptionsModal,
|
showUserSubscriptionsModal,
|
||||||
manageUser,
|
manageUser,
|
||||||
studentView,
|
|
||||||
}) => {
|
}) => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
@ -582,7 +526,6 @@ export const getUsersColumns = ({
|
||||||
showResetTwoFAModal,
|
showResetTwoFAModal,
|
||||||
showUserSubscriptionsModal,
|
showUserSubscriptionsModal,
|
||||||
manageUser,
|
manageUser,
|
||||||
studentView,
|
|
||||||
t,
|
t,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,6 @@ const UsersTable = (usersData) => {
|
||||||
showResetTwoFAModal: showResetTwoFAUserModal,
|
showResetTwoFAModal: showResetTwoFAUserModal,
|
||||||
showUserSubscriptionsModal: showUserSubscriptionsUserModal,
|
showUserSubscriptionsModal: showUserSubscriptionsUserModal,
|
||||||
manageUser,
|
manageUser,
|
||||||
studentView: usersData.studentView,
|
|
||||||
});
|
});
|
||||||
}, [
|
}, [
|
||||||
t,
|
t,
|
||||||
|
|
@ -156,7 +155,6 @@ const UsersTable = (usersData) => {
|
||||||
showResetTwoFAUserModal,
|
showResetTwoFAUserModal,
|
||||||
showUserSubscriptionsUserModal,
|
showUserSubscriptionsUserModal,
|
||||||
manageUser,
|
manageUser,
|
||||||
usersData.studentView,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Handle compact mode by removing fixed positioning
|
// Handle compact mode by removing fixed positioning
|
||||||
|
|
|
||||||
|
|
@ -59,13 +59,6 @@ const UsersPage = () => {
|
||||||
// Description state
|
// Description state
|
||||||
compactMode,
|
compactMode,
|
||||||
setCompactMode,
|
setCompactMode,
|
||||||
studentView,
|
|
||||||
setStudentView,
|
|
||||||
studentRewardAmount,
|
|
||||||
studentRewardLoading,
|
|
||||||
setStudentRewardAmount,
|
|
||||||
saveStudentRewardAmount,
|
|
||||||
assignStudent,
|
|
||||||
|
|
||||||
// Translation
|
// Translation
|
||||||
t,
|
t,
|
||||||
|
|
@ -74,14 +67,8 @@ const UsersPage = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='mb-2'>
|
<div className='mb-2'>
|
||||||
<Tabs
|
<Tabs type='line'>
|
||||||
type='line'
|
|
||||||
activeKey={studentView}
|
|
||||||
onChange={(key) => setStudentView(key)}
|
|
||||||
>
|
|
||||||
<Tabs.TabPane itemKey='all' tab={t('全部用户')} />
|
<Tabs.TabPane itemKey='all' tab={t('全部用户')} />
|
||||||
<Tabs.TabPane itemKey='pending' tab={t('学员待审批')} />
|
|
||||||
<Tabs.TabPane itemKey='students' tab={t('学员管理')} />
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
<AddUserModal
|
<AddUserModal
|
||||||
|
|
@ -113,12 +100,6 @@ const UsersPage = () => {
|
||||||
setShowAddUser={setShowAddUser}
|
setShowAddUser={setShowAddUser}
|
||||||
t={t}
|
t={t}
|
||||||
users={usersData.users}
|
users={usersData.users}
|
||||||
studentView={studentView}
|
|
||||||
studentRewardAmount={studentRewardAmount}
|
|
||||||
studentRewardLoading={studentRewardLoading}
|
|
||||||
setStudentRewardAmount={setStudentRewardAmount}
|
|
||||||
saveStudentRewardAmount={saveStudentRewardAmount}
|
|
||||||
assignStudent={assignStudent}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<UsersFilters
|
<UsersFilters
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,6 @@ export const useUsersData = () => {
|
||||||
const [activePage, setActivePage] = useState(1);
|
const [activePage, setActivePage] = useState(1);
|
||||||
const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
||||||
const [searching, setSearching] = useState(false);
|
const [searching, setSearching] = useState(false);
|
||||||
const [studentView, setStudentView] = useState('all');
|
|
||||||
const [studentRewardAmount, setStudentRewardAmount] = useState(0);
|
|
||||||
const [studentRewardLoading, setStudentRewardLoading] = useState(false);
|
|
||||||
const [groupOptions, setGroupOptions] = useState([]);
|
const [groupOptions, setGroupOptions] = useState([]);
|
||||||
const [userCount, setUserCount] = useState(0);
|
const [userCount, setUserCount] = useState(0);
|
||||||
const [tagOptions, setTagOptions] = useState([]);
|
const [tagOptions, setTagOptions] = useState([]);
|
||||||
|
|
@ -95,14 +92,11 @@ export const useUsersData = () => {
|
||||||
// Load users data
|
// Load users data
|
||||||
const loadUsers = async (startIdx, pageSize, tag = null) => {
|
const loadUsers = async (startIdx, pageSize, tag = null) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const viewQuery =
|
|
||||||
studentView && studentView !== 'all'
|
|
||||||
? `&student_view=${encodeURIComponent(studentView)}`
|
|
||||||
: '';
|
|
||||||
const tagFilter = tag || selectedTag;
|
const tagFilter = tag || selectedTag;
|
||||||
const tagQuery = tagFilter ? `&tag=${encodeURIComponent(tagFilter)}` : '';
|
const tagQuery = tagFilter ? `&tag=${encodeURIComponent(tagFilter)}` : '';
|
||||||
const res = await API.get(
|
const res = await API.get(
|
||||||
`/api/user/?p=${startIdx}&page_size=${pageSize}${viewQuery}${tagQuery}`,
|
`/api/user/?p=${startIdx}&page_size=${pageSize}${tagQuery}`,
|
||||||
);
|
);
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
@ -140,7 +134,7 @@ export const useUsersData = () => {
|
||||||
setSearching(true);
|
setSearching(true);
|
||||||
const tagQuery = (searchTag || selectedTag) ? `&tag=${encodeURIComponent(searchTag || selectedTag)}` : '';
|
const tagQuery = (searchTag || selectedTag) ? `&tag=${encodeURIComponent(searchTag || selectedTag)}` : '';
|
||||||
const res = await API.get(
|
const res = await API.get(
|
||||||
`/api/user/search?keyword=${searchKeyword}&group=${searchGroup}&student_view=${encodeURIComponent(studentView)}${tagQuery}&p=${startIdx}&page_size=${pageSize}`,
|
`/api/user/search?keyword=${searchKeyword}&group=${searchGroup}${tagQuery}&p=${startIdx}&page_size=${pageSize}`,
|
||||||
);
|
);
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
@ -195,99 +189,10 @@ export const useUsersData = () => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const assignStudent = async (userId, rewardAmount) => {
|
|
||||||
const uid = parseInt(String(userId), 10);
|
|
||||||
if (!Number.isFinite(uid) || uid <= 0) {
|
|
||||||
showError(t('请输入正确的用户ID'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const finalRewardAmount =
|
|
||||||
rewardAmount === undefined || rewardAmount === null || rewardAmount === ''
|
|
||||||
? studentRewardAmount
|
|
||||||
: Number(rewardAmount) || 0;
|
|
||||||
const rewardQuota = Math.max(0, usdToQuota(finalRewardAmount));
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
const res = await API.post('/api/user/manage', {
|
|
||||||
id: uid,
|
|
||||||
action: 'set_student',
|
|
||||||
reward_quota: rewardQuota,
|
|
||||||
});
|
|
||||||
const { success, message } = res.data;
|
|
||||||
if (!success) {
|
|
||||||
showError(message || t('操作失败,请重试'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
showSuccess(t('已指定用户为学员'));
|
|
||||||
await refresh(1);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
showError(t('操作失败,请重试'));
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadStudentRewardAmount = async () => {
|
|
||||||
setStudentRewardLoading(true);
|
|
||||||
try {
|
|
||||||
const res = await API.get('/api/option/');
|
|
||||||
const { success, data, message } = res.data;
|
|
||||||
if (!success) {
|
|
||||||
showError(message || t('加载赠送额度失败'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const option = (data || []).find(
|
|
||||||
(item) => item.key === 'StudentApprovalRewardQuota',
|
|
||||||
);
|
|
||||||
const quotaVal = parseInt(String(option?.value ?? '0'), 10);
|
|
||||||
if (Number.isFinite(quotaVal) && quotaVal >= 0) {
|
|
||||||
setStudentRewardAmount(quotaToUsd(quotaVal));
|
|
||||||
} else {
|
|
||||||
setStudentRewardAmount(0);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
showError(t('加载赠送额度失败'));
|
|
||||||
} finally {
|
|
||||||
setStudentRewardLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveStudentRewardAmount = async (rewardAmount) => {
|
|
||||||
const rewardQuota = Math.max(0, usdToQuota(Number(rewardAmount) || 0));
|
|
||||||
setStudentRewardLoading(true);
|
|
||||||
try {
|
|
||||||
const res = await API.put('/api/option/', {
|
|
||||||
key: 'StudentApprovalRewardQuota',
|
|
||||||
value: String(rewardQuota),
|
|
||||||
});
|
|
||||||
const { success, message } = res.data;
|
|
||||||
if (!success) {
|
|
||||||
showError(message || t('保存赠送额度失败'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
setStudentRewardAmount(Number(rewardAmount) || 0);
|
|
||||||
showSuccess(t('赠送额度已保存'));
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
showError(t('保存赠送额度失败'));
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
setStudentRewardLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleStudentViewChange = (nextView) => {
|
|
||||||
setStudentView(nextView);
|
|
||||||
setActivePage(1);
|
|
||||||
const { searchKeyword, searchGroup, searchTag } = getFormValues();
|
|
||||||
if (searchKeyword === '' && searchGroup === '' && !searchTag && !selectedTag) {
|
|
||||||
loadUsers(0, pageSize).then();
|
|
||||||
} else {
|
|
||||||
searchUsers(0, pageSize, searchKeyword, searchGroup, searchTag).then();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const resetUserPasskey = async (user) => {
|
const resetUserPasskey = async (user) => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
|
|
@ -429,13 +334,8 @@ export const useUsersData = () => {
|
||||||
});
|
});
|
||||||
fetchGroups().then();
|
fetchGroups().then();
|
||||||
fetchUserTags().then();
|
fetchUserTags().then();
|
||||||
}, [studentView]);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (studentView === 'students') {
|
|
||||||
loadStudentRewardAmount().then();
|
|
||||||
}
|
|
||||||
}, [studentView]);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Data state
|
// Data state
|
||||||
|
|
@ -445,9 +345,6 @@ export const useUsersData = () => {
|
||||||
pageSize,
|
pageSize,
|
||||||
userCount,
|
userCount,
|
||||||
searching,
|
searching,
|
||||||
studentView,
|
|
||||||
studentRewardAmount,
|
|
||||||
studentRewardLoading,
|
|
||||||
groupOptions,
|
groupOptions,
|
||||||
tagOptions,
|
tagOptions,
|
||||||
selectedTag,
|
selectedTag,
|
||||||
|
|
@ -470,15 +367,11 @@ export const useUsersData = () => {
|
||||||
// UI state
|
// UI state
|
||||||
compactMode,
|
compactMode,
|
||||||
setCompactMode,
|
setCompactMode,
|
||||||
setStudentView: handleStudentViewChange,
|
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
loadUsers,
|
loadUsers,
|
||||||
searchUsers,
|
searchUsers,
|
||||||
manageUser,
|
manageUser,
|
||||||
assignStudent,
|
|
||||||
setStudentRewardAmount,
|
|
||||||
saveStudentRewardAmount,
|
|
||||||
resetUserPasskey,
|
resetUserPasskey,
|
||||||
resetUserTwoFA,
|
resetUserTwoFA,
|
||||||
handlePageChange,
|
handlePageChange,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue