Files
mobile/lib/features/wash/presentation/widgets/active_wash_progress_card.dart
T

164 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../../../core/theme/app_colors.dart';
import '../../domain/wash.dart';
import '../../domain/wash_progress.dart';
/// Carte lavage en cours avec pourcentage et étape du cycle.
class ActiveWashProgressCard extends StatelessWidget {
const ActiveWashProgressCard({
super.key,
required this.wash,
required this.format,
this.progress,
});
final Wash wash;
final NumberFormat format;
final WashProgress? progress;
@override
Widget build(BuildContext context) {
final p = progress ?? wash.liveProgress;
final steps = _stepsForType(wash.machineType);
final currentIndex = steps.indexWhere((s) => s.key == p.phase);
final activeStep = currentIndex >= 0 ? currentIndex : 0;
return Card(
margin: const EdgeInsets.only(bottom: 10),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: AppColors.machineRunning.withValues(alpha: 0.12),
borderRadius: BorderRadius.circular(12),
),
child: const Icon(Icons.local_laundry_service, color: AppColors.machineRunning),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(wash.machineName, style: Theme.of(context).textTheme.titleMedium),
Text(
p.phaseLabel,
style: TextStyle(
color: AppColors.machineRunning,
fontWeight: FontWeight.w600,
fontSize: 13,
),
),
],
),
),
Text(
'${p.percent}%',
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w700,
color: AppColors.machineRunning,
),
),
],
),
const SizedBox(height: 14),
ClipRRect(
borderRadius: BorderRadius.circular(6),
child: LinearProgressIndicator(
value: p.percent / 100,
minHeight: 8,
backgroundColor: AppColors.machineRunning.withValues(alpha: 0.12),
color: AppColors.machineRunning,
),
),
const SizedBox(height: 14),
Row(
children: List.generate(steps.length, (index) {
final step = steps[index];
final isDone = index < activeStep;
final isActive = index == activeStep;
final color = isDone || isActive
? AppColors.machineRunning
: AppColors.textSecondary.withValues(alpha: 0.35);
return Expanded(
child: Column(
children: [
Icon(
isDone ? Icons.check_circle : step.icon,
size: 20,
color: color,
),
const SizedBox(height: 4),
Text(
step.label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 9,
fontWeight: isActive ? FontWeight.w700 : FontWeight.normal,
color: isActive ? AppColors.machineRunning : AppColors.textSecondary,
),
),
],
),
);
}),
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
p.remainingLabel.isNotEmpty ? p.remainingLabel : 'Cycle en cours…',
style: Theme.of(context).textTheme.bodyMedium,
),
Text(
format.format(wash.cost),
style: const TextStyle(fontWeight: FontWeight.w600),
),
],
),
],
),
),
);
}
static List<_WashStep> _stepsForType(String? type) {
if (type?.startsWith('dryer') ?? false) {
return const [
_WashStep('lock', 'Verrou', Icons.lock_outline),
_WashStep('heat', 'Chauffe', Icons.whatshot_outlined),
_WashStep('dry', 'Sèche', Icons.air),
_WashStep('finish', 'Fin', Icons.check),
];
}
return const [
_WashStep('lock', 'Verrou', Icons.lock_outline),
_WashStep('fill', 'Eau', Icons.water_drop_outlined),
_WashStep('wash', 'Lave', Icons.local_laundry_service_outlined),
_WashStep('rinse', 'Rince', Icons.waves_outlined),
_WashStep('spin', 'Essore', Icons.rotate_right),
_WashStep('finish', 'Fin', Icons.check),
];
}
}
class _WashStep {
const _WashStep(this.key, this.label, this.icon);
final String key;
final String label;
final IconData icon;
}