TKK_E32210103/lib/detail copy.dart

443 lines
14 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:app_ta/theme.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
class DetailTest extends StatefulWidget {
final String ip;
DetailTest(this.ip);
@override
State<DetailTest> createState() => _DetailTestState();
}
class _DetailTestState extends State<DetailTest> {
TextEditingController durasi = TextEditingController();
Timer? timer; // Gunakan nullable Timer
int sec = 0;
bool isLoading = true; // Tambahkan variabel untuk menunjukkan apakah sedang loading
@override
void initState() {
super.initState();
startTimer(); // Memulai timer saat initState dipanggil
}
void startTimer() {
timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
// Kirim permintaan ke ESP32 untuk mendapatkan waktu
http.get(Uri.parse('http://${widget.ip}/get-time')).then((response) {
// Periksa apakah respons berhasil dan memiliki data
if (response.statusCode == 200) {
// Ubah respons JSON menjadi Map
Map<String, dynamic> data = jsonDecode(response.body);
// Perbarui waktu sesuai respons dari ESP32
setState(() {
// Ambil nilai jam, menit, dan detik dari respons
int hours = data['hours'];
int minutes = data['minutes'];
int seconds = data['seconds'];
// Ubah waktu menjadi detik dan perbarui state
sec = hours * 3600 + minutes * 60 + seconds;
isLoading = false; // Setelah waktu berhasil diambil, loading selesai
});
// Jika waktu habis, atur nilai sec menjadi 0
if (sec <= 0) {
t.cancel();
}
} else {
// Jika respons gagal, tampilkan pesan kesalahan di konsol
print('Failed to fetch time: ${response.statusCode}');
}
}).catchError((error) {
// Tangani kesalahan jaringan jika terjadi
print('Error fetching time: $error');
});
});
}
@override
void dispose() {
// Batalkan timer saat widget di dispose
timer?.cancel();
super.dispose();
}
void onIncrementTime(int timeInMilliseconds) async {
// Kirim durasi waktu ke ESP32 dalam milidetik melalui HTTP POST
await http.post(
Uri.parse('http://${widget.ip}/set-timer'),
body: {'timer': timeInMilliseconds.toString()},
).then((response) {
if (response.statusCode == 200) {
// Jika waktu berhasil diatur pada ESP32
showBottomNotification(context, 'timer telah diatur.');
}
}).catchError((error) {
// Tangani kesalahan jika gagal mengatur waktu pada ESP32
print('Error setting timer: $error');
});
if (sec <= 0 && !timer!.isActive) {
// Jika waktu habis dan timer berhenti, mulai timer kembali
startTimer();
} else {
// Jika waktu belum habis, tambahkan waktu baru ke nilai sec yang ada
setState(() {
sec += timeInMilliseconds ~/ 1000; // Konversi waktu ke detik
});
}
}
void resetTimer() async {
// Kirim permintaan ke ESP32 untuk mereset timer
await http.get(Uri.parse('http://${widget.ip}/reset-timer')).then((response) {
if (response.statusCode == 200) {
// Jika berhasil mereset timer, atur nilai sec menjadi 0
setState(() {
sec = 0;
});
showBottomNotification(context, 'timer telah direset.');
} else {
// Jika gagal mereset timer, tampilkan pesan kesalahan di konsol
print('Failed to reset timer: ${response.statusCode}');
}
}).catchError((error) {
// Tangani kesalahan jaringan jika terjadi
print('Error resetting timer: $error');
});
}
void showBottomNotification(BuildContext context, String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message, style: GoogleFonts.poppins(),),
duration: Duration(seconds: 2),
behavior: SnackBarBehavior.floating,
backgroundColor: primaryColor,
),
);
}
Widget header() {
return Center(
child: Column(
children: [
SizedBox(
height: 16,
),
Container(
height: 90,
width: 90,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/ps.png'),
)),
),
Text(
'${widget.ip}',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
)
],
),
);
}
Widget countDown() {
int hours = sec ~/ 3600;
int minutes = (sec % 3600) ~/ 60;
int seconds = sec % 60;
String hoursStr = hours.toString().padLeft(2, '0');
String minutesStr = minutes.toString().padLeft(2, '0');
String secondsStr = seconds.toString().padLeft(2, '0');
return Center(
child: Container(
margin: EdgeInsets.only(top: 36),
height: 84,
width: 400,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
border: Border.all(width: 2, color: primaryColor)),
child: Center(
child: Text(
'$hoursStr:$minutesStr:$secondsStr',
style: GoogleFonts.spaceMono(fontSize: 52, fontWeight: FontWeight.bold, color: Colors.red),
),
),
),
);
}
Widget billing() {
return Container(
margin: EdgeInsets.only(top: 36),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tambah Durasi Sewa',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.only(top: 8),
height: 46,
width: 164,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(width: 2, color: primaryColor)),
child: Center(
child: Container(
margin: EdgeInsets.only(left: 10),
child: TextFormField(
controller: durasi,
keyboardType: TextInputType.number,
style: primaryTextStyle,
cursorColor: primaryColor,
decoration: InputDecoration.collapsed(
hintText: 'masukkan durasi',
hintStyle: GoogleFonts.poppins(fontSize: 12)),
),
),
),
),
SizedBox(
width: 14,
),
Container(
child: Center(
child: Text(
'menit',
style: primaryTextStyle.copyWith(fontSize: 16),
),
),
)
],
),
Container(
margin: EdgeInsets.only(top: 20),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () {
setState(() {
durasi.text = "30";
});
},
child: Container(
height: 38,
width: 102,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: primaryColor),
child: Center(
child: Text(
'30 menit',
style: secondTextStyle,
)),
),
),
GestureDetector(
onTap: () {
setState(() {
durasi.text = "60";
});
},
child: Container(
height: 38,
width: 102,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: primaryColor),
child: Center(
child: Text(
'60 menit',
style: secondTextStyle,
)),
),
),
GestureDetector(
onTap: () {
setState(() {
durasi.text = "90";
});
},
child: Container(
height: 38,
width: 102,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: primaryColor),
child: Center(
child: Text(
'90 menit',
style: secondTextStyle,
)),
),
),
],
),
Container(
margin: EdgeInsets.only(top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () {
setState(() {
durasi.text = "120";
});
},
child: Container(
height: 38,
width: 102,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: primaryColor),
child: Center(
child: Text(
'120 menit',
style: secondTextStyle,
)),
),
),
GestureDetector(
onTap: () {
setState(() {
durasi.text = "180";
});
},
child: Container(
height: 38,
width: 102,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: primaryColor),
child: Center(
child: Text(
'180 menit',
style: secondTextStyle,
)),
),
),
GestureDetector(
onTap: () {
setState(() {
durasi.text = "240";
});
},
child: Container(
height: 38,
width: 102,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: primaryColor),
child: Center(
child: Text(
'240 menit',
style: secondTextStyle,
)),
),
),
],
),
)
],
),
)
],
),
);
}
Widget button() {
return Center(
child: Container(
margin: EdgeInsets.only(top: 14),
height: 44,
width: 246,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: primaryColor),
child: TextButton(
onPressed: () {
// Konversi input dari menit menjadi milidetik
int durationInMilliseconds = int.parse(durasi.text) * 60 * 1000;
onIncrementTime(durationInMilliseconds);
},
child: Text('Set', style: secondTextStyle),
),
),
);
}
Widget resetButton() {
return Center(
child: Column(
children: [
Container(
margin: EdgeInsets.only(top: 14),
height: 44,
width: 246,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: Colors.red),
child: TextButton(
onPressed: () {
resetTimer(); // Panggil fungsi resetTimer saat tombol ditekan
},
child: Text('Reset', style: secondTextStyle.copyWith(color: Colors.white)),
),
),
SizedBox(height: 14,),
Text('setiap waktu habis jangan lupa klik reset :)', style: primaryTextStyle,)
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back_ios_new_rounded, color: primaryColor,),
),
),
body: isLoading // Tampilkan loading widget jika sedang loading
? Center(
child: CircularProgressIndicator(
color: primaryColor,
),
)
: Container(
margin: EdgeInsets.symmetric(horizontal: 30),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
header(),
countDown(),
billing(),
button(),
resetButton()
],
),
),
),
);
}
}