import 'package:flutter/material.dart'; import '../../../core/app_theme.dart'; class UserGuideSheet extends StatefulWidget { const UserGuideSheet({super.key}); static void show(BuildContext context) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => const UserGuideSheet(), ); } @override State createState() => _UserGuideSheetState(); } class _UserGuideSheetState extends State { final PageController _pageController = PageController(); int _currentStep = 0; final int _totalSteps = 4; @override void dispose() { _pageController.dispose(); super.dispose(); } void _next() { if (_currentStep < _totalSteps - 1) { _pageController.nextPage( duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } else { Navigator.pop(context); } } void _previous() { if (_currentStep > 0) { _pageController.previousPage( duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } } @override Widget build(BuildContext context) { final bottomPadding = MediaQuery.of(context).viewInsets.bottom; return Container( margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 50), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(28)), ), padding: EdgeInsets.only(bottom: bottomPadding), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Drag Handle bar const SizedBox(height: 12), Container( width: 40, height: 5, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(10), ), ), const SizedBox(height: 16), // Header Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Row( children: [ const Icon( Icons.menu_book, color: AppTheme.primary, size: 24, ), const SizedBox(width: 8), const Text( "Panduan Penggunaan", style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppTheme.textPrimary, ), ), const Spacer(), IconButton( onPressed: () => Navigator.pop(context), icon: const Icon(Icons.close, color: AppTheme.textSecondary), ), ], ), ), const Divider(height: 1), // Step Stepper Indicator Row Padding( padding: const EdgeInsets.all(16.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(_totalSteps, (index) { final isDone = index < _currentStep; final isCurrent = index == _currentStep; return Row( children: [ // Step Dot AnimatedContainer( duration: const Duration(milliseconds: 300), width: 28, height: 28, decoration: BoxDecoration( color: isDone ? AppTheme.statusNormal : (isCurrent ? AppTheme.primary : Colors.grey.shade200), shape: BoxShape.circle, border: isCurrent ? Border.all(color: AppTheme.primaryDark, width: 1) : null, ), child: Center( child: isDone ? const Icon(Icons.check, color: Colors.white, size: 16) : Text( "${index + 1}", style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: isCurrent ? Colors.white : AppTheme.textSecondary, ), ), ), ), // Line connector if (index < _totalSteps - 1) AnimatedContainer( duration: const Duration(milliseconds: 300), width: MediaQuery.of(context).size.width * 0.12, height: 3, color: isDone ? AppTheme.statusNormal : Colors.grey.shade200, ), ], ); }), ), ), // Sliding step contents SizedBox( height: 340, child: PageView( controller: _pageController, onPageChanged: (step) { setState(() { _currentStep = step; }); }, children: [ _buildStepContent( icon: Icons.developer_board, title: "1. Persiapan Alat ESP32", description: "Nyalakan dan sambungkan alat fisik ke jaringan internet Anda.", points: [ "Hubungkan ESP32 ke adaptor daya micro-USB 5V.", "Lampu indikator merah pada alat akan menyala saat aktif.", "Hubungkan ESP32 ke jaringan WiFi kumbung agar alat dapat mengirim data ke internet secara real-time.", ], ), _buildStepContent( icon: Icons.qr_code_scanner, title: "2. Hubungkan Alat ke Aplikasi", description: "Gunakan Claim Code perangkat untuk sinkronisasi dengan akun Anda.", points: [ "Cari 'Claim Code' pada stiker casing luar alat atau layar LCD (contoh: JTA-X97AB3).", "Di halaman Monitoring, ketuk tombol tambah (+) pada kartu 'Belum Ada Alat Terhubung'.", "Ketikkan Claim Code perangkat Anda, lalu ketuk 'Hubungkan'. Perangkat Anda akan terikat secara permanen ke akun Anda.", ], ), _buildStepContent( icon: Icons.analytics_outlined, title: "3. Memantau Kondisi Kumbung", description: "Pahami indikator suhu & kelembapan jamur tiram Anda.", points: [ "Setelah terhubung, nilai Suhu (°C) dan Kelembapan (%) real-time akan terus diperbarui.", "Status warna kartu mempermudah monitoring: Hijau (Optimal), Oranye (Perhatian/Warning), Merah (Kritis/Bahaya).", "Gunakan filter rentang waktu (Hari, Minggu, Bulan) di bawah grafik untuk memantau tren perkembangan lingkungan kumbung.", ], ), _buildStepContent( icon: Icons.tune, title: "4. Mengatur Kontrol & Jadwal", description: "Gunakan mode penyiraman otomatis atau manual sesuai kebutuhan.", points: [ "Buka tab 'Control' di bagian bawah aplikasi untuk manajemen penyiraman.", "Mode Otomatis: Pompa menyala otomatis ketika suhu melewati batas maksimal atau kelembapan di bawah batas minimal.", "Mode Manual: Ketuk tombol pompa, pilih durasi waktu siram (15s s/d 5m) dan nyalakan.", "Jadwal: Klik '+ Tambah Jadwal' untuk menentukan penyiraman terjadwal rutin secara otomatis.", ], ), ], ), ), const Divider(height: 1), // Actions Area Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Back Button Opacity( opacity: _currentStep > 0 ? 1.0 : 0.0, child: TextButton( onPressed: _currentStep > 0 ? _previous : null, child: const Row( children: [ Icon(Icons.arrow_back, size: 18), SizedBox(width: 4), Text( "Kembali", style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ], ), ), ), // Next / Finish Button SizedBox( height: 48, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: AppTheme.primary, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), padding: const EdgeInsets.symmetric(horizontal: 24), ), onPressed: _next, child: Row( children: [ Text( _currentStep == _totalSteps - 1 ? "Selesai" : "Lanjut", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, ), ), if (_currentStep < _totalSteps - 1) ...[ const SizedBox(width: 4), const Icon(Icons.arrow_forward, size: 18, color: Colors.white), ], ], ), ), ), ], ), ), const SizedBox(height: 10), ], ), ); } Widget _buildStepContent({ required IconData icon, required String title, required String description, required List points, }) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: AppTheme.accentLight, borderRadius: BorderRadius.circular(12), ), child: Icon(icon, color: AppTheme.primary, size: 30), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppTheme.textPrimary, ), ), const SizedBox(height: 2), Text( description, style: const TextStyle( fontSize: 13, color: AppTheme.textSecondary, ), ), ], ), ), ], ), const SizedBox(height: 20), ...points.map((point) => Padding( padding: const EdgeInsets.only(bottom: 12.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: const EdgeInsets.only(top: 4), width: 6, height: 6, decoration: const BoxDecoration( color: AppTheme.primary, shape: BoxShape.circle, ), ), const SizedBox(width: 10), Expanded( child: Text( point, style: const TextStyle( fontSize: 14, color: AppTheme.textPrimary, height: 1.45, ), ), ), ], ), )), ], ), ); } }