refactor(#173): widget NineSliceAsset réutilisable (cartes + bandeau)

Presets cards/bandeau, cache images, appliqué au sélecteur couple.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-01 17:10:41 +02:00
co-authored by Cursor
parent 42163826fe
commit 2c461abc82
4 changed files with 172 additions and 142 deletions
@@ -3,6 +3,7 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:p_tits_pas/models/couple_garde.dart';
import 'package:p_tits_pas/services/api/api_config.dart';
import 'package:p_tits_pas/widgets/common/auth_network_image.dart';
import 'package:p_tits_pas/widgets/quotidien/nine_slice_asset.dart';
import 'package:p_tits_pas/widgets/quotidien/quotidien_theme.dart';
/// Rôle qui consulte le bandeau : côté parent (enfant | nounou) ou côté AM
@@ -174,14 +175,10 @@ class _CoupleCard extends StatelessWidget {
);
}
return Container(
return NineSliceAsset.bandeau(
assetPath: QuotidienTheme
.bandeauColors[colorIndex % QuotidienTheme.bandeauColors.length],
height: 90,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(QuotidienTheme.bandeauColors[colorIndex % QuotidienTheme.bandeauColors.length]),
fit: BoxFit.fill,
),
),
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row(
children: [
@@ -190,7 +187,8 @@ class _CoupleCard extends StatelessWidget {
padding: const EdgeInsets.only(right: 12),
child: _MembreTile(
photoUrl: couple.enfant.photoUrl,
name: (couple.enfant.prenom != null && couple.enfant.prenom!.isNotEmpty)
name: (couple.enfant.prenom != null &&
couple.enfant.prenom!.isNotEmpty)
? couple.enfant.prenom!
: couple.enfant.displayName(fallback: 'Enfant'),
fallbackIcon: Icons.child_care,
@@ -215,12 +213,12 @@ class _CoupleCard extends StatelessWidget {
),
SizedBox(
width: 28,
child: showChevron
? const Icon(
Icons.keyboard_arrow_down,
color: QuotidienTheme.ink,
)
: null,
child: showChevron
? const Icon(
Icons.keyboard_arrow_down,
color: QuotidienTheme.ink,
)
: null,
),
],
),
@@ -306,24 +304,22 @@ class _CoupleBandeauSkeleton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 90,
decoration: BoxDecoration(
image: DecorationImage(
image: const AssetImage(QuotidienTheme.bandeauLime), // Un asset existant
fit: BoxFit.fill,
colorFilter: ColorFilter.mode(
Colors.white.withValues(alpha: 0.5),
BlendMode.lighten,
return ColorFiltered(
colorFilter: ColorFilter.mode(
Colors.white.withValues(alpha: 0.5),
BlendMode.lighten,
),
child: NineSliceAsset.bandeau(
assetPath: QuotidienTheme.bandeauLime,
height: 90,
child: const Center(
child: SizedBox(
width: 26,
height: 26,
child: CircularProgressIndicator(strokeWidth: 2),
),
),
),
alignment: Alignment.center,
child: const SizedBox(
width: 26,
height: 26,
child: CircularProgressIndicator(strokeWidth: 2),
),
);
}
}
@@ -333,14 +329,9 @@ class _CoupleBandeauEmpty extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
return NineSliceAsset.bandeau(
assetPath: QuotidienTheme.bandeauLime,
height: 90,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(QuotidienTheme.bandeauLime), // Un asset existant par défaut
fit: BoxFit.fill,
),
),
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row(
children: [
@@ -369,38 +360,35 @@ class _CoupleBandeauError extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 90,
decoration: BoxDecoration(
image: DecorationImage(
image: const AssetImage(QuotidienTheme.bandeauLime), // Un asset existant
fit: BoxFit.fill,
colorFilter: ColorFilter.mode(
QuotidienTheme.coral.withValues(alpha: 0.3),
BlendMode.srcATop,
),
),
return ColorFiltered(
colorFilter: ColorFilter.mode(
QuotidienTheme.coral.withValues(alpha: 0.3),
BlendMode.srcATop,
),
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row(
children: [
const Icon(Icons.error_outline, color: QuotidienTheme.ink),
const SizedBox(width: 12),
Expanded(
child: Text(
message,
style: GoogleFonts.merriweather(
fontSize: 13,
color: QuotidienTheme.ink,
child: NineSliceAsset.bandeau(
assetPath: QuotidienTheme.bandeauLime,
height: 90,
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row(
children: [
const Icon(Icons.error_outline, color: QuotidienTheme.ink),
const SizedBox(width: 12),
Expanded(
child: Text(
message,
style: GoogleFonts.merriweather(
fontSize: 13,
color: QuotidienTheme.ink,
),
),
),
),
if (onRetry != null)
TextButton(
onPressed: onRetry,
child: const Text('Réessayer'),
),
],
if (onRetry != null)
TextButton(
onPressed: onRetry,
child: const Text('Réessayer'),
),
],
),
),
);
}