import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:geolocator/geolocator.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Panic Button', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.red), useMaterial3: true, ), home: const PanicButtonPage(), ); } } class PanicButtonPage extends StatefulWidget { const PanicButtonPage({super.key}); @override State createState() => _PanicButtonPageState(); } class _PanicButtonPageState extends State { bool _isLoading = false; String? _message; String _selectedAlertType = 'fire'; String? _currentLocation; final List> alertTypes = [ {'label': 'Fire', 'value': 'fire', 'icon': '🔥'}, {'label': 'Earthquake', 'value': 'earthquake', 'icon': '🌍'}, {'label': 'Flood', 'value': 'flood', 'icon': '💧'}, ]; Future _getCurrentLocation() async { try { final position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, ); setState(() { _currentLocation = 'Lat: ${position.latitude.toStringAsFixed(6)}, Lng: ${position.longitude.toStringAsFixed(6)}'; }); } catch (e) { setState(() { _currentLocation = 'Location error: $e'; }); } } Future _sendPanicAlert() async { setState(() { _isLoading = true; _message = null; }); try { final url = Uri.parse('https://ntfy.ubharajaya.ac.id/panic-button'); final alertMessage = 'PANIC ALERT - $_selectedAlertType detected! Emergency button pressed!\nLocation : $_currentLocation'; final response = await http.post( url, body: alertMessage, ).timeout(const Duration(seconds: 10)); if (response.statusCode == 200 || response.statusCode == 201) { setState(() { _message = 'Alert sent successfully!'; _isLoading = false; }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Panic alert sent!'), backgroundColor: Colors.green, duration: Duration(seconds: 2), ), ); } else { setState(() { _message = 'Failed to send alert. Status: ${response.statusCode}'; _isLoading = false; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Error: ${response.statusCode}'), backgroundColor: Colors.orange, duration: const Duration(seconds: 2), ), ); } } catch (e) { setState(() { _message = 'Error: $e'; _isLoading = false; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Error: $e'), backgroundColor: Colors.red, duration: const Duration(seconds: 2), ), ); } } @override void initState() { super.initState(); _getCurrentLocation(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Panic Button'), backgroundColor: Colors.red, centerTitle: true, ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Alert Type Selection Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Select Alert Type:', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: alertTypes.map((alert) { final isSelected = _selectedAlertType == alert['value']; return GestureDetector( onTap: _isLoading ? null : () { setState(() { _selectedAlertType = alert['value']!; }); }, child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( border: Border.all( color: isSelected ? Colors.red : Colors.grey, width: isSelected ? 3 : 2, ), borderRadius: BorderRadius.circular(12), color: isSelected ? Colors.red.shade50 : Colors.transparent, ), child: Column( children: [ Text( alert['icon']!, style: const TextStyle(fontSize: 28), ), const SizedBox(height: 4), Text( alert['label']!, style: TextStyle( fontSize: 12, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, color: isSelected ? Colors.red : Colors.black, ), ), ], ), ), ); }).toList(), ), ], ), ), const SizedBox(height: 50), // Panic Button GestureDetector( onTap: _isLoading ? null : _sendPanicAlert, child: Container( width: 200, height: 200, decoration: BoxDecoration( shape: BoxShape.circle, color: _isLoading ? Colors.red.shade300 : Colors.red, boxShadow: [ BoxShadow( color: Colors.red.withOpacity(0.5), blurRadius: 20, spreadRadius: 5, ), ], ), child: Center( child: _isLoading ? const SizedBox( width: 60, height: 60, child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Colors.white), strokeWidth: 4, ), ) : const Text( 'PANIC', style: TextStyle( color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold, ), ), ), ), ), const SizedBox(height: 40), if (_message != null) Text( _message!, style: const TextStyle(fontSize: 16), textAlign: TextAlign.center, ), const SizedBox(height: 20), // Tampilkan Koordinat Lokasi if (_currentLocation != null) Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border.all(color: Colors.red), borderRadius: BorderRadius.circular(8), ), child: Column( children: [ const Text( 'Current Location:', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Text( _currentLocation!, style: const TextStyle(fontSize: 12), textAlign: TextAlign.center, ), ], ), ), ], ), ), ); } }