project setup
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { View, GestureResponderEvent, ScrollView, Text } from "react-native";
|
||||
|
||||
import { User } from "@/store/models/User.model";
|
||||
import { useAppSelector } from "@/store/hooks";
|
||||
import { selectIsMobile } from "@/store/screen/screenSizeSlice";
|
||||
import { UserTableControls } from "@/components/features/users/UserTableControls";
|
||||
import { DesktopUserAccountsTable } from "@/components/features/users/DesktopUserAccountsTable";
|
||||
import { MobileUserAccountsTable } from "@/components/features/users/MobileUserAccountsTable";
|
||||
import { TablePagination } from "@/components/shared/TablePagination";
|
||||
import { TableSortDirection } from "@/constants/tableSortDirectionEnum";
|
||||
import { RiskEnum } from "@/constants/riskEnum";
|
||||
|
||||
interface UserAccountsTableProps {
|
||||
users: User[];
|
||||
onEdit: (user: User) => void;
|
||||
onAddUser: () => void;
|
||||
onDelete: (user: User) => void;
|
||||
onLock: (user: User) => void;
|
||||
onSelect: (userIds: string[]) => void;
|
||||
onBulkDelete: (users: User[]) => void;
|
||||
selectedUserIds?: string[];
|
||||
page: number;
|
||||
itemsPerPage: number;
|
||||
totalItems: number;
|
||||
from: number;
|
||||
to: number;
|
||||
searchQuery: string;
|
||||
selectedRisks: RiskEnum[];
|
||||
sortColumn: string | null;
|
||||
sortDirection: TableSortDirection;
|
||||
onSearch: (q: string) => void;
|
||||
onSelectRisks: (risks: RiskEnum[]) => void;
|
||||
onSort: (column: string) => void;
|
||||
onItemsPerPageChange: (value: number) => void;
|
||||
onPageChange: (page: number) => void;
|
||||
onAddingUser: boolean;
|
||||
}
|
||||
|
||||
export const UserAccountsTable = ({
|
||||
users,
|
||||
onEdit,
|
||||
onAddUser,
|
||||
onDelete,
|
||||
onLock,
|
||||
onSelect,
|
||||
onBulkDelete,
|
||||
selectedUserIds,
|
||||
page,
|
||||
itemsPerPage,
|
||||
totalItems,
|
||||
from,
|
||||
to,
|
||||
searchQuery,
|
||||
selectedRisks,
|
||||
sortColumn,
|
||||
sortDirection,
|
||||
onSearch,
|
||||
onSelectRisks,
|
||||
onSort,
|
||||
onItemsPerPageChange,
|
||||
onPageChange,
|
||||
onAddingUser,
|
||||
}: UserAccountsTableProps) => {
|
||||
const [selectedUsers, setSelectedUsers] = useState<string[]>([]);
|
||||
const [selectAll, setSelectAll] = useState(false);
|
||||
const [menuVisible, setMenuVisible] = useState(false);
|
||||
const [menuAnchor, setMenuAnchor] = useState<{ x: number; y: number }>({
|
||||
x: 0,
|
||||
y: 0,
|
||||
});
|
||||
const [prevSelectedUserIds, setPrevSelectedUserIds] = useState<
|
||||
string[] | undefined
|
||||
>(selectedUserIds);
|
||||
const isMobile = useAppSelector(selectIsMobile);
|
||||
|
||||
const handleSort = (column: string) => onSort(column);
|
||||
const handleSearch = (query: string) => onSearch(query);
|
||||
const handleSelectRisks = (risks: RiskEnum[]) => onSelectRisks(risks);
|
||||
const handleItemsPerPageChange = (value: number) =>
|
||||
onItemsPerPageChange(value);
|
||||
|
||||
const handleSelectAll = () => {
|
||||
if (selectAll) {
|
||||
setSelectedUsers([]);
|
||||
} else {
|
||||
setSelectedUsers(users.map((user) => user.id) || []);
|
||||
}
|
||||
setSelectAll(!selectAll);
|
||||
};
|
||||
|
||||
const handleSelectUser = (userId: string) => {
|
||||
if (selectedUsers.includes(userId)) {
|
||||
setSelectedUsers(selectedUsers.filter((id) => id !== userId));
|
||||
} else {
|
||||
setSelectedUsers([...selectedUsers, userId]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBulkDelete = () => {
|
||||
if (selectedUsers.length === 0) return;
|
||||
|
||||
const selectedUserObjects = users.filter((user) =>
|
||||
selectedUsers.includes(user.id)
|
||||
);
|
||||
|
||||
if (onBulkDelete) {
|
||||
onBulkDelete(selectedUserObjects || []);
|
||||
} else {
|
||||
alert(`Would delete ${selectedUsers.length} users`);
|
||||
}
|
||||
|
||||
if (onSelect) {
|
||||
onSelect(selectedUsers);
|
||||
}
|
||||
};
|
||||
|
||||
const handleEdit = (user: User) => {
|
||||
if (onEdit) {
|
||||
onEdit(user);
|
||||
} else {
|
||||
alert(`Edit user: ${user.firstName} ${user.lastName}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = (user: User) => {
|
||||
if (onDelete) {
|
||||
onDelete(user);
|
||||
} else {
|
||||
alert(`Delete user: ${user.firstName} ${user.lastName}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleLock = (user: User) => {
|
||||
if (onLock) {
|
||||
onLock(user);
|
||||
} else {
|
||||
alert(`Lock user: ${user.firstName} ${user.lastName}`);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (onSelect) {
|
||||
onSelect(selectedUsers);
|
||||
}
|
||||
}, [selectedUsers, onSelect]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
prevSelectedUserIds &&
|
||||
prevSelectedUserIds.length > 0 &&
|
||||
selectedUserIds &&
|
||||
selectedUserIds.length === 0
|
||||
) {
|
||||
setSelectedUsers([]);
|
||||
setSelectAll(false);
|
||||
}
|
||||
|
||||
setPrevSelectedUserIds(selectedUserIds);
|
||||
}, [selectedUserIds, prevSelectedUserIds]);
|
||||
|
||||
useEffect(() => {
|
||||
const validSelectedUsers = selectedUsers.filter((userId) =>
|
||||
users.some((user) => user.id === userId)
|
||||
);
|
||||
|
||||
if (validSelectedUsers.length !== selectedUsers.length) {
|
||||
setSelectedUsers(validSelectedUsers);
|
||||
}
|
||||
|
||||
const allDisplayedSelected =
|
||||
users.every((user) => validSelectedUsers.includes(user.id)) ?? false;
|
||||
setSelectAll(allDisplayedSelected && users.length > 0);
|
||||
}, [users, selectedUsers]);
|
||||
|
||||
return (
|
||||
<View className="flex-1">
|
||||
<UserTableControls
|
||||
searchQuery={searchQuery}
|
||||
selectAll={selectAll}
|
||||
selectedItems={selectedUsers}
|
||||
menuVisible={menuVisible}
|
||||
menuAnchor={menuAnchor}
|
||||
selectedRisks={selectedRisks}
|
||||
onSearch={handleSearch}
|
||||
onSelectAll={handleSelectAll}
|
||||
onBulkDelete={handleBulkDelete}
|
||||
onMenuDismiss={() => setMenuVisible(false)}
|
||||
onItemsPerPageChange={handleItemsPerPageChange}
|
||||
onSelectRisks={handleSelectRisks}
|
||||
onAddUser={onAddUser}
|
||||
onAddingUser={onAddingUser}
|
||||
itemsPerPage={itemsPerPage}
|
||||
/>
|
||||
|
||||
{users.length === 0 ? (
|
||||
<View
|
||||
className={`flex-1 items-center justify-center ${
|
||||
isMobile ? "p-1" : "p-5"
|
||||
}`}
|
||||
>
|
||||
<Text className="text-lg text-gray-500">
|
||||
No users match your search{searchQuery && ` for "${searchQuery}"`}
|
||||
</Text>
|
||||
</View>
|
||||
) : isMobile ? (
|
||||
<MobileUserAccountsTable
|
||||
users={users}
|
||||
selectedUsers={selectedUsers}
|
||||
onSelectUser={handleSelectUser}
|
||||
onEdit={handleEdit}
|
||||
onLock={handleLock}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
) : (
|
||||
<ScrollView className="flex-1">
|
||||
<DesktopUserAccountsTable
|
||||
users={users}
|
||||
selectedUsers={selectedUsers}
|
||||
sortColumn={sortColumn}
|
||||
sortDirection={sortDirection}
|
||||
onSort={handleSort}
|
||||
onSelectUser={handleSelectUser}
|
||||
onEdit={handleEdit}
|
||||
onLock={handleLock}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
</ScrollView>
|
||||
)}
|
||||
|
||||
<TablePagination
|
||||
page={page}
|
||||
itemsPerPage={itemsPerPage}
|
||||
totalItems={totalItems}
|
||||
from={from}
|
||||
to={to}
|
||||
onPageChange={onPageChange}
|
||||
onItemsPerPageButtonPress={(event: GestureResponderEvent) => {
|
||||
const { pageX, pageY } = event.nativeEvent;
|
||||
setMenuAnchor({ x: pageX, y: pageY });
|
||||
setMenuVisible(true);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user