Spaces:
Running
Running
James McCool
commited on
Commit
·
9f63aed
1
Parent(s):
f0d329b
Add sorting functionality to DataTable component with visual indicators for column headers
Browse files- src/components/DataTable.jsx +70 -5
src/components/DataTable.jsx
CHANGED
@@ -6,6 +6,7 @@ const DataTable = () => {
|
|
6 |
const [data, setData] = useState([]);
|
7 |
const [loading, setLoading] = useState(true);
|
8 |
const [error, setError] = useState(null);
|
|
|
9 |
|
10 |
// Mock data for demonstration - replace with actual MongoDB data
|
11 |
const mockData = [
|
@@ -24,6 +25,48 @@ const DataTable = () => {
|
|
24 |
}, 1000);
|
25 |
}, []);
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
const fetchFromMongoDB = async () => {
|
28 |
try {
|
29 |
setLoading(true);
|
@@ -57,6 +100,8 @@ const DataTable = () => {
|
|
57 |
);
|
58 |
}
|
59 |
|
|
|
|
|
60 |
return (
|
61 |
<div className="w-full mx-auto p-6">
|
62 |
<div className="flex justify-between items-center mb-6">
|
@@ -71,14 +116,34 @@ const DataTable = () => {
|
|
71 |
<TableCaption>A list of users from the database.</TableCaption>
|
72 |
<TableHeader>
|
73 |
<TableRow>
|
74 |
-
<TableHead
|
75 |
-
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
</TableRow>
|
79 |
</TableHeader>
|
80 |
<TableBody>
|
81 |
-
{
|
82 |
<TableRow key={user.id}>
|
83 |
<TableCell className="font-medium">{user.id}</TableCell>
|
84 |
<TableCell>{user.name}</TableCell>
|
|
|
6 |
const [data, setData] = useState([]);
|
7 |
const [loading, setLoading] = useState(true);
|
8 |
const [error, setError] = useState(null);
|
9 |
+
const [sortConfig, setSortConfig] = useState({ key: null, direction: 'asc' });
|
10 |
|
11 |
// Mock data for demonstration - replace with actual MongoDB data
|
12 |
const mockData = [
|
|
|
25 |
}, 1000);
|
26 |
}, []);
|
27 |
|
28 |
+
// Sorting function
|
29 |
+
const sortData = (key) => {
|
30 |
+
let direction = 'asc';
|
31 |
+
|
32 |
+
// If clicking the same column, toggle direction
|
33 |
+
if (sortConfig.key === key && sortConfig.direction === 'asc') {
|
34 |
+
direction = 'desc';
|
35 |
+
}
|
36 |
+
|
37 |
+
setSortConfig({ key, direction });
|
38 |
+
};
|
39 |
+
|
40 |
+
// Get sorted data
|
41 |
+
const getSortedData = () => {
|
42 |
+
if (!sortConfig.key) return data;
|
43 |
+
|
44 |
+
return [...data].sort((a, b) => {
|
45 |
+
let aValue = a[sortConfig.key];
|
46 |
+
let bValue = b[sortConfig.key];
|
47 |
+
|
48 |
+
// Handle string comparison (case-insensitive)
|
49 |
+
if (typeof aValue === 'string') {
|
50 |
+
aValue = aValue.toLowerCase();
|
51 |
+
bValue = bValue.toLowerCase();
|
52 |
+
}
|
53 |
+
|
54 |
+
if (aValue < bValue) {
|
55 |
+
return sortConfig.direction === 'asc' ? -1 : 1;
|
56 |
+
}
|
57 |
+
if (aValue > bValue) {
|
58 |
+
return sortConfig.direction === 'asc' ? 1 : -1;
|
59 |
+
}
|
60 |
+
return 0;
|
61 |
+
});
|
62 |
+
};
|
63 |
+
|
64 |
+
// Get sort indicator for column headers
|
65 |
+
const getSortIndicator = (key) => {
|
66 |
+
if (sortConfig.key !== key) return '↕️';
|
67 |
+
return sortConfig.direction === 'asc' ? '↑' : '↓';
|
68 |
+
};
|
69 |
+
|
70 |
const fetchFromMongoDB = async () => {
|
71 |
try {
|
72 |
setLoading(true);
|
|
|
100 |
);
|
101 |
}
|
102 |
|
103 |
+
const sortedData = getSortedData();
|
104 |
+
|
105 |
return (
|
106 |
<div className="w-full mx-auto p-6">
|
107 |
<div className="flex justify-between items-center mb-6">
|
|
|
116 |
<TableCaption>A list of users from the database.</TableCaption>
|
117 |
<TableHeader>
|
118 |
<TableRow>
|
119 |
+
<TableHead
|
120 |
+
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
121 |
+
onClick={() => sortData('id')}
|
122 |
+
>
|
123 |
+
ID {getSortIndicator('id')}
|
124 |
+
</TableHead>
|
125 |
+
<TableHead
|
126 |
+
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
127 |
+
onClick={() => sortData('name')}
|
128 |
+
>
|
129 |
+
Name {getSortIndicator('name')}
|
130 |
+
</TableHead>
|
131 |
+
<TableHead
|
132 |
+
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
133 |
+
onClick={() => sortData('email')}
|
134 |
+
>
|
135 |
+
Email {getSortIndicator('email')}
|
136 |
+
</TableHead>
|
137 |
+
<TableHead
|
138 |
+
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
139 |
+
onClick={() => sortData('role')}
|
140 |
+
>
|
141 |
+
Role {getSortIndicator('role')}
|
142 |
+
</TableHead>
|
143 |
</TableRow>
|
144 |
</TableHeader>
|
145 |
<TableBody>
|
146 |
+
{sortedData.map((user) => (
|
147 |
<TableRow key={user.id}>
|
148 |
<TableCell className="font-medium">{user.id}</TableCell>
|
149 |
<TableCell>{user.name}</TableCell>
|