@@ -6,9 +6,10 @@ import {
6
6
Link ,
7
7
useLoaderData ,
8
8
useRouteLoaderData ,
9
+ useSearchParams ,
9
10
} from "@remix-run/react" ;
10
11
11
- import { UserPlus , UserX , MailX } from "lucide-react" ;
12
+ import { ArrowDown , UserPlus , UserX , MailX } from "lucide-react" ;
12
13
13
14
import { Button } from "~/components/ui/button" ;
14
15
@@ -62,6 +63,9 @@ export const loader: LoaderFunction = async ({ request, params }) => {
62
63
isAdmin : true ,
63
64
isSuperAdmin : true ,
64
65
} ,
66
+ orderBy : {
67
+ firstName : "asc" ,
68
+ } ,
65
69
} ) ;
66
70
const invitations = await prisma . userInvitation . findMany ( {
67
71
select : {
@@ -91,6 +95,52 @@ export default function UserIndexPage() {
91
95
const { program } = useRouteLoaderData < typeof programLoader > (
92
96
"routes/org.program.$programId" ,
93
97
) ;
98
+ const [ searchParams , setSearchParams ] = useSearchParams ( ) ;
99
+
100
+ let sortedUser = user ;
101
+ if ( searchParams . has ( "sort" ) ) {
102
+ switch ( searchParams . get ( "sort" ) ) {
103
+ case "name" :
104
+ sortedUser = user . toSorted ( ( a : User , b : User ) => {
105
+ if ( a . firstName < b . firstName ) {
106
+ return - 1 ;
107
+ }
108
+ if ( a . firstName > b . firstName ) {
109
+ return 1 ;
110
+ }
111
+ return 0 ;
112
+ } ) ;
113
+ break ;
114
+ case "email" :
115
+ sortedUser = user . toSorted ( ( a : User , b : User ) => {
116
+ if ( a . email < b . email ) {
117
+ return - 1 ;
118
+ }
119
+ if ( a . email > b . email ) {
120
+ return 1 ;
121
+ }
122
+ return 0 ;
123
+ } ) ;
124
+ break ;
125
+ case "permission" :
126
+ sortedUser = user . toSorted ( ( a : User , b : User ) => {
127
+ if ( a . isSuperAdmin && ! b . isSuperAdmin ) {
128
+ return - 1 ;
129
+ }
130
+ if ( ! a . isAdmin && b . isAdmin ) {
131
+ return 1 ;
132
+ }
133
+ if ( a . isAdmin && ! b . isAdmin ) {
134
+ return - 1 ;
135
+ }
136
+ if ( ! a . isSuperAdmin && b . isSuperAdmin ) {
137
+ return 1 ;
138
+ }
139
+ return 0 ;
140
+ } ) ;
141
+ break ;
142
+ }
143
+ }
94
144
95
145
return (
96
146
< div className = "flex flex-col gap-4" >
@@ -109,9 +159,52 @@ export default function UserIndexPage() {
109
159
< Table >
110
160
< TableHeader >
111
161
< TableRow >
112
- < TableHead > Name</ TableHead >
113
- < TableHead className = "font-medium" > Email</ TableHead >
114
- < TableHead > Permissions</ TableHead >
162
+ < TableHead >
163
+ < Button
164
+ variant = "ghost"
165
+ className = "pl-0"
166
+ onClick = { ( ) => {
167
+ const params = new URLSearchParams ( ) ;
168
+ params . set ( "sort" , "name" ) ;
169
+ setSearchParams ( params , {
170
+ preventScrollReset : true ,
171
+ } ) ;
172
+ } }
173
+ >
174
+ Name { searchParams . get ( "sort" ) === "name" && < ArrowDown /> }
175
+ </ Button >
176
+ </ TableHead >
177
+ < TableHead className = "font-medium" >
178
+ < Button
179
+ variant = "ghost"
180
+ className = "pl-0"
181
+ onClick = { ( ) => {
182
+ const params = new URLSearchParams ( ) ;
183
+ params . set ( "sort" , "email" ) ;
184
+ setSearchParams ( params , {
185
+ preventScrollReset : true ,
186
+ } ) ;
187
+ } }
188
+ >
189
+ Email { searchParams . get ( "sort" ) === "email" && < ArrowDown /> }
190
+ </ Button >
191
+ </ TableHead >
192
+ < TableHead >
193
+ < Button
194
+ variant = "ghost"
195
+ className = "pl-0"
196
+ onClick = { ( ) => {
197
+ const params = new URLSearchParams ( ) ;
198
+ params . set ( "sort" , "permission" ) ;
199
+ setSearchParams ( params , {
200
+ preventScrollReset : true ,
201
+ } ) ;
202
+ } }
203
+ >
204
+ Permissions{ " " }
205
+ { searchParams . get ( "sort" ) === "permission" && < ArrowDown /> }
206
+ </ Button >
207
+ </ TableHead >
115
208
< TableHead > </ TableHead >
116
209
</ TableRow >
117
210
</ TableHeader >
@@ -139,7 +232,7 @@ export default function UserIndexPage() {
139
232
</ TableCell >
140
233
</ TableRow >
141
234
) ) }
142
- { user . map ( ( u : User ) => (
235
+ { sortedUser . map ( ( u : User ) => (
143
236
< TableRow key = { u . id } >
144
237
< TableCell >
145
238
{ u . firstName } { u . lastName }
0 commit comments