Skip to content

Commit 3a1e630

Browse files
committed
Add filter users
1 parent 8e6cfe6 commit 3a1e630

File tree

3 files changed

+41
-17
lines changed

3 files changed

+41
-17
lines changed

frontend/src/presentation/components/QuestionFilters.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ export const QuestionFilters: React.FC<QuestionFiltersProps> = ({
214214

215215
{showSearchBar && (
216216
<div className={styles.searchBarContainer}>
217-
<SearchBar searchTerm={searchTerm} onSearch={handleSearch} />
217+
<SearchBar searchTerm={searchTerm} onSearch={handleSearch} placeholder="Search questions..." />
218218
</div>
219219
)}
220220
</div>

frontend/src/presentation/components/SearchBar.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import styles from "./SearchBar.module.css";
66
interface SearchBarProps {
77
searchTerm: string;
88
onSearch: (term: string) => void;
9+
placeholder?: string;
910
}
1011

11-
export const SearchBar: React.FC<SearchBarProps> = ({ searchTerm, onSearch }) => {
12+
export const SearchBar: React.FC<SearchBarProps> = ({ searchTerm, onSearch, placeholder }) => {
1213
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
1314
onSearch(e.target.value);
1415
};
@@ -17,7 +18,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({ searchTerm, onSearch }) =>
1718
<div className={styles.searchBarWrapper}>
1819
<SearchOutlined className={styles.searchIcon} />
1920
<Input
20-
placeholder="Search questions..."
21+
placeholder={placeholder ?? "Search..."}
2122
value={searchTerm}
2223
onChange={handleInputChange}
2324
allowClear

frontend/src/presentation/pages/UserManagement.tsx

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import { User } from "domain/entities/User";
22
import { userUseCases } from "domain/usecases/UserUseCases";
3-
import { useEffect, useState } from "react";
3+
import { useEffect, useMemo, useState } from "react";
44
import { EditOutlined, DeleteOutlined, CrownFilled, CrownOutlined } from "@ant-design/icons";
55
import styles from "./UserManagement..module.css";
66
import { Modal } from "antd";
77
import { UpdateProfileForm } from "presentation/components/UpdateProfileForm/UpdateProfileForm";
88
import { DeleteUserForm } from "presentation/components/DeleteUserForm/DeleteUserForm";
99
import { UpdateUserPrivilegeForm } from "presentation/components/UpdateUserPrivilegeForm/UpdateUserPrivilegeForm";
10-
10+
import { useAuth } from "domain/context/AuthContext";
11+
import { SearchBar } from "presentation/components/SearchBar";
1112

1213
export const UserManagement: React.FC<{}> = () => {
1314
const [users, setUsers] = useState<User[]>([]);
14-
1515
const [editingUser, setEditingUser] = useState<User | null>(null);
1616
const [deletingUser, setDeletingUser] = useState<User | null>(null);
1717
const [promotingUser, setPromotingUser] = useState<User | null>(null);
18+
const [searchTerm, setSearchTerm] = useState<string>("");
19+
20+
const { user: currUser } = useAuth();
1821

1922
useEffect(() => {
2023
const getAllUsers = async () => {
@@ -24,21 +27,40 @@ export const UserManagement: React.FC<{}> = () => {
2427
getAllUsers();
2528
}, []);
2629

27-
const sortedUsers = users.sort((u1, u2) => {
28-
if (u1.isAdmin && !u2.isAdmin) {
29-
return -1;
30-
} else if (!u1.isAdmin && u2.isAdmin) {
31-
return 1;
32-
} else {
33-
return u1.username.localeCompare(u2.username);
34-
}
35-
});
30+
const sortedUsers = useMemo(
31+
() =>
32+
users.sort((u1, u2) => {
33+
if (u1._id === currUser?._id) {
34+
return -1;
35+
}
36+
37+
if (u2._id === currUser?._id) {
38+
return 1;
39+
}
40+
if (u1.isAdmin && !u2.isAdmin) {
41+
return -1;
42+
}
43+
44+
if (!u1.isAdmin && u2.isAdmin) {
45+
return 1;
46+
}
47+
return u1.username.localeCompare(u2.username);
48+
}),
49+
[users]
50+
);
51+
52+
const filteredUsers = useMemo(
53+
() => sortedUsers.filter((user) => user.username.toLowerCase().includes(searchTerm.toLowerCase())),
54+
[sortedUsers, searchTerm]
55+
);
3656

3757
const renderUser = (user: User) => {
3858
return (
3959
<div className={styles.userRow} key={user._id}>
4060
<div className={styles.username}>
41-
<p>{user.username}</p>
61+
<p>
62+
{user.username} {currUser?._id === user._id && <span style={{ color: "gray" }}>(you)</span>}
63+
</p>
4264
{user.isAdmin && <CrownFilled />}
4365
</div>
4466

@@ -84,7 +106,8 @@ export const UserManagement: React.FC<{}> = () => {
84106

85107
return (
86108
<div className={styles.container}>
87-
{sortedUsers.map((user) => renderUser(user))}
109+
<SearchBar searchTerm={searchTerm} onSearch={(s) => setSearchTerm(s)} placeholder="Search users..." />
110+
{filteredUsers.map((user) => renderUser(user))}
88111
{editingUser && (
89112
<Modal
90113
open={editingUser !== null}

0 commit comments

Comments
 (0)