@@ -21,7 +21,9 @@ import com.mouton.openwinemer.R
2121// import pour le scroll
2222import androidx.compose.foundation.rememberScrollState
2323import androidx.compose.foundation.verticalScroll
24-
24+ // import pour le remplissage auto des champs
25+ import kotlin.reflect.full.memberProperties
26+ import androidx.compose.ui.platform.LocalContext
2527
2628
2729/* *
@@ -32,6 +34,45 @@ import androidx.compose.foundation.verticalScroll
3234 * - Permet de supprimer le vin (avec confirmation)
3335 */
3436
37+ /* *
38+ * Génère automatiquement les champs supplémentaires d'un vin,
39+ * en utilisant les traductions si disponibles.
40+ */
41+ @Composable
42+ private fun autoTranslatedFields (wine : WineEntity ): List <Pair <String , String >> {
43+ val context = LocalContext .current
44+
45+ // Champs déjà affichés manuellement
46+ val excluded = setOf (
47+ " name" , " producer" , " region" , " color" , " vintage" ,
48+ " stockQuantity" , " generalDescription"
49+ )
50+
51+ return WineEntity ::class .memberProperties
52+ .filter { it.name !in excluded }
53+ .mapNotNull { prop ->
54+ val value = prop.get(wine) ? : return @mapNotNull null
55+ val textValue = value.toString().takeIf { it.isNotBlank() } ? : return @mapNotNull null
56+
57+ // Nom de la clé dans strings.xml
58+ val key = " wine_${prop.name.replace(Regex (" ([A-Z])" ), " _$1" ).lowercase()} "
59+
60+ // Essayer de trouver la ressource string correspondante
61+ val resId = context.resources.getIdentifier(key, " string" , context.packageName)
62+
63+ val label =
64+ if (resId != 0 )
65+ stringResource(resId) // traduction trouvée
66+ else
67+ // fallback : transformer "mainGrape" → "Main grape"
68+ prop.name.replace(Regex (" ([a-z])([A-Z])" ), " $1 $2" )
69+ .replaceFirstChar { it.uppercase() }
70+
71+ label to textValue
72+ }
73+ }
74+
75+
3576// fonction utile pour ajouter les champs supplémentaires
3677private fun buildDynamicFields (wine : WineEntity ): List <Pair <String , String >> {
3778 val fields = mutableListOf<Pair <String , String >>()
@@ -89,6 +130,33 @@ private fun buildDynamicFields(wine: WineEntity): List<Pair<String, String>> {
89130 return fields
90131}
91132
133+ /* *
134+ * Génère automatiquement une liste (label, valeur) pour tous les champs non nuls
135+ * de WineEntity, sauf ceux déjà affichés manuellement.
136+ */
137+ private fun autoFields (wine : WineEntity ): List <Pair <String , String >> {
138+
139+ // Champs que tu affiches déjà dans l'écran
140+ val excluded = setOf (
141+ " name" , " producer" , " region" , " color" , " vintage" ,
142+ " stockQuantity" , " generalDescription"
143+ )
144+
145+ return WineEntity ::class .memberProperties
146+ .filter { it.name !in excluded } // ignorer les champs déjà affichés
147+ .mapNotNull { prop ->
148+ val value = prop.get(wine) ? : return @mapNotNull null
149+ val text = value.toString().takeIf { it.isNotBlank() } ? : return @mapNotNull null
150+
151+ // Convertir "mainGrape" → "Main grape"
152+ val label = prop.name
153+ .replace(Regex (" ([a-z])([A-Z])" ), " $1 $2" )
154+ .replaceFirstChar { it.uppercase() }
155+
156+ label to text
157+ }
158+ }
159+
92160
93161@Composable
94162fun WineDetailScreen (
@@ -134,17 +202,17 @@ fun WineDetailScreen(
134202 .padding(16 .dp)
135203 .fillMaxSize()
136204 ) {
137- // --- CHAMPS PRINCIPAUX (ceux que tu avais déjà) ---
138- DetailRow (" Nom" , current.name)
139- DetailRow (" Producteur" , current.producer)
140- DetailRow (" Région" , current.region)
141- DetailRow (" Couleur" , current.color)
142- DetailRow (" Année" , current.vintage?.toString())
205+ // --- CHAMPS PRINCIPAUX (ceux à toujours afficher) ---
206+ // "${wine?.name ?: stringResource(R.string.wine_details)}"
207+ Text (stringResource(R .string.name) + " : " + (current.name ? : " -" ))
208+ Text (stringResource(R .string.wine_producer, " : " , current.producer ? : " -" ))
209+ Text (stringResource(R .string.region_label, " : " , current.region ? : " -" ))
210+ Text (stringResource(R .string.color_label, " : " , current.color ? : " -" ))
211+ Text (stringResource(R .string.year_label, " : " , current.vintage ? : " -" ))
143212
144213 Spacer (Modifier .height(16 .dp))
145214
146- // --- STOCK ---
147- DetailRow (" Stock" , (current.stockQuantity ? : 0 ).toString())
215+ Text (stringResource(R .string.wine_stock, " : " , current.stockQuantity ? : 0 ))
148216
149217 Row {
150218 Button (onClick = { viewModel.updateStock(- 1 ) }) { Text (" -" ) }
@@ -155,16 +223,33 @@ fun WineDetailScreen(
155223 Spacer (Modifier .height(24 .dp))
156224
157225 // --- DESCRIPTION GÉNÉRALE ---
158- DetailRow ( " Description " , current.generalDescription)
226+ Text (stringResource( R .string.wine_general_desc, " : " , current.generalDescription ? : " - " ) )
159227
160228 Spacer (Modifier .height(24 .dp))
161229
230+ // --- CHAMPS AUTOMATIQUES MULTILINGUES ---
231+ val extraFields = autoTranslatedFields(current)
232+
233+ if (extraFields.isNotEmpty()) {
234+ Spacer (Modifier .height(24 .dp))
235+ Text (
236+ stringResource(R .string.additional_information),
237+ style = MaterialTheme .typography.titleMedium
238+ )
239+ Spacer (Modifier .height(8 .dp))
240+
241+ extraFields.forEach { (label, value) ->
242+ DetailRow (label, value)
243+ }
244+ }
245+
246+ /*
162247 // --- CHAMPS DYNAMIQUES (tous les autres renseignés) ---
163248 val dynamicFields = buildDynamicFields(current)
164249
165250 if (dynamicFields.isNotEmpty()) {
166251 Text(
167- " Informations supplémentaires " ,
252+ stringResource(R.string.additional_information) ,
168253 style = MaterialTheme.typography.titleMedium
169254 )
170255 Spacer(Modifier.height(8.dp))
@@ -173,6 +258,7 @@ fun WineDetailScreen(
173258 DetailRow(label, value)
174259 }
175260 }
261+ */
176262 }
177263 } ? : Box (
178264 modifier = Modifier
@@ -211,7 +297,24 @@ fun WineDetailScreen(
211297}
212298
213299@Composable
214- private fun DetailRow (label : String , value : String? ) {
300+ private fun DetailRow (label : String , value : String ) {
301+ Column (Modifier .padding(vertical = 6 .dp)) {
302+ Text (
303+ text = label,
304+ style = MaterialTheme .typography.labelLarge,
305+ color = MaterialTheme .colorScheme.primary
306+ )
307+ Text (
308+ text = value,
309+ style = MaterialTheme .typography.bodyLarge
310+ )
311+ Divider (Modifier .padding(top = 6 .dp))
312+ }
313+ }
314+
315+
316+ @Composable
317+ private fun old_DetailRow (label : String , value : String? ) {
215318 if (value.isNullOrBlank()) return
216319
217320 Column (Modifier .padding(vertical = 6 .dp)) {
0 commit comments