etm-powersync-app/lib/widgets/production_card.dart
etm d5dc0c7ca5 Initial commit : Flutter app nymea energy monitor
- NymeaService : auth complète (Hello → Authenticate → SetNotificationStatus)
- Token top-level dans chaque requête JSON-RPC (fix critique GetThings)
- Persistance token via shared_preferences par hôte
- Dashboard : champs utilisateur/mot de passe dans le dialog de connexion
- ThingDetailScreen : renommer, réglages (settingsTypes) et supprimer
- NymeaThingClass : champ settingsTypes parsé depuis l'API
- NymeaThing : copyWith(name) + settingValue()
- Fix overflow _StateChip dans ThingsScreen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 16:57:46 +01:00

177 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:percent_indicator/percent_indicator.dart';
import '../models/energy_data.dart';
import '../theme/app_theme.dart';
class ProductionCard extends StatelessWidget {
final EnergyData data;
const ProductionCard({super.key, required this.data});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Production du jour',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: AppTheme.textDark,
),
),
Text(
'${_formatEnergy(data.dayProductionWh)} Wh',
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: AppTheme.textDark,
),
),
],
),
CircularPercentIndicator(
radius: 35,
lineWidth: 6,
percent: (data.selfConsumptionRate / 100).clamp(0, 1),
center: Text(
'${data.selfConsumptionRate.toStringAsFixed(0)}%',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13,
),
),
progressColor: AppTheme.primaryGreen,
backgroundColor: Colors.grey.shade200,
),
],
),
const Divider(height: 24),
// Self-consumption
_StatRow(
icon: Icons.home_rounded,
iconColor: AppTheme.solarYellow,
label: 'Usage personnel',
value: '${_formatEnergy(data.daySelfConsumptionWh)} Wh',
subLabel: 'Autoconsommation',
percent: data.selfConsumptionRate,
color: AppTheme.solarYellow,
),
const SizedBox(height: 12),
// Grid injection
_StatRow(
icon: Icons.electrical_services_rounded,
iconColor: AppTheme.gridGray,
label: 'Vers réseau',
value: '${_formatEnergy(data.dayGridInjectionWh)} Wh',
subLabel: 'Autonomie',
percent: data.autonomyRate,
color: AppTheme.homeBlue,
),
],
),
),
);
}
String _formatEnergy(double wh) {
if (wh >= 1000) return '${(wh / 1000).toStringAsFixed(2)} k';
return wh.toStringAsFixed(0);
}
}
class _StatRow extends StatelessWidget {
final IconData icon;
final Color iconColor;
final String label;
final String value;
final String subLabel;
final double percent;
final Color color;
const _StatRow({
required this.icon,
required this.iconColor,
required this.label,
required this.value,
required this.subLabel,
required this.percent,
required this.color,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: iconColor.withValues(alpha:0.15),
shape: BoxShape.circle,
),
child: Icon(icon, color: iconColor, size: 20),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label,
style: const TextStyle(
fontSize: 14, color: AppTheme.textLight)),
Text(value,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: AppTheme.textDark)),
],
),
const SizedBox(height: 4),
Row(
children: [
Text(
'$subLabel : ${percent.toStringAsFixed(0)}%',
style: TextStyle(fontSize: 11, color: color),
),
const SizedBox(width: 8),
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(4),
child: LinearProgressIndicator(
value: (percent / 100).clamp(0, 1),
backgroundColor: Colors.grey.shade200,
valueColor: AlwaysStoppedAnimation(color),
minHeight: 5,
),
),
),
],
),
],
),
),
],
),
],
);
}
}