TKK_E32230206/lib/features/iot/widgets/pump_card.dart

190 lines
5.9 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import '../../../core/app_theme.dart';
class PumpCard extends StatefulWidget {
final bool isPumpOn;
final bool isOnline;
final int? activePumpDuration;
final DateTime? pumpTurnedOnAt;
final VoidCallback onToggle;
const PumpCard({
super.key,
required this.isPumpOn,
required this.isOnline,
this.activePumpDuration,
this.pumpTurnedOnAt,
required this.onToggle,
});
@override
State<PumpCard> createState() => _PumpCardState();
}
class _PumpCardState extends State<PumpCard> {
Timer? _timer;
int _remainingSeconds = 0;
@override
void initState() {
super.initState();
_updateTimer();
}
@override
void didUpdateWidget(PumpCard oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.isPumpOn != oldWidget.isPumpOn ||
widget.pumpTurnedOnAt != oldWidget.pumpTurnedOnAt ||
widget.activePumpDuration != oldWidget.activePumpDuration) {
_updateTimer();
}
}
void _updateTimer() {
_timer?.cancel();
if (widget.isPumpOn && widget.activePumpDuration != null && widget.pumpTurnedOnAt != null) {
final elapsed = DateTime.now().difference(widget.pumpTurnedOnAt!).inSeconds;
final remaining = widget.activePumpDuration! - elapsed;
if (remaining > 0) {
setState(() {
_remainingSeconds = remaining;
});
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
final currentElapsed = DateTime.now().difference(widget.pumpTurnedOnAt!).inSeconds;
final currentRemaining = widget.activePumpDuration! - currentElapsed;
if (currentRemaining > 0) {
setState(() {
_remainingSeconds = currentRemaining;
});
} else {
setState(() {
_remainingSeconds = 0;
});
timer.cancel();
}
});
} else {
setState(() {
_remainingSeconds = 0;
});
}
} else {
setState(() {
_remainingSeconds = 0;
});
}
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
String get _formattedTime {
final m = (_remainingSeconds ~/ 60).toString().padLeft(2, '0');
final s = (_remainingSeconds % 60).toString().padLeft(2, '0');
return '$m:$s';
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
decoration: BoxDecoration(
color: widget.isOnline ? AppTheme.accent : Colors.grey.shade400,
borderRadius: BorderRadius.circular(16),
boxShadow: [
if (widget.isOnline)
BoxShadow(
color: AppTheme.accent.withValues(alpha: 0.3),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(8),
),
child: const Icon(Icons.water_drop, color: Colors.white, size: 20),
),
const SizedBox(width: 12),
const Text(
'Pompa Air',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
],
),
const SizedBox(height: 12),
AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
child: Text(
!widget.isOnline
? 'Status: Offline'
: (widget.isPumpOn
? 'Status: Menyala${_remainingSeconds > 0 ? ' ($_formattedTime)' : ''}'
: 'Status: Mati'),
key: ValueKey('${widget.isPumpOn}_${widget.isOnline}_$_remainingSeconds'),
style: TextStyle(
color: widget.isPumpOn || !widget.isOnline ? Colors.white : Colors.white70,
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
),
],
),
),
const SizedBox(width: 16),
GestureDetector(
onTap: widget.isOnline ? widget.onToggle : () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Tidak dapat mengontrol pompa saat alat offline'),
backgroundColor: Colors.orange,
),
);
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 250),
width: 64,
height: 64,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: widget.isPumpOn
? Colors.white.withValues(alpha: 0.3)
: Colors.white.withValues(alpha: 0.15),
border: Border.all(color: Colors.white, width: 2.5),
),
child: Icon(
Icons.power_settings_new,
color: widget.isPumpOn ? Colors.white : Colors.white70,
size: 32,
),
),
),
],
),
);
}
}