1- import { HStack , Input , Button , Box , Icon , Menu , Text , Flex } from '@chakra-ui/react' ;
2- import { X , CheckCircle } from 'lucide-react' ;
1+ import {
2+ Box ,
3+ Button ,
4+ Flex ,
5+ HStack ,
6+ Icon ,
7+ Input ,
8+ Text ,
9+ Menu
10+ } from '@chakra-ui/react' ; import { X } from 'lucide-react' ;
311import type { LiveStatusParams } from '@/api/types' ;
412import { MdSearch , MdExpandMore } from 'react-icons/md' ;
513
@@ -13,6 +21,7 @@ interface StatusFiltersProps {
1321 groupByOptions ?: string [ ] ;
1422 searchTerm ?: string ;
1523 onSearchChange ?: ( searchTerm : string ) => void ;
24+ onToggleGroupBy ?: ( groupBy : string , isSelected : boolean ) => void ;
1625}
1726
1827export function StatusFilters ( {
@@ -23,6 +32,7 @@ export function StatusFilters({
2332 groupByOptions = [ ] ,
2433 searchTerm = '' ,
2534 onSearchChange,
35+ onToggleGroupBy,
2636} : StatusFiltersProps ) {
2737 const handleGroupChange = ( value : string ) => {
2838 onFiltersChange ( {
@@ -95,7 +105,7 @@ export function StatusFilters({
95105 </ Menu . Trigger >
96106 < Menu . Positioner >
97107 < Menu . Content >
98- < Menu . Item key = { 'all' } value = { '' } onSelect = { ( ) => handleGroupChange ( '' ) } >
108+ < Menu . Item value = { '' } onSelect = { ( ) => handleGroupChange ( '' ) } >
99109 All Groups
100110 </ Menu . Item >
101111 { groups . map ( group => (
@@ -110,7 +120,7 @@ export function StatusFilters({
110120 { /* Search Input */ }
111121 < Flex w = '80' position = 'relative' align = 'center' >
112122 < Icon
113- as = { MdSearch }
123+ as = { MdSearch }
114124 color = 'gray.400'
115125 position = 'absolute'
116126 left = '3'
@@ -144,6 +154,8 @@ export function StatusFilters({
144154 </ Box >
145155 ) }
146156 </ Flex >
157+
158+ { /* Group By Dropdown */ }
147159 < Menu . Root >
148160 < Menu . Trigger asChild >
149161 < Button
@@ -159,33 +171,78 @@ export function StatusFilters({
159171 < MdExpandMore />
160172 </ Button >
161173 </ Menu . Trigger >
162- < Menu . Positioner >
163- < Menu . Content >
164- < Menu . Item
165- value = "status"
166- onSelect = { ( ) => {
167- onGroupByChange && onGroupByChange ( 'status' ) ;
168- } }
169- >
170- < HStack w = "full" justify = "space-between" align = "center" >
171- < Text as = "span" > Group by Status</ Text >
172- { groupByOptions . includes ( 'status' ) && < CheckCircle size = { 16 } color = "green" /> }
174+ < Menu . Positioner px = { 4 } >
175+ < Menu . Content minWidth = "200px" borderColor = "gray.300" >
176+ < Flex justify = "flex-end" px = { 2 } py = { 1 } borderBottom = "1px solid" borderColor = "gray.200" >
177+ < HStack gap = { 2 } >
178+ < Button
179+ size = "xs"
180+ variant = "ghost"
181+ onClick = { ( ) => {
182+ [ 'status' , 'group' ] . forEach ( opt =>
183+ onToggleGroupBy && onToggleGroupBy ( opt , true )
184+ ) ;
185+ } }
186+ textDecoration = { 'underline' }
187+ >
188+ Select All
189+ </ Button >
190+ < Button
191+ size = "xs"
192+ variant = "ghost"
193+ onClick = { ( ) => {
194+ [ 'status' , 'group' ] . forEach ( opt =>
195+ onToggleGroupBy && onToggleGroupBy ( opt , false )
196+ ) ;
197+ } }
198+ textDecoration = { 'underline' }
199+ >
200+ Clear
201+ </ Button >
173202 </ HStack >
174- </ Menu . Item >
175- < Menu . Item
176- value = "group"
177- onSelect = { ( ) => {
178- onGroupByChange && onGroupByChange ( 'group' ) ;
179- } }
180- >
181- < HStack w = "full" justify = "space-between" align = "center" >
182- < Text as = "span" > Group by Group</ Text >
183- { groupByOptions . includes ( 'group' ) && < CheckCircle size = { 16 } color = "green" /> }
184- </ HStack >
185- </ Menu . Item >
203+ </ Flex >
204+ < Menu . ItemGroup >
205+ < Menu . CheckboxItem
206+ cursor = { 'pointer' }
207+ value = "status"
208+ checked = { groupByOptions . includes ( 'status' ) }
209+ onCheckedChange = { ( ) => {
210+ onToggleGroupBy && onToggleGroupBy ( 'status' , ! groupByOptions . includes ( 'status' ) ) ;
211+ } }
212+ >
213+ < Flex
214+ w = "full"
215+ justify = "flex-start"
216+ align = "center"
217+ gap = { 3 }
218+ >
219+ < Text as = "span" > Group by Status</ Text >
220+ < Menu . ItemIndicator />
221+ </ Flex >
222+ </ Menu . CheckboxItem >
223+ < Menu . CheckboxItem
224+ cursor = { 'pointer' }
225+ value = "group"
226+ checked = { groupByOptions . includes ( 'group' ) }
227+ onCheckedChange = { ( ) => {
228+ onToggleGroupBy && onToggleGroupBy ( 'group' , ! groupByOptions . includes ( 'group' ) ) ;
229+ } }
230+ >
231+ < Flex
232+ w = "full"
233+ justify = "flex-start"
234+ align = "center"
235+ gap = { 3 }
236+ >
237+ < Text as = "span" > Group by Group</ Text >
238+ < Menu . ItemIndicator />
239+ </ Flex >
240+ </ Menu . CheckboxItem >
241+ </ Menu . ItemGroup >
186242 </ Menu . Content >
187243 </ Menu . Positioner >
188244 </ Menu . Root >
245+
189246 { /* Clear Filters */ }
190247 { hasFilters && (
191248 < Button
0 commit comments