190 lines
5.9 KiB
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,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|