Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
package com.zenmo.web.zenmo.domains.lux.sections.luxmodels

import androidx.compose.runtime.*
import com.varabyte.kobweb.compose.css.TextTransform
import com.varabyte.kobweb.compose.foundation.layout.Arrangement
import com.varabyte.kobweb.compose.foundation.layout.Column
import com.varabyte.kobweb.compose.foundation.layout.Row
import com.varabyte.kobweb.compose.ui.Alignment
import com.varabyte.kobweb.compose.ui.Modifier
import com.varabyte.kobweb.compose.ui.modifiers.*
import com.varabyte.kobweb.compose.ui.modifiers.background
import com.varabyte.kobweb.compose.ui.modifiers.gap
import com.varabyte.kobweb.compose.ui.modifiers.margin
import com.varabyte.kobweb.compose.ui.toAttrs
import com.varabyte.kobweb.silk.components.icons.mdi.MdiLock
import com.varabyte.kobweb.silk.style.toModifier
import com.zenmo.web.zenmo.components.widgets.LangText
import com.zenmo.web.zenmo.components.widgets.SectionContainer
import com.zenmo.web.zenmo.domains.lux.components.LuxSectionContainer
import com.zenmo.web.zenmo.domains.lux.core.model.subdomain.subdomainModels
import com.zenmo.web.zenmo.domains.lux.core.toTwinModelCardItem
import com.zenmo.web.zenmo.domains.lux.sections.DeEmphasizedTextStyle
import com.zenmo.web.zenmo.domains.lux.sections.LuxSectionContainerStyleVariant
import com.zenmo.web.zenmo.domains.lux.sections.luxmodels.components.EmptyResults
import com.zenmo.web.zenmo.domains.lux.sections.luxmodels.components.SearchBar
import com.zenmo.web.zenmo.domains.lux.sections.luxmodels.components.filterAndSearchModels
import com.zenmo.web.zenmo.domains.lux.widgets.RadioRow
import com.zenmo.web.zenmo.domains.lux.sections.ResponsiveFlexStyle
import com.zenmo.web.zenmo.domains.lux.sections.application_fields.LuxApplicationArea
import com.zenmo.web.zenmo.domains.lux.sections.luxmodels.components.*
import com.zenmo.web.zenmo.domains.lux.widgets.TwinModelsGrid
import com.zenmo.web.zenmo.domains.lux.widgets.headings.HeaderText
import com.zenmo.web.zenmo.theme.SitePalette
import org.jetbrains.compose.web.css.Position
import org.jetbrains.compose.web.css.cssRem
import org.jetbrains.compose.web.css.px
import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.dom.P
import org.jetbrains.compose.web.dom.Span


