style
This commit is contained in:
@@ -1,25 +1,31 @@
|
||||
package com.approagency.pharmacy.presentation.common
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
|
||||
@Composable
|
||||
|
||||
fun CustomBox(
|
||||
modifier: Modifier? = Modifier,
|
||||
modifier: Modifier = Modifier,
|
||||
child: @Composable () -> Unit
|
||||
) {
|
||||
if (modifier != null) {
|
||||
val shape = MaterialTheme.shapes.large
|
||||
Box(
|
||||
modifier = modifier.clip(shape = MaterialTheme.shapes.large).background(
|
||||
color = MaterialTheme.colorScheme.surfaceContainer
|
||||
modifier = modifier
|
||||
.clip(shape)
|
||||
.background(color = MaterialTheme.colorScheme.surfaceContainerLowest)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MaterialTheme.colorScheme.outlineVariant,
|
||||
shape = shape
|
||||
)
|
||||
) {
|
||||
child()
|
||||
}
|
||||
}
|
||||
}
|
||||
+212
-253
@@ -1,8 +1,12 @@
|
||||
package com.approagency.pharmacy.presentation.screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -15,9 +19,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
@@ -39,8 +40,10 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -52,6 +55,7 @@ import com.approagency.pharmacy.presentation.common.Loading
|
||||
import com.approagency.pharmacy.presentation.viewModel.DrugDetailViewModel
|
||||
import com.approagency.pharmacy.presentation.viewModel.DrugDetailYabState
|
||||
import com.vada.caller.ui.theme.LocalDime
|
||||
import com.vada.caller.ui.theme.dime
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@@ -85,17 +89,21 @@ fun DrugDetailScreen(
|
||||
)
|
||||
if (state.drugDetail.englishName.isNotEmpty()) {
|
||||
Text(
|
||||
text = state.drugDetail.englishName.take(30),
|
||||
fontSize = 11.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
|
||||
maxLines = 1
|
||||
text = state.drugDetail.englishName,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
Text("جزئیات دارو", fontSize = 16.sp)
|
||||
Text(
|
||||
text = "جزئیات دارو",
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -157,7 +165,7 @@ fun DrugDetailScreen(
|
||||
text = {
|
||||
Text(
|
||||
text = title,
|
||||
fontSize = 13.sp,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
fontWeight = if (selectedTab == index) FontWeight.Bold else FontWeight.Normal,
|
||||
maxLines = 1
|
||||
)
|
||||
@@ -170,8 +178,8 @@ fun DrugDetailScreen(
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = dime.md)
|
||||
.padding(top = dime.md),
|
||||
.padding(horizontal = dime.md),
|
||||
contentPadding = PaddingValues(top = dime.md, bottom = dime.xxl),
|
||||
verticalArrangement = Arrangement.spacedBy(dime.md)
|
||||
) {
|
||||
when (selectedTab) {
|
||||
@@ -219,66 +227,63 @@ fun ManufacturerInfoCard(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val dime = LocalDime.current
|
||||
val onContainer = MaterialTheme.colorScheme.onSecondaryContainer
|
||||
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.15f)
|
||||
),
|
||||
shape = RoundedCornerShape(dime.sm)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(dime.md),
|
||||
verticalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clip(MaterialTheme.shapes.large)
|
||||
.background(MaterialTheme.colorScheme.secondaryContainer)
|
||||
.padding(dime.md),
|
||||
verticalArrangement = Arrangement.spacedBy(dime.sm)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
horizontalArrangement = Arrangement.spacedBy(dime.sm)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Info,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
tint = onContainer
|
||||
)
|
||||
Text(
|
||||
text = "سازنده:",
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 13.sp
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = onContainer
|
||||
)
|
||||
Text(
|
||||
text = manufacturer,
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = onContainer
|
||||
)
|
||||
}
|
||||
|
||||
if (genericInfo != null) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
horizontalArrangement = Arrangement.spacedBy(dime.sm)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Info,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
tint = onContainer
|
||||
)
|
||||
Text(
|
||||
text = "ماده موثره:",
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 13.sp
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = onContainer
|
||||
)
|
||||
Text(
|
||||
text = genericInfo.persianName,
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = onContainer
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// آپدیت GeneralInfoTabContent برای صفحات Generic
|
||||
@Composable
|
||||
@@ -308,44 +313,13 @@ fun GeneralInfoTabContent(drugDetail: DrugDetail) {
|
||||
else {
|
||||
// Categories Card
|
||||
if (drugDetail.drugClass != null || drugDetail.therapeuticClass != null) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.2f)
|
||||
),
|
||||
shape = RoundedCornerShape(dime.sm)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(dime.md),
|
||||
verticalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
) {
|
||||
DetailCard {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dime.xs)) {
|
||||
drugDetail.drugClass?.let {
|
||||
Row {
|
||||
Text(
|
||||
text = "طبقه بندی مارتیندل: ",
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 13.sp
|
||||
)
|
||||
Text(
|
||||
text = it,
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
LabeledRow(label = "طبقه بندی مارتیندل", value = it)
|
||||
}
|
||||
drugDetail.therapeuticClass?.let {
|
||||
Row {
|
||||
Text(
|
||||
text = "طبقه درمانی: ",
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 13.sp
|
||||
)
|
||||
Text(
|
||||
text = it,
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
LabeledRow(label = "طبقه درمانی", value = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -353,42 +327,39 @@ fun GeneralInfoTabContent(drugDetail: DrugDetail) {
|
||||
|
||||
// Pregnancy Card
|
||||
if (drugDetail.pregnancyCategory != null || drugDetail.pregnancyDescription != null) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = Color(0xFFFFF3E0)
|
||||
),
|
||||
shape = RoundedCornerShape(dime.sm)
|
||||
) {
|
||||
val onContainer = MaterialTheme.colorScheme.onTertiaryContainer
|
||||
Column(
|
||||
modifier = Modifier.padding(dime.md),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(MaterialTheme.shapes.large)
|
||||
.background(MaterialTheme.colorScheme.tertiaryContainer)
|
||||
.padding(dime.md),
|
||||
verticalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
) {
|
||||
Text(
|
||||
text = "مصرف در بارداری",
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 15.sp,
|
||||
color = Color(0xFFE65100)
|
||||
color = onContainer
|
||||
)
|
||||
drugDetail.pregnancyCategory?.let {
|
||||
Text(
|
||||
text = "گروه: $it",
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Medium
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Medium,
|
||||
color = onContainer
|
||||
)
|
||||
}
|
||||
drugDetail.pregnancyDescription?.let {
|
||||
Spacer(modifier = Modifier.height(dime.xs))
|
||||
Text(
|
||||
text = it,
|
||||
fontSize = 12.sp,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
lineHeight = 18.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
|
||||
color = onContainer.copy(alpha = 0.9f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// موارد مصرف
|
||||
drugDetail.usage?.let {
|
||||
@@ -427,19 +398,7 @@ fun GeneralInfoTabContent(drugDetail: DrugDetail) {
|
||||
drugDetail.generalInfo.isNullOrBlank() &&
|
||||
drugDetail.specializedInfo.isNullOrBlank()
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(32.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "اطلاعات عمومی برای این دارو ثبت نشده است",
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
DetailEmptyState(text = "اطلاعات عمومی برای این دارو ثبت نشده است")
|
||||
}
|
||||
} else {
|
||||
// ========== صفحات برند (Brand) ==========
|
||||
@@ -465,23 +424,13 @@ fun GeneralInfoTabContent(drugDetail: DrugDetail) {
|
||||
drugDetail.sideEffects == null &&
|
||||
drugDetail.warnings == null
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(32.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "اطلاعات عمومی برای این برند ثبت نشده است.\nبرای مشاهده اطلاعات کامل، به صفحه داروی ژنریک مراجعه کنید.",
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
|
||||
textAlign = TextAlign.Center
|
||||
DetailEmptyState(
|
||||
text = "اطلاعات عمومی برای این برند ثبت نشده است.\nبرای مشاهده اطلاعات کامل، به صفحه داروی ژنریک مراجعه کنید."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
@@ -525,25 +474,15 @@ fun SpecializedInfoTabContent(drugDetail: DrugDetail) {
|
||||
drugDetail.sideEffects == null &&
|
||||
drugDetail.warnings == null
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(32.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
DetailEmptyState(
|
||||
text = if (drugDetail.isGeneric)
|
||||
"اطلاعات تخصصی برای این دارو ثبت نشده است"
|
||||
else
|
||||
"اطلاعات تخصصی برای این برند ثبت نشده است.\nبرای مشاهده اطلاعات کامل، به صفحه داروی ژنریک مراجعه کنید.",
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
|
||||
textAlign = TextAlign.Center
|
||||
"اطلاعات تخصصی برای این برند ثبت نشده است.\nبرای مشاهده اطلاعات کامل، به صفحه داروی ژنریک مراجعه کنید."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DosageFormsTabContent(drugDetail: DrugDetail) {
|
||||
@@ -551,86 +490,53 @@ fun DosageFormsTabContent(drugDetail: DrugDetail) {
|
||||
val dosageForms = drugDetail.dosageForms
|
||||
|
||||
if (dosageForms.isEmpty()) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(32.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
DetailEmptyState(
|
||||
text = if (drugDetail.isGeneric)
|
||||
"اشکال دارویی برای این دارو ثبت نشده است"
|
||||
else
|
||||
"سایر اشکال دارویی این برند ثبت نشده است",
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
|
||||
textAlign = TextAlign.Center
|
||||
"سایر اشکال دارویی این برند ثبت نشده است"
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dime.sm)) {
|
||||
// اگر صفحه برند است، عنوان متفاوت نشان بده
|
||||
if (!drugDetail.isGeneric) {
|
||||
Text(
|
||||
text = "سایر محصولات این برند",
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 14.sp,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
SectionHeader(
|
||||
title = "سایر محصولات این برند",
|
||||
modifier = Modifier.padding(bottom = dime.xs)
|
||||
)
|
||||
}
|
||||
|
||||
dosageForms.forEach { form ->
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
|
||||
shape = RoundedCornerShape(dime.sm)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(dime.md),
|
||||
verticalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
) {
|
||||
DetailCard {
|
||||
Text(
|
||||
text = form.persianName,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 14.sp
|
||||
style = MaterialTheme.typography.titleSmall
|
||||
)
|
||||
if (form.englishName.isNotBlank()) {
|
||||
Spacer(modifier = Modifier.height(dime.xxs))
|
||||
Text(
|
||||
text = form.englishName,
|
||||
fontSize = 11.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
// نشانگرهای خطر
|
||||
if (form.isHighRisk || form.isVital) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(dime.sm))
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(dime.xs)) {
|
||||
if (form.isHighRisk) {
|
||||
androidx.compose.material3.Surface(
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
color = Color(0xFFFFEBEE)
|
||||
) {
|
||||
Text(
|
||||
TagChip(
|
||||
text = "پرخطر",
|
||||
fontSize = 10.sp,
|
||||
color = Color(0xFFC62828),
|
||||
modifier = Modifier.padding(horizontal = 6.dp, vertical = dime.xxs)
|
||||
container = MaterialTheme.colorScheme.errorContainer,
|
||||
onContainer = MaterialTheme.colorScheme.onErrorContainer
|
||||
)
|
||||
}
|
||||
}
|
||||
if (form.isVital) {
|
||||
androidx.compose.material3.Surface(
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
color = Color(0xFFE8F5E9)
|
||||
) {
|
||||
Text(
|
||||
TagChip(
|
||||
text = "حیاتی",
|
||||
fontSize = 10.sp,
|
||||
color = Color(0xFF2E7D32),
|
||||
modifier = Modifier.padding(horizontal = 6.dp, vertical = dime.xxs)
|
||||
container = MaterialTheme.colorScheme.primaryContainer,
|
||||
onContainer = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -640,93 +546,39 @@ fun DosageFormsTabContent(drugDetail: DrugDetail) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BrandNamesTabContent(drugDetail: DrugDetail) {
|
||||
val dime = LocalDime.current
|
||||
|
||||
if (drugDetail.isGeneric && drugDetail.brandNames.isEmpty()) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(32.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "اسامی تجاری برای این دارو ثبت نشده است",
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
DetailEmptyState(text = "اسامی تجاری برای این دارو ثبت نشده است")
|
||||
} else if (drugDetail.isGeneric && drugDetail.brandNames.isNotEmpty()) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dime.sm)) {
|
||||
drugDetail.brandNames.forEach { brand ->
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
|
||||
shape = RoundedCornerShape(dime.sm)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(dime.md),
|
||||
verticalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
) {
|
||||
DetailCard {
|
||||
Text(
|
||||
text = brand.persianName,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 14.sp
|
||||
style = MaterialTheme.typography.titleSmall
|
||||
)
|
||||
brand.manufacturer?.let {
|
||||
Row {
|
||||
Text(
|
||||
text = "تولید کننده: ",
|
||||
fontSize = 12.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
|
||||
)
|
||||
Text(
|
||||
text = it,
|
||||
fontSize = 12.sp,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(dime.xs))
|
||||
LabeledRow(label = "تولید کننده", value = it)
|
||||
}
|
||||
brand.importer?.let {
|
||||
Row {
|
||||
Text(
|
||||
text = "وارد کننده: ",
|
||||
fontSize = 12.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
|
||||
)
|
||||
Text(
|
||||
text = it,
|
||||
fontSize = 12.sp,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(dime.xxs))
|
||||
LabeledRow(label = "وارد کننده", value = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// صفحه برند است - اسامی تجاری برای برند معنی ندارد
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(32.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "این صفحه مربوط به یک محصول تجاری است. برای مشاهده اسامی تجاری سایر برندها، به صفحه داروی ژنریک مراجعه کنید.",
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
|
||||
textAlign = TextAlign.Center
|
||||
DetailEmptyState(
|
||||
text = "این صفحه مربوط به یک محصول تجاری است. برای مشاهده اسامی تجاری سایر برندها، به صفحه داروی ژنریک مراجعه کنید."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun InfoSectionCard(
|
||||
@@ -736,29 +588,136 @@ fun InfoSectionCard(
|
||||
) {
|
||||
val dime = LocalDime.current
|
||||
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
|
||||
shape = RoundedCornerShape(dime.sm)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(dime.md),
|
||||
verticalArrangement = Arrangement.spacedBy(dime.xs)
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 15.sp,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f))
|
||||
DetailCard(modifier = modifier) {
|
||||
SectionHeader(title = title)
|
||||
Spacer(modifier = Modifier.height(dime.sm))
|
||||
Text(
|
||||
text = content,
|
||||
fontSize = 13.sp,
|
||||
lineHeight = 20.sp,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
lineHeight = 22.sp,
|
||||
textAlign = TextAlign.Justify,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.85f)
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* کارت پایهی صفحهی جزئیات — ظاهر یکدست با بقیهی برنامه:
|
||||
* سطح روشن + قاب نازک همرنگ تم، بدون سایهی سنگین.
|
||||
*/
|
||||
@Composable
|
||||
private fun DetailCard(
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
val shape = MaterialTheme.shapes.large
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clip(shape)
|
||||
.background(MaterialTheme.colorScheme.surfaceContainerLowest)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MaterialTheme.colorScheme.outlineVariant,
|
||||
shape = shape
|
||||
)
|
||||
.padding(MaterialTheme.dime.md),
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
/** سربرگ بخش با نوار تأکید کوچک کنار عنوان. */
|
||||
@Composable
|
||||
private fun SectionHeader(
|
||||
title: String,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val dime = LocalDime.current
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(dime.sm)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(width = 4.dp, height = 18.dp)
|
||||
.clip(RoundedCornerShape(dime.xxs))
|
||||
.background(MaterialTheme.colorScheme.primary)
|
||||
)
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** حالت «اطلاعاتی ثبت نشده» با آیکن، یکدست در همهی تبها. */
|
||||
@Composable
|
||||
private fun DetailEmptyState(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val dime = LocalDime.current
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = dime.xxl, horizontal = dime.lg),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(dime.sm)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Info,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(40.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f)
|
||||
)
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** ردیف «برچسب: مقدار» با تایپوگرافی یکدست. */
|
||||
@Composable
|
||||
private fun LabeledRow(
|
||||
label: String,
|
||||
value: String,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Row(modifier = modifier) {
|
||||
Text(
|
||||
text = "$label: ",
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Text(
|
||||
text = value,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** برچسب کوچک رنگی (مثل «پرخطر» / «حیاتی»). */
|
||||
@Composable
|
||||
private fun TagChip(
|
||||
text: String,
|
||||
container: Color,
|
||||
onContainer: Color
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = onContainer,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(MaterialTheme.dime.xs))
|
||||
.background(container)
|
||||
.padding(horizontal = MaterialTheme.dime.sm, vertical = MaterialTheme.dime.xxs)
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
package com.approagency.pharmacy.ui.theme
|
||||
|
||||
// رنگهای برنامه در MaterialThemeExt.kt (MedicalColors و ColorScheme ها) تعریف شدهاند.
|
||||
// رنگهای برنامه بهصورت ColorScheme کامل (Light/Dark) در Theme.kt تعریف شدهاند.
|
||||
|
||||
@@ -14,72 +14,96 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import com.fabirt.podcastapp.ui.theme.Shapes
|
||||
import com.vada.caller.ui.theme.Dime
|
||||
import com.vada.caller.ui.theme.LocalDime
|
||||
object MedicalColors {
|
||||
// پالت کامل و هماهنگ بر پایهی سبز-آبی پزشکی (teal).
|
||||
// همهی نقشهای surface/container/outline تعریف شدهاند تا کانتینرها (کارتها،
|
||||
// تکستفیلدها، باتمشیتها) رنگ یکدست و متناسب با برند داشته باشند و به مقادیر
|
||||
// پیشفرض بنفشگون Material برنگردند.
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Color(0xFF0F766E),
|
||||
onPrimary = Color(0xFFFFFFFF),
|
||||
primaryContainer = Color(0xFFC7ECE6),
|
||||
onPrimaryContainer = Color(0xFF00201D),
|
||||
|
||||
val Primary = Color(0xFF0F766E)
|
||||
val PrimaryContainer = Color(0xFFD7F3EF)
|
||||
secondary = Color(0xFF4C6360),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFFCEE8E3),
|
||||
onSecondaryContainer = Color(0xFF09201D),
|
||||
|
||||
val Secondary = Color(0xFF5B8E8A)
|
||||
val SecondaryContainer = Color(0xFFE3F3F1)
|
||||
tertiary = Color(0xFF3D6373),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
tertiaryContainer = Color(0xFFC0E8FB),
|
||||
onTertiaryContainer = Color(0xFF001F2A),
|
||||
|
||||
val Tertiary = Color(0xFF8FBFB8)
|
||||
background = Color(0xFFF5FBF9),
|
||||
onBackground = Color(0xFF171D1C),
|
||||
|
||||
val Background = Color(0xFFF8FCFB)
|
||||
val Surface = Color(0xFFFFFFFF)
|
||||
surface = Color(0xFFF5FBF9),
|
||||
onSurface = Color(0xFF171D1C),
|
||||
surfaceVariant = Color(0xFFDAE5E1),
|
||||
onSurfaceVariant = Color(0xFF3F4947),
|
||||
|
||||
val DarkBackground = Color(0xFF0F1720)
|
||||
val DarkSurface = Color(0xFF17232B)
|
||||
surfaceContainerLowest = Color(0xFFFFFFFF),
|
||||
surfaceContainerLow = Color(0xFFEFF6F3),
|
||||
surfaceContainer = Color(0xFFE9F1EE),
|
||||
surfaceContainerHigh = Color(0xFFE3ECE9),
|
||||
surfaceContainerHighest = Color(0xFFDEE7E4),
|
||||
|
||||
val OnDark = Color(0xFFF5FAF9)
|
||||
val OnLight = Color(0xFF102A2A)
|
||||
outline = Color(0xFF6F7977),
|
||||
outlineVariant = Color(0xFFBEC9C5),
|
||||
|
||||
val Error = Color(0xFFD64545)
|
||||
error = Color(0xFFBA1A1A),
|
||||
onError = Color(0xFFFFFFFF),
|
||||
errorContainer = Color(0xFFFFDAD6),
|
||||
onErrorContainer = Color(0xFF410002),
|
||||
|
||||
val Outline = Color(0xFFD0E2DF)
|
||||
}
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Color(0xFF5DD4C3),
|
||||
onPrimary = Color(0xFF003733),
|
||||
|
||||
secondary = Color(0xFF8CC9C1),
|
||||
onSecondary = Color(0xFF0D2B29),
|
||||
|
||||
tertiary = Color(0xFFA7DCD4),
|
||||
onTertiary = Color(0xFF102A2A),
|
||||
|
||||
background = MedicalColors.DarkBackground,
|
||||
onBackground = MedicalColors.OnDark,
|
||||
|
||||
surface = MedicalColors.DarkSurface,
|
||||
onSurface = MedicalColors.OnDark,
|
||||
|
||||
primaryContainer = Color(0xFF124A45),
|
||||
secondaryContainer = Color(0xFF1D3D3A),
|
||||
|
||||
error = Color(0xFFFF8A80)
|
||||
inverseSurface = Color(0xFF2B3231),
|
||||
inverseOnSurface = Color(0xFFECF2EF),
|
||||
inversePrimary = Color(0xFF80D5CB),
|
||||
scrim = Color(0xFF000000),
|
||||
)
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = MedicalColors.Primary,
|
||||
onPrimary = Color.White,
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Color(0xFF5DD4C3),
|
||||
onPrimary = Color(0xFF00382F),
|
||||
primaryContainer = Color(0xFF005048),
|
||||
onPrimaryContainer = Color(0xFF7FF8E6),
|
||||
|
||||
secondary = MedicalColors.Secondary,
|
||||
onSecondary = Color.White,
|
||||
secondary = Color(0xFFB0CCC6),
|
||||
onSecondary = Color(0xFF1B3531),
|
||||
secondaryContainer = Color(0xFF324B47),
|
||||
onSecondaryContainer = Color(0xFFCCE8E2),
|
||||
|
||||
tertiary = MedicalColors.Tertiary,
|
||||
onTertiary = MedicalColors.OnLight,
|
||||
tertiary = Color(0xFFA4CCDE),
|
||||
onTertiary = Color(0xFF053543),
|
||||
tertiaryContainer = Color(0xFF234C5B),
|
||||
onTertiaryContainer = Color(0xFFC0E8FB),
|
||||
|
||||
background = MedicalColors.Background,
|
||||
onBackground = MedicalColors.OnLight,
|
||||
background = Color(0xFF0E1514),
|
||||
onBackground = Color(0xFFDDE4E1),
|
||||
|
||||
surface = MedicalColors.Surface,
|
||||
onSurface = MedicalColors.OnLight,
|
||||
surface = Color(0xFF0E1514),
|
||||
onSurface = Color(0xFFDDE4E1),
|
||||
surfaceVariant = Color(0xFF3F4947),
|
||||
onSurfaceVariant = Color(0xFFBEC9C5),
|
||||
|
||||
primaryContainer = MedicalColors.PrimaryContainer,
|
||||
secondaryContainer = MedicalColors.SecondaryContainer,
|
||||
surfaceContainerLowest = Color(0xFF090F0E),
|
||||
surfaceContainerLow = Color(0xFF171D1C),
|
||||
surfaceContainer = Color(0xFF1B211F),
|
||||
surfaceContainerHigh = Color(0xFF252B2A),
|
||||
surfaceContainerHighest = Color(0xFF303635),
|
||||
|
||||
outline = MedicalColors.Outline,
|
||||
error = MedicalColors.Error
|
||||
outline = Color(0xFF899390),
|
||||
outlineVariant = Color(0xFF3F4947),
|
||||
|
||||
error = Color(0xFFFFB4AB),
|
||||
onError = Color(0xFF690005),
|
||||
errorContainer = Color(0xFF93000A),
|
||||
onErrorContainer = Color(0xFFFFDAD6),
|
||||
|
||||
inverseSurface = Color(0xFFDDE4E1),
|
||||
inverseOnSurface = Color(0xFF2B3231),
|
||||
inversePrimary = Color(0xFF0F766E),
|
||||
scrim = Color(0xFF000000),
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
||||
Reference in New Issue
Block a user