feat: remove code

This commit is contained in:
2026-06-14 15:31:13 +03:30
parent 27dc08fa68
commit 1971708b3f
2 changed files with 181 additions and 167 deletions
@@ -1,21 +1,30 @@
package com.approagency.pharmacy.presentation.components package com.approagency.pharmacy.presentation.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.LocalPharmacy
import androidx.compose.material.icons.filled.Medication
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.sp import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.approagency.pharmacy.domain.model.DrugSearchResult import com.approagency.pharmacy.domain.model.DrugSearchResult
import com.approagency.pharmacy.presentation.common.CustomBox import com.approagency.pharmacy.presentation.common.CustomBox
import com.vada.caller.ui.theme.LocalDime
import com.vada.caller.ui.theme.dime import com.vada.caller.ui.theme.dime
@Composable @Composable
@@ -25,50 +34,64 @@ fun DaroYabSearchResult(
onClickDrugStore: (DrugSearchResult) -> Unit, onClickDrugStore: (DrugSearchResult) -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val dime = LocalDime.current
CustomBox( CustomBox(
modifier = modifier modifier = modifier
.padding(bottom = MaterialTheme.dime.sm) .padding(bottom = MaterialTheme.dime.sm)
.fillMaxWidth() .fillMaxWidth()
.clickable { onClickDetail(drug) },
) {
Row (
modifier = modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End
) { ) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
Column( Column(
modifier = Modifier.padding(dime.lg), modifier = Modifier
verticalArrangement = Arrangement.Center, .fillMaxWidth()
horizontalAlignment = Alignment.End .padding(MaterialTheme.dime.lg),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.dime.xs)
) { ) {
Text( Text(
text = drug.persianName, text = drug.persianName,
style = MaterialTheme.typography.labelLarge style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
) )
drug.englishName?.let { drug.englishName?.takeIf { it.isNotBlank() }?.let {
Text( Text(
text = it, text = it,
fontSize = 12.sp, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f) color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
Text(
text = "کد: ${drug.genericId}", Spacer(Modifier.height(MaterialTheme.dime.sm))
fontSize = 10.sp,
color = MaterialTheme.colorScheme.primary
)
Row( Row(
modifier = modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.spacedBy(MaterialTheme.dime.sm)
) { ) {
TextButton(onClick = {onClickDetail(drug)} , content = { Button(
Text("اطلاعات دارویی") onClick = { onClickDrugStore(drug) },
}) modifier = Modifier
TextButton(onClick = {onClickDrugStore(drug)} , content = { .weight(1f)
Text("موجودی داروخانه") .height(44.dp)
}) ) {
Icon(
imageVector = Icons.Filled.LocalPharmacy,
contentDescription = null,
modifier = Modifier.size(18.dp)
)
Spacer(Modifier.size(MaterialTheme.dime.xs))
Text("موجودی داروخانه", style = MaterialTheme.typography.labelLarge)
}
OutlinedButton(
onClick = { onClickDetail(drug) },
modifier = Modifier
.weight(1f)
.height(44.dp)
) {
Icon(
imageVector = Icons.Filled.Medication,
contentDescription = null,
modifier = Modifier.size(18.dp)
)
Spacer(Modifier.size(MaterialTheme.dime.xs))
Text("اطلاعات دارویی", style = MaterialTheme.typography.labelLarge)
}
} }
} }
} }
@@ -3,13 +3,13 @@ package com.approagency.pharmacy.presentation.components
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
@@ -33,155 +33,99 @@ fun PharmacyBottomSheet(
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val sheetState = rememberModalBottomSheetState( val sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = false, confirmValueChange = { true }) skipPartiallyExpanded = true, confirmValueChange = { true }
)
var selectedProvinceId by remember { mutableStateOf("40") } // پیش‌فرض تهران var selectedProvinceId by remember { mutableStateOf("40") } // پیش‌فرض تهران
var showProvinceDropdown by remember { mutableStateOf(false) } var showProvinceDropdown by remember { mutableStateOf(false) }
val pharmacyState by viewModel.state.collectAsState() val pharmacyState by viewModel.state.collectAsState()
// جستجوی اولیه با استان تهران — با تغییر دارو دوباره اجرا می‌شود // شیت بلند ثابت می‌شود تا لیست داخلی به‌درستی اسکرول شود (نه اینکه درگِ شیت
// (در صورت خالی بودن شناسه، ViewModel وضعیت قبلی را پاک و خطا نمایش می‌دهد) // جای اسکرولِ لیست را بگیرد) و حالت‌های لودینگ/خالی/خطا وسط دیده شوند.
val sheetHeight = (LocalConfiguration.current.screenHeightDp * 0.85f).dp
LaunchedEffect(genericDrugId, brandIrc) { LaunchedEffect(genericDrugId, brandIrc) {
viewModel.search(genericDrugId, brandIrc, "40") viewModel.search(genericDrugId, brandIrc, "40")
} }
if (isOpen) { if (isOpen) {
CustomModalBottomSheet( CustomModalBottomSheet(sheetState = sheetState, onDismiss = onDismiss, scope = scope) {
sheetState = sheetState, onDismiss = onDismiss, scope = scope
) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
LazyColumn( Column(
modifier = Modifier modifier = Modifier
.fillMaxHeight()
.fillMaxWidth() .fillMaxWidth()
.heightIn(min = 400.dp) .height(sheetHeight)
.padding(MaterialTheme.dime.md), .padding(MaterialTheme.dime.lg)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.dime.xl)
) { ) {
item { // سربرگ ثابت
Text( Text(
text = "جستجوی دارو در داروخانه‌ها", text = "موجودی دارو در داروخانه‌ها",
fontWeight = FontWeight.Bold, style = MaterialTheme.typography.titleMedium,
fontSize = MaterialTheme.typography.titleMedium.fontSize fontWeight = FontWeight.Bold
)
}
// عنوان
item {
ExposedDropdownMenuBox(
expanded = showProvinceDropdown,
onExpandedChange = { showProvinceDropdown = it }) {
OutlinedTextField(
value = provinces.find { it.id == selectedProvinceId }?.name
?: "انتخاب استان",
onValueChange = {},
readOnly = true,
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = showProvinceDropdown) },
modifier = Modifier
.fillMaxWidth()
.menuAnchor(),
shape = MaterialTheme.shapes.large
) )
ExposedDropdownMenu( Spacer(Modifier.height(MaterialTheme.dime.md))
ProvinceSelector(
selectedProvinceId = selectedProvinceId,
expanded = showProvinceDropdown, expanded = showProvinceDropdown,
onDismissRequest = { showProvinceDropdown = false }) { onExpandedChange = { showProvinceDropdown = it },
provinces.forEach { province -> onProvinceSelected = { id ->
DropdownMenuItem(text = { Text(province.name) }, onClick = { selectedProvinceId = id
selectedProvinceId = province.id
showProvinceDropdown = false showProvinceDropdown = false
// جستجو با استان جدید viewModel.search(genericDrugId, brandIrc, id)
viewModel.search(genericDrugId, brandIrc, province.id)
})
} }
}
}
}
// انتخاب استان
// نمایش نتایج
when (val state = pharmacyState) {
PharmacyState.Loading -> {
item {
Loading(
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
message = "در حال جستجو..."
) )
}
}
is PharmacyState.Success -> { Spacer(Modifier.height(MaterialTheme.dime.md))
if (state.items.isEmpty()) {
item { // ناحیه‌ی محتوا فضای باقی‌مانده را پر می‌کند؛ سربرگ بالا ثابت می‌ماند.
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(400.dp), .weight(1f),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Text( when (val state = pharmacyState) {
text = "هیچ داروخانه‌ای یافت نشد", PharmacyState.Loading -> Loading(
fontSize = MaterialTheme.typography.bodyMedium.fontSize, modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f) message = "در حال جستجو..."
) )
}
}
is PharmacyState.Success -> {
if (state.items.isEmpty()) {
EmptyMessage("هیچ داروخانه‌ای یافت نشد")
} else { } else {
LazyColumn(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.dime.sm)
) {
items(state.items) { pharmacy -> items(state.items) { pharmacy ->
PharmacyResultItem(pharmacy = pharmacy, viewModel) PharmacyResultItem(pharmacy = pharmacy, viewModel)
} }
item { item {
Spacer(modifier = Modifier.height(MaterialTheme.dime.md))
Text( Text(
text = "تعداد کل: ${state.items.size} داروخانه", text = "تعداد کل: ${state.items.size} داروخانه",
fontSize = MaterialTheme.typography.bodySmall.fontSize, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f), color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(bottom = MaterialTheme.dime.xs) modifier = Modifier.padding(vertical = MaterialTheme.dime.sm)
) )
} }
// LazyColumn( }
// verticalArrangement = Arrangement.spacedBy(8.dp),
// modifier = Modifier,
// ) {
// items(state.items) { pharmacy ->
// PharmacyResultItem(pharmacy = pharmacy)
// }
//
//
// }
} }
} }
is PharmacyState.Error -> { is PharmacyState.Error -> Column(
item { horizontalAlignment = Alignment.CenterHorizontally
Box(
modifier = Modifier
.fillMaxWidth()
.height(200.dp),
contentAlignment = Alignment.Center
) { ) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text( Text(
text = state.message, text = state.message,
color = MaterialTheme.colorScheme.error, color = MaterialTheme.colorScheme.error,
fontSize = MaterialTheme.typography.bodyMedium.fontSize style = MaterialTheme.typography.bodyMedium
) )
Spacer(modifier = Modifier.height(MaterialTheme.dime.sm)) Spacer(Modifier.height(MaterialTheme.dime.sm))
TextButton( TextButton(onClick = { viewModel.retry() }) { Text("تلاش مجدد") }
onClick = { viewModel.retry() }) {
Text("تلاش مجدد")
}
}
}
}
} }
PharmacyState.Idle -> {} PharmacyState.Idle -> {}
@@ -191,3 +135,50 @@ fun PharmacyBottomSheet(
} }
} }
} }
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ProvinceSelector(
selectedProvinceId: String,
expanded: Boolean,
onExpandedChange: (Boolean) -> Unit,
onProvinceSelected: (String) -> Unit
) {
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = onExpandedChange
) {
OutlinedTextField(
value = provinces.find { it.id == selectedProvinceId }?.name ?: "انتخاب استان",
onValueChange = {},
readOnly = true,
label = { Text("استان") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
modifier = Modifier
.fillMaxWidth()
.menuAnchor(),
shape = MaterialTheme.shapes.large
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { onExpandedChange(false) }
) {
provinces.forEach { province ->
DropdownMenuItem(
text = { Text(province.name) },
onClick = { onProvinceSelected(province.id) }
)
}
}
}
}
@Composable
private fun EmptyMessage(message: String) {
Text(
text = message,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}