Skip to content
Open
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.Business
Expand All @@ -18,7 +17,6 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
Expand All @@ -34,6 +32,7 @@ import androidx.lifecycle.compose.LifecycleEventEffect
import com.cramsan.edifikana.client.ui.components.EdifikanaPrimaryButton
import com.cramsan.edifikana.client.ui.components.EdifikanaTopBar
import com.cramsan.edifikana.client.ui.components.IconBadge
import com.cramsan.edifikana.client.ui.components.StatusPillBadge
import com.cramsan.edifikana.client.ui.theme.Elevation
import com.cramsan.edifikana.client.ui.theme.Shapes
import com.cramsan.edifikana.client.ui.theme.Spacing
Expand Down Expand Up @@ -187,24 +186,11 @@ private fun OrgCard(
modifier = Modifier.weight(1f, fill = false),
)
if (org.isActive) {
Surface(
color = MaterialTheme.colorScheme.primaryContainer,
StatusPillBadge(
text = "Current",
containerColor = MaterialTheme.colorScheme.primaryContainer,
contentColor = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(percent = 50),
) {
Text(
text = "Current",
style = MaterialTheme.typography.labelSmall,
fontWeight = FontWeight.SemiBold,
maxLines = 1,
softWrap = false,
modifier =
Modifier.padding(
horizontal = Spacing.md,
vertical = Spacing.xs,
),
)
}
)
}
}
Text(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cramsan.edifikana.client.lib.features.settings.organizations.orgdetail

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -8,10 +9,12 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.Build
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
Expand All @@ -23,11 +26,19 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LifecycleEventEffect
import com.cramsan.edifikana.client.lib.features.settings.SettingsDestination
import com.cramsan.edifikana.client.ui.components.EdifikanaTopBar
import com.cramsan.edifikana.client.ui.components.IconBadge
import com.cramsan.edifikana.client.ui.components.StatusPillBadge
import com.cramsan.edifikana.client.ui.theme.Elevation
import com.cramsan.edifikana.client.ui.theme.Shapes
import com.cramsan.edifikana.client.ui.theme.Spacing
import com.cramsan.edifikana.client.ui.theme.StatusColors
import com.cramsan.edifikana.client.ui.theme.Typography
import com.cramsan.edifikana.lib.model.organization.OrgRole
import com.cramsan.framework.core.compose.ui.ObserveViewModelEvents
import com.cramsan.ui.components.LoadingAnimationOverlay
Expand Down Expand Up @@ -126,6 +137,7 @@ internal fun OrgDetailContent(
InfoCard(
userRole = uiState.userRole,
memberCount = uiState.memberCount,
propertyCount = uiState.propertyCount,
joinedDate = uiState.joinedDate,
modifier = sectionModifier,
)
Expand Down Expand Up @@ -159,7 +171,18 @@ private fun OrgHeaderCard(
isActive: Boolean,
modifier: Modifier = Modifier,
) {
Card(modifier = modifier.fillMaxWidth()) {
Card(
modifier = modifier.fillMaxWidth(),
shape = Shapes.pill,
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLowest),
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
elevation =
CardDefaults.cardElevation(
defaultElevation = Elevation.resting,
hoveredElevation = Elevation.hovered,
pressedElevation = Elevation.pressed,
),
) {
Row(
modifier =
Modifier
Expand All @@ -169,12 +192,16 @@ private fun OrgHeaderCard(
horizontalArrangement = Arrangement.spacedBy(Spacing.lg),
) {
Column {
Text(text = orgName, style = MaterialTheme.typography.headlineSmall)
Text(
text = orgName,
style = Typography.cardTitle,
)
if (isActive) {
Text(
StatusPillBadge(
text = "Active",
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.primary,
containerColor = StatusColors.successContainer,
contentColor = StatusColors.onSuccessContainer,
modifier = Modifier.padding(top = Spacing.xs),
)
}
}
Expand All @@ -186,16 +213,29 @@ private fun OrgHeaderCard(
private fun InfoCard(
userRole: OrgRole?,
memberCount: Int,
propertyCount: Int,
joinedDate: String,
modifier: Modifier = Modifier,
) {
Card(modifier = modifier.fillMaxWidth()) {
Card(
modifier = modifier.fillMaxWidth(),
shape = Shapes.pill,
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLowest),
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
elevation =
CardDefaults.cardElevation(
defaultElevation = Elevation.resting,
hoveredElevation = Elevation.hovered,
pressedElevation = Elevation.pressed,
),
) {
Column(modifier = Modifier.padding(Spacing.lg)) {
InfoRow(
label = "Your Role",
value = userRole?.name?.lowercase()?.replaceFirstChar { it.uppercaseChar() } ?: "—",
)
InfoRow(label = "Members", value = memberCount.toString())
InfoRow(label = "Properties", value = propertyCount.toString())
InfoRow(label = "Joined", value = joinedDate.ifEmpty { "—" })
}
}
Expand All @@ -219,7 +259,12 @@ private fun InfoRow(
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
Text(text = value, style = MaterialTheme.typography.bodyMedium)
Text(
text = value,
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.onSurface,
)
}
}

Expand All @@ -229,18 +274,32 @@ private fun TransferOwnershipRow(
modifier: Modifier = Modifier,
) {
Card(
modifier =
modifier
.fillMaxWidth(),
modifier = modifier.fillMaxWidth(),
onClick = onClick,
shape = Shapes.pill,
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLowest),
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
elevation =
CardDefaults.cardElevation(
defaultElevation = Elevation.resting,
hoveredElevation = Elevation.hovered,
pressedElevation = Elevation.pressed,
),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(Spacing.lg),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(Spacing.md),
) {
IconBadge(
icon = Icons.Filled.Build,
contentDescription = null,
backgroundColor = StatusColors.warningContainer,
tint = StatusColors.onWarningContainer,
)
Column(modifier = Modifier.weight(1f)) {
Text(text = "Transfer Ownership", style = MaterialTheme.typography.bodyLarge)
Text(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ private fun OrgDetailScreenPreview() =
isActiveOrg = true,
userRole = OrgRole.OWNER,
memberCount = 8,
propertyCount = 12,
joinedDate = "1/15/2025",
isSoleOwner = false,
dialog = OrgDetailDialogState.None,
Expand All @@ -40,6 +41,7 @@ private fun OrgDetailScreenSoleOwnerPreview() =
isActiveOrg = true,
userRole = OrgRole.OWNER,
memberCount = 1,
propertyCount = 1,
joinedDate = "3/1/2024",
isSoleOwner = true,
dialog = OrgDetailDialogState.None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ data class OrgDetailUIState(
val isActiveOrg: Boolean,
val userRole: OrgRole?,
val memberCount: Int,
val propertyCount: Int,
val joinedDate: String,
val isSoleOwner: Boolean,
val dialog: OrgDetailDialogState = OrgDetailDialogState.None,
Expand All @@ -34,6 +35,7 @@ data class OrgDetailUIState(
isActiveOrg = false,
userRole = null,
memberCount = 0,
propertyCount = 0,
joinedDate = "",
isSoleOwner = false,
dialog = OrgDetailDialogState.None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.cramsan.edifikana.client.lib.features.window.EdifikanaWindowsEvent
import com.cramsan.edifikana.client.lib.managers.AuthManager
import com.cramsan.edifikana.client.lib.managers.MembershipManager
import com.cramsan.edifikana.client.lib.managers.OrganizationManager
import com.cramsan.edifikana.client.lib.managers.PropertyManager
import com.cramsan.edifikana.client.lib.settings.getLastSelectedOrganizationId
import com.cramsan.edifikana.lib.model.organization.OrgRole
import com.cramsan.edifikana.lib.model.organization.OrganizationId
Expand All @@ -28,6 +29,7 @@ class OrgDetailViewModel(
private val membershipManager: MembershipManager,
private val authManager: AuthManager,
private val preferencesManager: PreferencesManager,
private val propertyManager: PropertyManager,
) : BaseViewModel<OrgDetailEvent, OrgDetailUIState>(
dependencies,
OrgDetailUIState.Initial,
Expand All @@ -45,6 +47,12 @@ class OrgDetailViewModel(

val org = organizationManager.getOrganization(orgId).getOrNull()
val members = membershipManager.listMembers(orgId).getOrNull()
val propertyCount =
propertyManager
.getPropertyList()
.getOrNull()
?.count { it.organizationId == orgId }
?: 0

if (org == null || members == null) {
updateUiState { it.copy(isLoading = false) }
Expand All @@ -63,6 +71,7 @@ class OrgDetailViewModel(
isActiveOrg = org.id == activeOrgId,
userRole = myMembership?.role,
memberCount = members.size,
propertyCount = propertyCount,
joinedDate = myMembership?.joinedAt?.toDisplayDate() ?: "",
isSoleOwner = isSoleOwner,
)
Expand Down
Loading