@@ -253,7 +253,8 @@ fun DiscoveryScreen(
253253 uiState = uiState,
254254 isLoggedIn = token != null ,
255255 onQuickFilterSelect = viewModel::onQuickFilterSelected,
256- onCategorySelect = viewModel::onCategorySelected,
256+ onCategoryToggle = viewModel::onCategoryToggled,
257+ onSortSelect = viewModel::onSortSelected,
257258 onBookmarkedToggle = viewModel::onBookmarkedOnlyToggle,
258259 onGoingToggle = viewModel::onGoingOnlyToggle,
259260 onWheelchairToggle = viewModel::onWheelchairToggle,
@@ -510,7 +511,7 @@ private fun FilterSheetContent(
510511 uiState : DiscoveryUiState ,
511512 isLoggedIn : Boolean ,
512513 onQuickFilterSelect : (String? ) -> Unit ,
513- onCategorySelect : (String? ) -> Unit ,
514+ onCategoryToggle : (String ) -> Unit ,
514515 onBookmarkedToggle : () -> Unit ,
515516 onGoingToggle : () -> Unit ,
516517 onWheelchairToggle : () -> Unit ,
@@ -521,12 +522,13 @@ private fun FilterSheetContent(
521522 onQuietFriendlyToggle : () -> Unit ,
522523 onSuggestedToggle : () -> Unit ,
523524 onProximitySortToggle : () -> Unit ,
525+ onSortSelect : (String? ) -> Unit ,
524526 onClear : () -> Unit ,
525527 onApply : () -> Unit
526528) {
527- val hasAnyFilter = uiState.selectedQuickFilter != null || uiState.selectedCategoryId != null ||
529+ val hasAnyFilter = uiState.selectedQuickFilter != null || uiState.selectedCategoryIds.isNotEmpty() ||
528530 uiState.bookmarkedOnly || uiState.goingOnly || uiState.hasAccessibilityFilter ||
529- uiState.proximitySort || uiState.suggestedActive
531+ uiState.proximitySort || uiState.suggestedActive || uiState.selectedSort != null
530532
531533 Column (modifier = Modifier .fillMaxWidth().padding(bottom = 32 .dp)) {
532534 // Header
@@ -552,88 +554,23 @@ private fun FilterSheetContent(
552554 .padding(horizontal = 20 .dp, vertical = 16 .dp),
553555 verticalArrangement = Arrangement .spacedBy(20 .dp)
554556 ) {
555- // ── Quick Filters ──────────────────────────────────────────────────
556- FilterSectionLabel (" QUICK FILTERS" )
557- Row (
558- modifier = Modifier .horizontalScroll(rememberScrollState()),
559- horizontalArrangement = Arrangement .spacedBy(8 .dp)
560- ) {
561- listOf (
562- " now" to " Now" ,
563- " today" to " Today" ,
564- " weekend" to " Weekend" ,
565- " this_week" to " This Week" ,
566- " upcoming" to " Upcoming" ,
567- " past" to " Past"
568- ).forEach { (key, label) ->
569- FilterPill (label = label, selected = uiState.selectedQuickFilter == key) {
570- onQuickFilterSelect(key)
571- }
572- }
573- if (isLoggedIn) {
574- FilterPill (" ✨ Suggested for you" , uiState.suggestedActive, onSuggestedToggle)
575- FilterPill (" 🔖 Bookmarked" , uiState.bookmarkedOnly, onBookmarkedToggle)
576- FilterPill (" ✓ Going" , uiState.goingOnly, onGoingToggle)
577- }
578- }
579-
557+ FilterQuickFiltersSection (uiState, isLoggedIn, onQuickFilterSelect,
558+ onBookmarkedToggle, onGoingToggle, onSuggestedToggle)
559+ HorizontalDivider (color = MaterialTheme .colorScheme.outline.copy(alpha = 0.15f ))
560+ FilterSortSection (uiState, onSortSelect)
580561 HorizontalDivider (color = MaterialTheme .colorScheme.outline.copy(alpha = 0.15f ))
581-
582- // ── Ranking & Proximity ────────────────────────────────────────────
583562 FilterSectionLabel (" RANKING" )
584563 FilterSwitchRow (
585564 label = " Proximity Ranking" ,
586565 sublabel = " Sort by distance from your current location" ,
587566 checked = uiState.proximitySort,
588567 onCheckedChange = { onProximitySortToggle() }
589568 )
590-
591569 HorizontalDivider (color = MaterialTheme .colorScheme.outline.copy(alpha = 0.15f ))
592-
593- // ── Accessibility ──────────────────────────────────────────────────
594- FilterSectionLabel (" ACCESSIBILITY" )
595- Column (verticalArrangement = Arrangement .spacedBy(4 .dp)) {
596- FilterSwitchRow (" Wheelchair Access" , checked = uiState.wheelchair,
597- onCheckedChange = { onWheelchairToggle() })
598- FilterSwitchRow (" Accessible Restroom" , checked = uiState.accessibleRestroom,
599- onCheckedChange = { onAccessibleRestroomToggle() })
600- FilterSwitchRow (" Elevator Available" , checked = uiState.elevator,
601- onCheckedChange = { onElevatorToggle() })
602- FilterSwitchRow (" Seating Available" , checked = uiState.seating,
603- onCheckedChange = { onSeatingToggle() })
604- FilterSwitchRow (" Captions Support" , checked = uiState.captions,
605- onCheckedChange = { onCaptionsToggle() })
606- FilterSwitchRow (" Quiet-Friendly" , checked = uiState.quietFriendly,
607- onCheckedChange = { onQuietFriendlyToggle() })
608- }
609-
570+ FilterAccessibilitySection (uiState, onWheelchairToggle, onAccessibleRestroomToggle,
571+ onElevatorToggle, onSeatingToggle, onCaptionsToggle, onQuietFriendlyToggle)
610572 HorizontalDivider (color = MaterialTheme .colorScheme.outline.copy(alpha = 0.15f ))
611-
612- // ── Category ───────────────────────────────────────────────────────
613- FilterSectionLabel (" CATEGORY" )
614- uiState.categories.forEach { cat ->
615- val selected = uiState.selectedCategoryId == cat.id
616- Row (
617- modifier = Modifier .fillMaxWidth().clip(RoundedCornerShape (10 .dp))
618- .clickable { onCategorySelect(cat.id) }
619- .padding(horizontal = 10 .dp, vertical = 10 .dp),
620- horizontalArrangement = Arrangement .SpaceBetween ,
621- verticalAlignment = Alignment .CenterVertically
622- ) {
623- Text (cat.name, fontSize = 14 .sp, color = MaterialTheme .colorScheme.onSurface)
624- Box (
625- modifier = Modifier .size(20 .dp).clip(RoundedCornerShape (4 .dp))
626- .background(
627- if (selected) MaterialTheme .colorScheme.primary
628- else MaterialTheme .colorScheme.outline.copy(alpha = 0.2f )
629- ),
630- contentAlignment = Alignment .Center
631- ) {
632- if (selected) Icon (Icons .Default .Check , null ,
633- tint = MaterialTheme .colorScheme.onPrimary, modifier = Modifier .size(14 .dp))
634- }
635- }
636- }
573+ FilterCategorySection (uiState, onCategoryToggle)
637574 }
638575
639576 Button (
@@ -647,6 +584,103 @@ private fun FilterSheetContent(
647584 }
648585}
649586
587+ @Composable
588+ private fun FilterQuickFiltersSection (
589+ uiState : DiscoveryUiState ,
590+ isLoggedIn : Boolean ,
591+ onQuickFilterSelect : (String? ) -> Unit ,
592+ onBookmarkedToggle : () -> Unit ,
593+ onGoingToggle : () -> Unit ,
594+ onSuggestedToggle : () -> Unit
595+ ) {
596+ FilterSectionLabel (" QUICK FILTERS" )
597+ Row (
598+ modifier = Modifier .horizontalScroll(rememberScrollState()),
599+ horizontalArrangement = Arrangement .spacedBy(8 .dp)
600+ ) {
601+ if (isLoggedIn) FilterPill (" ✨ Suggested for you" , uiState.suggestedActive, onSuggestedToggle)
602+ listOf (" now" to " Now" , " today" to " Today" , " weekend" to " Weekend" ,
603+ " this_week" to " This Week" , " upcoming" to " Upcoming" , " past" to " Past"
604+ ).forEach { (key, label) ->
605+ FilterPill (label = label, selected = uiState.selectedQuickFilter == key) {
606+ onQuickFilterSelect(key)
607+ }
608+ }
609+ if (isLoggedIn) {
610+ FilterPill (" 🔖 Bookmarked" , uiState.bookmarkedOnly, onBookmarkedToggle)
611+ FilterPill (" ✓ Going" , uiState.goingOnly, onGoingToggle)
612+ }
613+ }
614+ }
615+
616+ @Composable
617+ private fun FilterSortSection (uiState : DiscoveryUiState , onSortSelect : (String? ) -> Unit ) {
618+ FilterSectionLabel (" SORT BY" )
619+ Row (horizontalArrangement = Arrangement .spacedBy(8 .dp)) {
620+ listOf (" start_time" to " Start Time" , " category" to " Category" ).forEach { (key, label) ->
621+ FilterPill (
622+ label = label,
623+ selected = uiState.selectedSort == key && ! uiState.proximitySort
624+ ) { onSortSelect(if (uiState.selectedSort == key) null else key) }
625+ }
626+ }
627+ }
628+
629+ @Composable
630+ private fun FilterAccessibilitySection (
631+ uiState : DiscoveryUiState ,
632+ onWheelchairToggle : () -> Unit ,
633+ onAccessibleRestroomToggle : () -> Unit ,
634+ onElevatorToggle : () -> Unit ,
635+ onSeatingToggle : () -> Unit ,
636+ onCaptionsToggle : () -> Unit ,
637+ onQuietFriendlyToggle : () -> Unit
638+ ) {
639+ FilterSectionLabel (" ACCESSIBILITY" )
640+ Column (verticalArrangement = Arrangement .spacedBy(4 .dp)) {
641+ FilterSwitchRow (" Wheelchair Access" , checked = uiState.wheelchair,
642+ onCheckedChange = { onWheelchairToggle() })
643+ FilterSwitchRow (" Accessible Restroom" , checked = uiState.accessibleRestroom,
644+ onCheckedChange = { onAccessibleRestroomToggle() })
645+ FilterSwitchRow (" Elevator Available" , checked = uiState.elevator,
646+ onCheckedChange = { onElevatorToggle() })
647+ FilterSwitchRow (" Seating Available" , checked = uiState.seating,
648+ onCheckedChange = { onSeatingToggle() })
649+ FilterSwitchRow (" Captions Support" , checked = uiState.captions,
650+ onCheckedChange = { onCaptionsToggle() })
651+ FilterSwitchRow (" Quiet-Friendly" , checked = uiState.quietFriendly,
652+ onCheckedChange = { onQuietFriendlyToggle() })
653+ }
654+ }
655+
656+ @Composable
657+ private fun FilterCategorySection (uiState : DiscoveryUiState , onCategoryToggle : (String ) -> Unit ) {
658+ FilterSectionLabel (" CATEGORY" )
659+ uiState.categories.forEach { cat ->
660+ val selected = cat.id in uiState.selectedCategoryIds
661+ Row (
662+ modifier = Modifier .fillMaxWidth().clip(RoundedCornerShape (10 .dp))
663+ .clickable { onCategoryToggle(cat.id) }
664+ .padding(horizontal = 10 .dp, vertical = 10 .dp),
665+ horizontalArrangement = Arrangement .SpaceBetween ,
666+ verticalAlignment = Alignment .CenterVertically
667+ ) {
668+ Text (cat.name, fontSize = 14 .sp, color = MaterialTheme .colorScheme.onSurface)
669+ Box (
670+ modifier = Modifier .size(20 .dp).clip(RoundedCornerShape (4 .dp))
671+ .background(
672+ if (selected) MaterialTheme .colorScheme.primary
673+ else MaterialTheme .colorScheme.outline.copy(alpha = 0.2f )
674+ ),
675+ contentAlignment = Alignment .Center
676+ ) {
677+ if (selected) Icon (Icons .Default .Check , null ,
678+ tint = MaterialTheme .colorScheme.onPrimary, modifier = Modifier .size(14 .dp))
679+ }
680+ }
681+ }
682+ }
683+
650684@Composable
651685private fun FilterSectionLabel (text : String ) {
652686 Text (
0 commit comments