import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:terepi_seged/pages/tracking/presentation/controllers/tracking_controller.dart'; import 'tracking_sheet.dart'; /// Kompakt tracking státusz kártya a térkép bal felső sarkában. /// /// Rögzítés közben: idő, távolság, pontok + szünet/stop gombok /// Rögzítésen kívül: egyetlen start gomb /// /// Mindig látható — tap → TrackingSheet (teljes lista + vezérlők) class TrackInfoCard extends StatelessWidget { const TrackInfoCard({super.key}); @override Widget build(BuildContext context) { return Obx(() { final ctrl = TrackingController.to; final isRec = ctrl.isRecording.value; return GestureDetector( onTap: () => _openSheet(context), child: Card( elevation: 4, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), color: Theme.of(context).colorScheme.surface.withValues(alpha: 0.92), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), child: isRec ? _RecordingContent(ctrl: ctrl) : _IdleContent(), )), ); }); } void _openSheet(BuildContext context) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => const TrackingSheet(), ); } } // ─── Rögzítés közben ────────────────────────────────────────────────────────── class _RecordingContent extends StatelessWidget { final TrackingController ctrl; const _RecordingContent({required this.ctrl}); @override Widget build(BuildContext context) { return Obx(() => Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Fejléc sor — piros pont + "REC" vagy "SZÜNET" Row(mainAxisSize: MainAxisSize.min, children: [ _StatusDot(paused: ctrl.isPaused.value), const SizedBox(width: 5), Text( ctrl.isPaused.value ? 'SZÜNET' : 'REC', style: TextStyle( color: ctrl.isPaused.value ? Colors.orange : Colors.red, fontSize: 11, fontWeight: FontWeight.w700, letterSpacing: 0.5, ), ), const SizedBox(width: 5), Obx(() { if (!ctrl.gpsSignalLost.value) return const SizedBox.shrink(); return Row(children: [ Icon(Icons.gps_off, size: 12, color: Colors.orange), const SizedBox(width: 4), Text('GPS-ejl elveszett', style: TextStyle(color: Colors.orange, fontSize: 10)) ]); }), const Spacer(), // Kártya bezárása (csak megkisebbíti, nem állítja le) GestureDetector( onTap: () {}, // placeholder — a kártya mindig látható child: Icon(Icons.unfold_less, size: 14, color: Colors.white.withOpacity(0.3)), ), ]), const SizedBox(height: 4), // Statisztika sor Row( //mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _MiniStat( icon: Icons.timer_outlined, value: ctrl.elapsedFormatted.value, label: 'Idő'), const _Divider(), _MiniStat( icon: Icons.route, value: _fmtDist(ctrl.sessionDistance.value), label: 'Távolság'), const _Divider(), _MiniStat( icon: Icons.speed, label: 'Sebesség', value: '${ctrl.currentSpeedKmh.value.toStringAsFixed(1)} km/h', ), _Divider(), _MiniStat( icon: Icons.location_on_outlined, value: '${ctrl.livePoints.length}', label: 'Pontok'), ], ), const SizedBox(height: 6), // Vezérlő gombok Row(children: [ // Szünet / Folytatás _CardButton( icon: ctrl.isPaused.value ? Icons.play_arrow : Icons.pause, color: ctrl.isPaused.value ? Colors.greenAccent : Colors.orange, onTap: ctrl.isPaused.value ? ctrl.resumeRecording : ctrl.pauseRecording, tooltip: ctrl.isPaused.value ? 'Folytatás' : 'Szünet', ), const SizedBox(width: 6), // Stop _CardButton( icon: Icons.stop, color: Colors.red, onTap: () => _confirmStop(context), tooltip: 'Befejezés', ), const Spacer(), // Nyíl → sheet megnyitás Icon(Icons.keyboard_arrow_up, size: 14, color: Colors.white.withOpacity(0.35)), ]), ], )); } void _confirmStop(BuildContext context) { Get.dialog(AlertDialog( title: const Text('Rögzítés befejezése'), content: Obx(() => Text( '${ctrl.elapsedFormatted.value} · ' '${_fmtDist(ctrl.sessionDistance.value)}\n' '${ctrl.livePoints.length} pont', )), actions: [ TextButton(onPressed: Get.back, child: const Text('Mégse')), FilledButton( style: FilledButton.styleFrom(backgroundColor: Colors.red.shade700), onPressed: () { Get.back(); ctrl.stopRecording(); }, child: const Text('Befejezés'), ), ], )); } String _fmtDist(double m) => m < 1000 ? '${m.toStringAsFixed(0)} m' : '${(m / 1000).toStringAsFixed(2)} km'; } class _Divider extends StatelessWidget { const _Divider(); @override Widget build(BuildContext context) => Container(height: 36, width: 1, color: Colors.grey.shade300); } // ─── Idle állapot ───────────────────────────────────────────────────────────── class _IdleContent extends StatelessWidget { @override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.route_outlined, size: 14, color: Colors.white.withOpacity(0.5)), const SizedBox(width: 6), Text( 'Track', style: TextStyle( color: Colors.white.withOpacity(0.55), fontSize: 12, ), ), const SizedBox(width: 8), // Indítás gomb GestureDetector( onTap: () => _startRecording(context), child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: Colors.red.withOpacity(0.2), borderRadius: BorderRadius.circular(6), border: Border.all(color: Colors.red.withOpacity(0.4)), ), child: const Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.fiber_manual_record, size: 10, color: Colors.red), SizedBox(width: 4), Text('Start', style: TextStyle( color: Colors.red, fontSize: 11, fontWeight: FontWeight.w600)), ], ), ), ), ], ); } void _startRecording(BuildContext context) { final nameCtrl = TextEditingController( text: 'Track ${DateTime.now().toString().substring(5, 16)}', ); Get.dialog(AlertDialog( title: const Text('Rögzítés indítása'), content: TextField( controller: nameCtrl, autofocus: true, decoration: const InputDecoration( labelText: 'Track neve', border: OutlineInputBorder(), ), ), actions: [ TextButton(onPressed: Get.back, child: const Text('Mégse')), FilledButton( onPressed: () { Get.back(); TrackingController.to.startRecording(); // .startRecording(name: nameCtrl.text.trim()); }, child: const Text('Indítás'), ), ], )); } } // ─── Segéd widgetek ─────────────────────────────────────────────────────────── class _StatusDot extends StatefulWidget { final bool paused; const _StatusDot({required this.paused}); @override State<_StatusDot> createState() => _StatusDotState(); } class _StatusDotState extends State<_StatusDot> with SingleTickerProviderStateMixin { late AnimationController _ctrl; late Animation _anim; @override void initState() { super.initState(); _ctrl = AnimationController( vsync: this, duration: const Duration(milliseconds: 700), )..repeat(reverse: true); _anim = Tween(begin: 0.3, end: 1.0) .animate(CurvedAnimation(parent: _ctrl, curve: Curves.easeInOut)); } @override void didUpdateWidget(_StatusDot old) { super.didUpdateWidget(old); widget.paused ? _ctrl.stop() : _ctrl.repeat(reverse: true); } @override void dispose() { _ctrl.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final color = widget.paused ? Colors.orange : Colors.red; return AnimatedBuilder( animation: _anim, builder: (_, __) => Opacity( opacity: widget.paused ? 0.6 : _anim.value, child: Container( width: 7, height: 7, decoration: BoxDecoration(color: color, shape: BoxShape.circle), ), ), ); } } class _MiniStat extends StatelessWidget { final IconData icon; final String? label; final String value; const _MiniStat({required this.icon, required this.value, this.label}); @override Widget build(BuildContext context) { return Column(mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 16, color: Theme.of(context).colorScheme.primary), const SizedBox(height: 2), Text( value, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, fontFeatures: [FontFeature.tabularFigures()], ), ), label != null ? Text(label!) : SizedBox.shrink() ]); } } class _CardButton extends StatelessWidget { final IconData icon; final Color color; final VoidCallback onTap; final String tooltip; const _CardButton({ required this.icon, required this.color, required this.onTap, required this.tooltip, }); @override Widget build(BuildContext context) { return Tooltip( message: tooltip, child: GestureDetector( onTap: onTap, child: Container( width: 28, height: 24, decoration: BoxDecoration( color: color.withOpacity(0.18), borderRadius: BorderRadius.circular(6), border: Border.all(color: color.withOpacity(0.45)), ), child: Icon(icon, size: 14, color: color), ), ), ); } }