import 'dart:ui'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import '../widgets/custom_text_field.dart'; import '../utils/api_config.dart'; import 'route_recommendation_screen.dart'; class SearchRouteScreen extends StatefulWidget { const SearchRouteScreen({super.key}); @override State createState() => _SearchRouteScreenState(); } class _SearchRouteScreenState extends State { String? selectedBikeType; String? selectedUserType; String selectedSpeed = "Sedang"; // Default: Sedang bool _isLoading = false; // Fungsi untuk memanggil API Rekomendasi SAW Future _findRoutes() async { if (selectedUserType == null || selectedBikeType == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Tolong pilih tipe pengguna dan jenis sepeda!')), ); return; } setState(() => _isLoading = true); try { final response = await http.post( Uri.parse('${ApiConfig.baseUrl}/recommend_routes.php'), body: { 'jenis_sepeda': selectedBikeType, 'tipe_pengguna': selectedUserType, }, ); final data = jsonDecode(response.body); if (!mounted) return; if (data['status'] == 'success') { Navigator.push( context, MaterialPageRoute( builder: (context) => RouteRecommendationScreen( routes: data['data'], selectedSpeed: selectedSpeed, ), ), ); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Gagal: ${data['message']}')), ); } } catch (e) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: $e')), ); } finally { if (mounted) setState(() => _isLoading = false); } } @override Widget build(BuildContext context) { return Scaffold( body: Container( width: double.infinity, height: double.infinity, decoration: const BoxDecoration( gradient: LinearGradient( colors: [Color(0xFF3949AB), Color(0xFF00BCD4)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), child: Stack( children: [ SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.symmetric( horizontal: 24.0, vertical: 20.0), child: Column( children: [ const SizedBox(height: 40), // Header Section const Icon(Icons.explore_outlined, size: 60, color: Colors.white), const SizedBox(height: 16), const Text( "Cari Rute Terbaik", style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Colors.white, fontFamily: 'Montserrat', ), ), const Text( "Tentukan kriteria perjalanan Anda", style: TextStyle(fontSize: 15, color: Colors.white70), ), const SizedBox(height: 40), // GLASSMORPHISM FORM CARD ClipRRect( borderRadius: BorderRadius.circular(30), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), child: Container( padding: const EdgeInsets.all(24.0), decoration: BoxDecoration( color: Colors.white.withOpacity(0.15), borderRadius: BorderRadius.circular(30), border: Border.all( color: Colors.white.withOpacity(0.3), width: 1.5, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 1. TIPE PENGGUNA _buildLabel("TIPE PENGGUNA"), _buildGlassDropdown( ['Profesional', 'Amatir'], Icons.person_outline, "Pilih Tipe Pengguna", (val) => setState(() => selectedUserType = val), selectedUserType, ), const SizedBox(height: 24), // 2. JENIS SEPEDA _buildLabel("JENIS SEPEDA"), _buildGlassDropdown( ['Road Bike', 'MTB', 'Hybrid'], Icons.pedal_bike, "Pilih Jenis Sepeda", (val) => setState(() => selectedBikeType = val), selectedBikeType, ), const SizedBox(height: 24), // 3. KECEPATAN (3 Pilihan: Lambat, Sedang, Cepat) _buildLabel("MODE BERSEPEDA"), const SizedBox(height: 8), Row( children: [ _buildSpeedCard( "Lambat", Icons.directions_walk), const SizedBox(width: 10), _buildSpeedCard( "Sedang", Icons.directions_bike), const SizedBox(width: 10), _buildSpeedCard("Cepat", Icons.flash_on), ], ), const SizedBox(height: 32), // SUBMIT BUTTON SizedBox( width: double.infinity, height: 55, child: ElevatedButton( onPressed: _isLoading ? null : _findRoutes, style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: const Color(0xFF3949AB), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), elevation: 0, ), child: _isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Color(0xFF3949AB), ), ) : const Text( "TEMUKAN RUTE", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 16, letterSpacing: 1.2, ), ), ), ), ], ), ), ), ), const SizedBox(height: 40), ], ), ), ), ], ), ), ); } Widget _buildLabel(String text) { return Padding( padding: const EdgeInsets.only(left: 4, bottom: 8), child: Text( text, style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.white.withOpacity(0.8), letterSpacing: 1.5, ), ), ); } Widget _buildGlassDropdown(List items, IconData icon, String hint, void Function(String?) onChanged, String? value) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(15), border: Border.all(color: Colors.white.withOpacity(0.3)), ), child: DropdownButtonHideUnderline( child: DropdownButtonFormField( value: value, dropdownColor: const Color(0xFF1E2140).withOpacity(0.9), style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w500), decoration: InputDecoration( border: InputBorder.none, icon: Icon(icon, color: Colors.white70, size: 22), ), items: items.map((String value) { return DropdownMenuItem( value: value, child: Text(value, style: const TextStyle(color: Colors.white)), ); }).toList(), onChanged: onChanged, hint: Text(hint, style: const TextStyle(color: Colors.white54)), ), ), ); } Widget _buildSpeedCard(String label, IconData icon) { bool isSelected = selectedSpeed == label; return Expanded( child: GestureDetector( onTap: () => setState(() => selectedSpeed = label), child: Container( padding: const EdgeInsets.symmetric(vertical: 16), decoration: BoxDecoration( color: isSelected ? Colors.white : Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(15), border: Border.all( color: isSelected ? Colors.white : Colors.white.withOpacity(0.3), width: 1.5, ), ), child: Column( children: [ Icon( icon, color: isSelected ? const Color(0xFF3949AB) : Colors.white70, ), const SizedBox(height: 8), Text( label, style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: isSelected ? const Color(0xFF3949AB) : Colors.white70, ), ), ], ), ), ), ); } }