Skip to content

Commit ec00db2

Browse files
authored
Merge pull request #804 from darkhorse-420/Search
feat: Implemented search and pagination in Dashboard
2 parents d6d93e0 + 06d7042 commit ec00db2

File tree

9 files changed

+486
-56
lines changed

9 files changed

+486
-56
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
.filtering-container {
2+
position: relative;
3+
display: inline-block;
4+
padding-bottom: 10px;
5+
}
6+
7+
.dropdown-toggle {
8+
padding: 10px 10px;
9+
padding-right: 10px;
10+
border: 1px solid #ccc;
11+
border-radius: 5px;
12+
background-color: #fff;
13+
color: #333;
14+
cursor: pointer;
15+
font-size: 14px;
16+
text-align: left;
17+
width: 130px;
18+
display: inline-flex;
19+
align-items: center;
20+
justify-content: space-between;
21+
}
22+
23+
.dropdown-toggle:hover {
24+
background-color: #f0f0f0;
25+
}
26+
27+
.dropdown-arrow {
28+
border: none;
29+
background: none;
30+
cursor: pointer;
31+
font-size: 15px;
32+
margin-left: 1px;
33+
margin-right: 10px;
34+
}
35+
36+
.dropdown-menu {
37+
position: absolute;
38+
background-color: #fff;
39+
border: 1px solid #ccc;
40+
border-radius: 5px;
41+
margin-top: 5px;
42+
z-index: 1000;
43+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
44+
}
45+
46+
.dropdown-item {
47+
padding: 10px 15px;
48+
cursor: pointer;
49+
font-size: 14px;
50+
color: #333;
51+
}
52+
53+
.dropdown-item:hover {
54+
background-color: #f0f0f0;
55+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React, { useState } from 'react';
2+
import './Filtering.css';
3+
4+
const Filtering = ({ onFilterChange }) => {
5+
const [isOpen, setIsOpen] = useState(false); // State to toggle dropdown open/close
6+
const [selectedOption, setSelectedOption] = useState('Sort by'); // Initial state
7+
const [sortOrder, setSortOrder] = useState('asc'); // Track sort order (asc/desc)
8+
9+
const toggleDropdown = () => {
10+
setIsOpen(!isOpen); // Toggle dropdown open/close state
11+
};
12+
13+
const toggleSortOrder = () => {
14+
// Toggle sort order only if an option is selected
15+
if (selectedOption !== 'Sort by') {
16+
const newSortOrder = sortOrder === 'asc' ? 'desc' : 'asc';
17+
setSortOrder(newSortOrder);
18+
onFilterChange(selectedOption, newSortOrder); // Trigger filtering with new order
19+
}
20+
};
21+
22+
const handleOptionClick = (option) => {
23+
// Handle filter option selection
24+
setSelectedOption(option);
25+
onFilterChange(option, sortOrder); // Call the parent function with selected filter and order
26+
setIsOpen(false); // Collapse the dropdown after selection
27+
};
28+
29+
return (
30+
<div className="filtering-container">
31+
<div className="dropdown">
32+
{/* Make the entire button clickable for toggling dropdown */}
33+
<button onClick={toggleDropdown} className="dropdown-toggle">
34+
{selectedOption}
35+
{/* Render the up/down arrow next to selected option */}
36+
{selectedOption !== 'Sort by' && (
37+
<span onClick={(e) => { e.stopPropagation(); toggleSortOrder(); }}>
38+
{sortOrder === 'asc' ? ' ↑' : ' ↓'}
39+
</span>
40+
)}
41+
<span className="dropdown-arrow"></span>
42+
</button>
43+
44+
{isOpen && (
45+
<div className="dropdown-menu">
46+
<div onClick={() => handleOptionClick('Date Modified')} className="dropdown-item">
47+
Date Modified
48+
</div>
49+
<div onClick={() => handleOptionClick('Date Created')} className="dropdown-item">
50+
Date Created
51+
</div>
52+
<div onClick={() => handleOptionClick('Alphabetical')} className="dropdown-item">
53+
Alphabetical
54+
</div>
55+
</div>
56+
)}
57+
</div>
58+
</div>
59+
);
60+
};
61+
62+
export default Filtering;
63+
64+
65+
66+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.paginationContainer {
2+
display: flex;
3+
justify-content: center;
4+
padding: 1rem;
5+
margin-top: 20px;
6+
gap: 10px;
7+
}
8+
9+
.pageButton {
10+
padding: 8px 12px;
11+
font-size: 14px;
12+
color: #333;
13+
border: 1px solid #ccc;
14+
background-color: #f9f9f9;
15+
cursor: pointer;
16+
border-radius: 5px;
17+
transition: background-color 0.3s ease;
18+
}
19+
20+
.pageButton:hover {
21+
background-color: #e2e6ea;
22+
}
23+
24+
.activeButton {
25+
background-color: #007bff;
26+
color: #fff;
27+
border-color: #007bff;
28+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react';
2+
import './Pagination.css';
3+
4+
export default function Pagination({ currentPage, totalItems = 0, itemsPerPage, onPageChange }) {
5+
6+
const totalPages = Math.ceil(totalItems / itemsPerPage);
7+
8+
const handlePageClick = (page) => {
9+
if (page >= 1 && page <= totalPages) {
10+
onPageChange(page);
11+
}
12+
};
13+
14+
return (
15+
<div className='paginationContainer'>
16+
<button
17+
className='pageButton'
18+
onClick={() => handlePageClick(currentPage - 1)}
19+
disabled={currentPage === 1}
20+
>
21+
Previous
22+
</button>
23+
24+
<span>
25+
Page {currentPage} of {totalPages}
26+
</span>
27+
28+
<button
29+
className='pageButton'
30+
onClick={() => handlePageClick(currentPage + 1)}
31+
disabled={currentPage === totalPages}
32+
>
33+
Next
34+
</button>
35+
</div>
36+
);
37+
}

src/ui/components/Search/Search.css

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.search-bar {
2+
width: 100%;
3+
max-width:100%;
4+
margin: 0 auto 20px auto;
5+
}
6+
7+
.search-input {
8+
width: 100%;
9+
padding: 10px;
10+
font-size: 16px;
11+
border: 1px solid #ccc;
12+
border-radius: 4px;
13+
box-sizing: border-box;
14+
}
15+
16+
.search-input:focus {
17+
border-color: #007bff;
18+
}

src/ui/components/Search/Search.jsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react';
2+
import { TextField } from '@material-ui/core';
3+
import './Search.css';
4+
import InputAdornment from '@material-ui/core/InputAdornment';
5+
import SearchIcon from '@material-ui/icons/Search';
6+
7+
8+
export default function Search({ onSearch }) {
9+
const handleSearchChange = (event) => {
10+
const query = event.target.value;
11+
onSearch(query);
12+
};
13+
14+
return (
15+
<div style={{ margin: '20px 0' }}>
16+
<TextField
17+
label="Search"
18+
variant="outlined"
19+
fullWidth
20+
margin="normal"
21+
onChange={handleSearchChange}
22+
placeholder="Search..."
23+
InputProps={{
24+
startAdornment: (
25+
<InputAdornment position="start">
26+
<SearchIcon />
27+
</InputAdornment>
28+
),
29+
}}
30+
/>
31+
</div>
32+
);
33+
}
34+
35+
36+
37+

0 commit comments

Comments
 (0)