enum class FilterType {
Expand All @@ -40,17 +35,13 @@ enum class FilterType {

@Composable
fun LuxModels() {
SectionContainer(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
LuxSectionContainer(
modifier =
Modifier
.background(SitePalette.light.overlay)
.position(Position.Relative)
.gap(5.cssRem),
variant = LuxSectionContainerStyleVariant
) {
var query by remember { mutableStateOf("") }
var selectedAreaOptions by remember { mutableStateOf(emptySet<LuxApplicationArea>()) }

val allModels =
(subdomainModels + com.zenmo.web.zenmo.domains.lux.subdomains.private_subdomains.drechtsteden.drechtstedenModels).map { it.toTwinModelCardItem() }
Expand Down Expand Up @@ -82,49 +73,41 @@ fun LuxModels() {
luxModels = filterAndSearchModels(
models = allModels,
query = query,
filterType = filterType
filterType = filterType,
areas = selectedAreaOptions
)
}
)

Column(
horizontalAlignment = Alignment.CenterHorizontally,
Div(
ResponsiveFlexStyle.toModifier()
.gap(0.5.cssRem)
.toAttrs()
) {
Span(
attrs = DeEmphasizedTextStyle.toModifier()
.textTransform(TextTransform.Uppercase)
.padding(bottom = 8.px)
.toAttrs()
) {
LangText(
en = "Access",
nl = "Toegang"
)
}
RadioRow(
value = filterType,
options = FilterType.entries.associateWith { it.name },
onChange = { type ->
ModelAccessFilter(
filterType = filterType,
onFilterChange = { type ->
filterType = type
luxModels = filterAndSearchModels(
models = allModels,
query = query,
filterType = filterType
filterType = filterType,
areas = selectedAreaOptions
)
}
) { option, _ ->
when (option) {
FilterType.ALL -> LangText(en = "All", nl = "Alle")
FilterType.PUBLIC -> LangText(en = "Public", nl = "Openbaar")
FilterType.PRIVATE -> Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.px)
) {
MdiLock(Modifier.fontSize(16.px))
LangText(en = "Private", nl = "Privé")
}
)
ModelAreaFilter(
selectedOptions = selectedAreaOptions,
onSelectionChange = {
selectedAreaOptions = it
luxModels = filterAndSearchModels(
models = allModels,
query = query,
filterType = filterType,
areas = selectedAreaOptions
)
}
}
)
}
}

Expand All @@ -136,4 +119,4 @@ fun LuxModels() {
EmptyResults()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.zenmo.web.zenmo.domains.lux.sections.luxmodels.components

import androidx.compose.runtime.Composable
import com.varabyte.kobweb.compose.foundation.layout.Arrangement
import com.varabyte.kobweb.compose.foundation.layout.Row
import com.varabyte.kobweb.compose.ui.Alignment
import com.varabyte.kobweb.compose.ui.Modifier
import com.varabyte.kobweb.compose.ui.modifiers.fontSize
import com.varabyte.kobweb.silk.components.icons.mdi.MdiLock
import com.zenmo.web.zenmo.components.widgets.LangText
import com.zenmo.web.zenmo.core.services.localization.LocalizedText
import com.zenmo.web.zenmo.domains.lux.sections.luxmodels.FilterType
import com.zenmo.web.zenmo.domains.lux.widgets.RadioRow
import org.jetbrains.compose.web.css.px

@Composable
fun ModelAccessFilter(
filterType: FilterType,
onFilterChange: (FilterType) -> Unit
) {
ModelFilter(
filterLabel = LocalizedText(en = "Access", nl = "Toegang")
) {
RadioRow(
value = filterType,
options = FilterType.entries.associateWith { it.name },
onChange = onFilterChange
) { option, _ ->
when (option) {
FilterType.ALL -> LangText(en = "All", nl = "Alle")
FilterType.PUBLIC -> LangText(en = "Public", nl = "Openbaar")
FilterType.PRIVATE -> Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.px)
) {
MdiLock(Modifier.fontSize(16.px))
LangText(en = "Private", nl = "Privé")
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.zenmo.web.zenmo.domains.lux.sections.luxmodels.components

import androidx.compose.runtime.Composable
import com.zenmo.web.zenmo.core.services.localization.Language
import com.zenmo.web.zenmo.core.services.localization.LocalLanguage
import com.zenmo.web.zenmo.core.services.localization.LocalizedText
import com.zenmo.web.zenmo.domains.lux.sections.application_fields.LuxApplicationArea
import com.zenmo.web.zenmo.domains.lux.widgets.MultiSelectRow

@Composable
fun ModelAreaFilter(
selectedOptions: Set<LuxApplicationArea>,
onSelectionChange: (Set<LuxApplicationArea>) -> Unit,
) {
val currentLanguage = LocalLanguage.current
ModelFilter(
filterLabel = LocalizedText(en = "Application Area", nl = "Toepassingsgebied")
) {
MultiSelectRow(
selectedValues = selectedOptions,
options = LuxApplicationArea.entries.associateWith {
when (currentLanguage) {
Language.Dutch -> it.label.nl
Language.English -> it.label.en
}
},
onChange = onSelectionChange
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.zenmo.web.zenmo.domains.lux.sections.luxmodels.components

import androidx.compose.runtime.Composable
import com.varabyte.kobweb.compose.css.TextTransform
import com.varabyte.kobweb.compose.foundation.layout.Column
import com.varabyte.kobweb.compose.ui.Alignment
import com.varabyte.kobweb.compose.ui.modifiers.gap
import com.varabyte.kobweb.compose.ui.modifiers.padding
import com.varabyte.kobweb.compose.ui.modifiers.textTransform
import com.varabyte.kobweb.compose.ui.toAttrs
import com.varabyte.kobweb.silk.style.toModifier
import com.zenmo.web.zenmo.components.widgets.LangText
import com.zenmo.web.zenmo.core.services.localization.LocalizedText
import com.zenmo.web.zenmo.domains.lux.sections.DeEmphasizedTextStyle
import com.zenmo.web.zenmo.domains.lux.sections.ResponsiveFlexStyle
import org.jetbrains.compose.web.css.cssRem
import org.jetbrains.compose.web.css.px
import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.dom.Span

@Composable
fun ModelFilter(
filterLabel: LocalizedText,
content: @Composable () -> Unit,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Span(
attrs = DeEmphasizedTextStyle.toModifier()
.textTransform(TextTransform.Uppercase)
.padding(bottom = 8.px)
.toAttrs()
) {
LangText(
en = filterLabel.en,
nl = filterLabel.nl
)
}
Div(
ResponsiveFlexStyle.toModifier()
.gap(0.5.cssRem)
.toAttrs()
) { content() }
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package com.zenmo.web.zenmo.domains.lux.sections.luxmodels.components

import com.zenmo.web.zenmo.domains.lux.core.TwinModelCardItem
import com.zenmo.web.zenmo.domains.lux.sections.application_fields.LuxApplicationArea
import com.zenmo.web.zenmo.domains.lux.sections.luxmodels.FilterType


/**
* Filters and searches a list of models based on visibility and title.
* Filters and searches a list of models based on visibility, matching title, and application area.
*
* Applies the selected [filterType] and
* Applies the selected [filterType], filters by [areas] if specified, and
* optionally narrows the result by matching the [query] against
* each model’s title (case-insensitive).
*/
fun filterAndSearchModels(
models: List<TwinModelCardItem>,
query: String,
filterType: FilterType
filterType: FilterType,
areas: Set<LuxApplicationArea>
): List<TwinModelCardItem> {
val queryString = query.trim().lowercase()

Expand All @@ -34,5 +36,9 @@ fun filterAndSearchModels(
sTokens.lowercase().contains(queryString)
}
}
.filter { model ->
if (areas.isEmpty()) return@filter true
model.applicationArea in areas
}
.toList()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.zenmo.web.zenmo.domains.lux.widgets

import androidx.compose.runtime.Composable
import com.varabyte.kobweb.compose.foundation.layout.Arrangement
import com.varabyte.kobweb.compose.foundation.layout.Row
import com.varabyte.kobweb.compose.ui.Alignment
import com.varabyte.kobweb.compose.ui.Modifier
import com.varabyte.kobweb.compose.ui.modifiers.gap
import org.jetbrains.compose.web.css.cssRem
import org.jetbrains.compose.web.dom.Text

@Composable
fun <T> MultiSelectRow(
selectedValues: Set<T>,
options: Map<T, String>,
onChange: (Set<T>) -> Unit,
modifier: Modifier = Modifier.Companion,
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
modifier = modifier.gap(0.5.cssRem)
) {
options.forEach { (optionValue, displayName) ->
val isSelected = optionValue in selectedValues
RadioItem(
onClick = {
val selection = selectedValues.toMutableSet()
if (isSelected) {
selection.remove(optionValue)
} else {
selection.add(optionValue)
}
onChange(selection)
},
isSelected = isSelected,
) {
Text(displayName)
}
}
}
}