TKK_E32230859/lib/app/modules/home-patient/views/home_patient_view.dart

344 lines
14 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/home_patient_controller.dart';
import '../../../widgets/banner_slider.dart';
import '../../../widgets/monitoring_card.dart';
import '../../../widgets/history_grafik_card.dart';
import '../../../widgets/notification_patient_card.dart';
import '../../home/controllers/home_controller.dart';
class HomePatientView extends GetView<HomePatientController> {
const HomePatientView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: RefreshIndicator(
onRefresh: controller.refreshData,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header
Padding(
padding: const EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Obx(
() => Text(
'Halo Wali Pasien ${controller.patientName.value}',
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
),
),
),
const SizedBox(width: 12),
InkWell(
onTap: () => controller.showLogoutDialog(context),
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300]!),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(Icons.logout, color: Colors.red),
),
),
],
),
),
// Banner Slider
BannerSlider(
bannerImages: controller.bannerImages,
currentCarouselIndex: controller.currentCarouselIndex,
onPageChanged: controller.updateCarouselIndex,
),
const SizedBox(height: 15),
// ── BUZZER ALERT BANNER ──────────────────────────────────
Obx(() {
if (!controller.isBuzzerActive.value) {
return const SizedBox.shrink();
}
return Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 12),
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.red[50],
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.red[200]!),
),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.red[100],
borderRadius: BorderRadius.circular(10),
),
child: Icon(
Icons.notifications_active_rounded,
color: Colors.red[700],
size: 26,
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Buzzer Aktif!',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.red[800],
),
),
const SizedBox(height: 3),
Text(
'Tetesan infus berhenti. Harap hubungi perawat.',
style: TextStyle(
fontSize: 12,
color: Colors.red[600],
height: 1.4,
),
),
],
),
),
const SizedBox(width: 10),
ElevatedButton(
onPressed: controller.turnOffBuzzer,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red[700],
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 10,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 0,
),
child: const Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.volume_off_rounded, size: 18),
SizedBox(height: 2),
Text(
'Matikan',
style: TextStyle(fontSize: 11),
),
],
),
),
],
),
),
);
}),
// ── END BUZZER ALERT BANNER ──────────────────────────────
// Monitoring Infus Section
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
'Monitoring Infus',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
),
),
// Monitoring Card
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Obx(() {
if (controller.isLoading.value) {
return Container(
padding: const EdgeInsets.all(32),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey[200]!),
),
child: const Center(child: CircularProgressIndicator()),
);
}
final infusData = controller.currentInfusData.value;
final monitoring = InfusMonitoring(
id: controller.deviceId.value,
patientName: controller.patientName.value,
deviceId: infusData.deviceId,
room: infusData.room,
roomId: '',
dropsPerMinute: infusData.dropsPerMinute,
lastUpdate: DateTime.now(),
deviceStatus: infusData.deviceStatus,
);
return MonitoringCard(
monitoring: monitoring,
onTap: () {},
);
}),
),
const SizedBox(height: 15),
// History Data Section
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
'History Data',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
),
),
// Chart Card
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Obx(() {
if (controller.isLoadingHistory.value) {
return Container(
padding: const EdgeInsets.all(32),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey[200]!),
),
child: const Center(child: CircularProgressIndicator()),
);
}
return HistoryGrafikCard(
dataPoints: controller.chartDataPoints.toList(),
onBookmarkTap: () {},
);
}),
),
const SizedBox(height: 15),
// History Notifikasi Section
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
'History Notifikasi',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
),
),
// Notifications List
Obx(() {
if (controller.isLoadingNotifications.value) {
return const Padding(
padding: EdgeInsets.all(32),
child: Center(child: CircularProgressIndicator()),
);
}
if (controller.notificationsList.isEmpty) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Container(
padding: const EdgeInsets.all(32),
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey[200]!),
),
child: Center(
child: Column(
children: [
Icon(
Icons.notifications_none,
size: 48,
color: Colors.grey[400],
),
const SizedBox(height: 12),
Text(
'Belum ada notifikasi',
style: TextStyle(
fontSize: 14,
color: Colors.grey[600],
),
),
],
),
),
),
);
}
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 20),
itemCount: controller.notificationsList.length,
itemBuilder: (context, index) {
final notification = controller.notificationsList[index];
return NotificationPatientCard(
title: notification.title,
message: notification.message,
room: notification.room,
deviceId: notification.deviceId,
timeAgo: notification.timeAgo,
onTap: () {},
);
},
);
}),
const SizedBox(height: 20),
],
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => controller.showCallDialog(context),
backgroundColor: const Color(0xFF2196F3),
child: const Icon(Icons.phone, color: Colors.white),
),
);
}
}