import 'dart:convert'; import 'package:manager_app/l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:html/parser.dart' as html_parser; import 'package:manager_api_new/api.dart'; import 'package:manager_app/Components/multi_input_modal.dart'; import 'package:manager_app/Components/multi_string_input_html_modal.dart'; import 'package:manager_app/app_context.dart'; import 'package:manager_app/constants.dart'; import 'package:provider/provider.dart'; class MultiStringInputContainer extends StatelessWidget { final Color color; final String label; final String modalLabel; final List initialValue; final Function(List) onGetResult; final int maxLines; final bool isTitle; final List? resourceTypes; final bool isHTML; final double fontSize; final bool isMandatory; final bool showPreview; /// Hors d'une configuration (ex. réglages d'une application), les langues ne /// peuvent pas venir de `selectedConfiguration` : on les passe explicitement. final List? languages; const MultiStringInputContainer({ Key? key, this.color = kSecond, required this.label, required this.modalLabel, required this.initialValue, required this.onGetResult, required this.maxLines, required this.isTitle, this.resourceTypes, this.isHTML = false, this.fontSize = 18, this.isMandatory = true, this.showPreview = false, this.languages, }) : super(key: key); String _plainTextPreview(String htmlOrText) { if (htmlOrText.trim().isEmpty) return ""; try { final doc = html_parser.parse(htmlOrText); final text = (doc.body?.text ?? htmlOrText).trim(); return text.isEmpty ? htmlOrText.trim() : text; } catch (_) { return htmlOrText; } } @override Widget build(BuildContext context) { final appContext = Provider.of(context); final managerAppContext = appContext.getContext(); final languages = this.languages ?? managerAppContext.selectedConfiguration!.languages!; final completed = initialValue.where((t) => (t.value ?? "").trim().isNotEmpty).length; final l = AppLocalizations.of(context)!; return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Flexible(child: Text(label, style: kLabelField)), if (isMandatory) const Padding( padding: EdgeInsets.only(left: kSpace1), child: Text("*", style: TextStyle(fontSize: 12.5, color: kError)), ), ], ), const SizedBox(height: kSpace2), Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(kRadiusInput), onTap: () { List newValues = []; List initials = initialValue; // Préparer les valeurs pour toutes les langues languages.forEach((lang) { if (initials.any((iv) => iv.language == lang)) { newValues.add(TranslationDTO.fromJson( jsonDecode(jsonEncode(initials.firstWhere((e) => e.language == lang)))!)!); } else { newValues.add(TranslationDTO(language: lang, value: "")); } }); if (isHTML) { showMultiStringInputHTML( label, modalLabel, isTitle, initials, newValues, onGetResult, maxLines, resourceTypes, context, isMandatory, ); } else { showMultiStringInput( label, modalLabel, isTitle, initials, newValues, onGetResult, maxLines, resourceTypes, context, ); } }, child: _field(context, l, languages), ), ), if (resourceTypes == null) Padding( padding: const EdgeInsets.only(top: kSpace1), child: Text( l.translatedLanguagesCount(completed, languages.length), style: kTextHint, ), ), ], ); } Widget _field( BuildContext context, AppLocalizations l, List languages) { final preview = resourceTypes == null ? _plainTextPreview(initialValue.isNotEmpty ? (initialValue .firstWhere((t) => t.language == 'FR', orElse: () => initialValue.first) .value ?? "") : "") : ""; final isEmpty = preview.isEmpty; return Container( padding: const EdgeInsets.symmetric(horizontal: kSpace4, vertical: kSpace3), decoration: BoxDecoration( color: kSurface2, border: Border.all(color: kLine), borderRadius: BorderRadius.circular(kRadiusInput), ), child: Row( children: [ Expanded( child: Text( resourceTypes != null ? l.changeResources : (isEmpty ? l.noTextYet : preview), maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 13, color: isEmpty ? kInk3 : kInk, fontStyle: isEmpty ? FontStyle.italic : FontStyle.normal, ), ), ), if (resourceTypes == null) ...[ const SizedBox(width: kSpace3), for (final language in languages) Padding( padding: const EdgeInsets.only(left: kSpace1), child: _LanguageBadge( language: language, isFilled: initialValue.any((t) => t.language == language && (t.value ?? "").trim().isNotEmpty), ), ), ], const SizedBox(width: kSpace3), const Icon(Icons.edit_outlined, size: 16, color: kInk3), ], ), ); } } class _LanguageBadge extends StatelessWidget { const _LanguageBadge({required this.language, required this.isFilled}); final String language; final bool isFilled; @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: kSpace2, vertical: 3), decoration: BoxDecoration( color: isFilled ? kSurface3 : Colors.transparent, border: isFilled ? null : Border.all(color: kLineSoft), borderRadius: BorderRadius.circular(kRadiusInput), ), child: Text( language, style: TextStyle( fontSize: 10.5, fontWeight: FontWeight.w600, letterSpacing: 0.5, color: isFilled ? kPrimaryColor : kInk3, ), ), ); } }