feat(front): implémentation UI soins enfant (#207)
- Ajout des formulaires spécifiques (fièvre, bobo, médicament) dans la modale d'ajout - Formatage personnalisé du résumé des soins dans le feed - Boutons supprimer / corriger (24h) pour l'AM - Icônes contextuelles selon le sous-type de soin Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -611,8 +611,15 @@ class _BulleTile extends StatelessWidget {
|
||||
return '$jj ${_mois[dt.month - 1]} ${dt.year}';
|
||||
}
|
||||
|
||||
/// Une ligne type maquette : « Du 04 au 06 novembre 2026 ».
|
||||
String _fmtPeriodeUneLigne() {
|
||||
// Si c'est un soin_enfant en singleDay, on affiche juste "Le ..." ou un résumé si pertinent
|
||||
if (card.isSoinEnfant) {
|
||||
final resume = card.resumerSoin;
|
||||
final jour = card.dateDebut != null ? 'Le ${_fmtLong(card.dateDebut)}' : '';
|
||||
if (resume != null) return '$jour\n$resume';
|
||||
return jour;
|
||||
}
|
||||
|
||||
final d1 = DateTime.tryParse(card.dateDebut ?? '');
|
||||
final d2 = DateTime.tryParse(card.dateFin ?? '');
|
||||
if (d1 == null && d2 == null) return '';
|
||||
@@ -850,6 +857,11 @@ class _BulleTile extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildGeneric(BuildContext context) {
|
||||
final encre = _Encre.pour(card.colorFamily);
|
||||
final isEdited = card.modifieLe != null && (card.creeLe == null || card.modifieLe!.isAfter(card.creeLe!));
|
||||
final createdAt = card.creeLe ?? DateTime.now();
|
||||
final canEdit = card.isCreator && DateTime.now().difference(createdAt).inHours < 24;
|
||||
|
||||
final memeJour = card.dateDebut != null &&
|
||||
card.dateFin != null &&
|
||||
card.dateDebut == card.dateFin;
|
||||
@@ -870,23 +882,41 @@ class _BulleTile extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
card.titreAffiche,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: GoogleFonts.merienda(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: QuotidienTheme.ink,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
card.titreAffiche,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: GoogleFonts.merienda(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: QuotidienTheme.ink,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isEdited)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Text(
|
||||
'(Corrigée)',
|
||||
style: GoogleFonts.merriweather(
|
||||
fontSize: 11,
|
||||
fontStyle: FontStyle.italic,
|
||||
color: QuotidienTheme.ink.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (card.dateDebut != null || card.dateFin != null) ...[
|
||||
if (card.dateDebut != null || card.dateFin != null || card.isSoinEnfant) ...[
|
||||
const SizedBox(height: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 12),
|
||||
child: memeJour
|
||||
child: (memeJour || card.isSoinEnfant)
|
||||
? Text(
|
||||
'Le ${_fmtLong(card.dateDebut)}',
|
||||
_fmtPeriodeUneLigne(),
|
||||
style: GoogleFonts.merienda(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w600,
|
||||
@@ -960,6 +990,73 @@ class _BulleTile extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
// Edit / Delete buttons for creator if within 24h
|
||||
if (canEdit && !busy) ...[
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton.icon(
|
||||
icon: const Icon(Icons.edit, size: 16),
|
||||
label: const Text('Corriger'),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: encre.link,
|
||||
textStyle: GoogleFonts.merriweather(fontSize: 12),
|
||||
),
|
||||
onPressed: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('La correction de carte sera implémentée ultérieurement.'),
|
||||
duration: Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
TextButton.icon(
|
||||
icon: const Icon(Icons.delete_outline, size: 16),
|
||||
label: const Text('Supprimer'),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Colors.red[700],
|
||||
textStyle: GoogleFonts.merriweather(fontSize: 12),
|
||||
),
|
||||
onPressed: () async {
|
||||
final confirm = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: Text('Supprimer cette carte ?', style: GoogleFonts.merienda()),
|
||||
content: const Text('Cette action est définitive.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx, false),
|
||||
child: const Text('Annuler'),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.pop(ctx, true),
|
||||
style: FilledButton.styleFrom(backgroundColor: Colors.red[700]),
|
||||
child: const Text('Supprimer'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (confirm == true && context.mounted) {
|
||||
try {
|
||||
await CardsService.supprimer(card.id);
|
||||
// The stream will handle the removal locally via card.deleted
|
||||
} catch (e) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Erreur: ${e.toString().replaceFirst('Exception: ', '')}')),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
if (card.peutRepondre) ...[
|
||||
const SizedBox(height: 14),
|
||||
if (busy)
|
||||
|
||||
Reference in New Issue
Block a user