manager-app/lib/Components/multi_string_input_container.dart

222 lines
6.9 KiB
Dart

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<TranslationDTO> initialValue;
final Function(List<TranslationDTO>) onGetResult;
final int maxLines;
final bool isTitle;
final List<ResourceType>? resourceTypes;
final bool isHTML;
final double fontSize;
final bool isMandatory;
final bool showPreview;
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,
}) : 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<AppContext>(context);
final managerAppContext = appContext.getContext();
final 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<TranslationDTO> newValues = [];
List<TranslationDTO> initials = initialValue;
// Préparer les valeurs pour toutes les langues
managerAppContext.selectedConfiguration!.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<String> 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,
),
),
);
}
}