diff --git a/lib/main_screen.dart b/lib/main_screen.dart index df56eb8..a9bacd9 100644 --- a/lib/main_screen.dart +++ b/lib/main_screen.dart @@ -144,16 +144,19 @@ class _MainScreenState extends State with TickerProviderStateMixin { children: [ _buildHeader(), Expanded( - child: Padding( + child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox(height: 16), _buildStatusCard(), const SizedBox(height: 16), _buildTrackingToggle(), - const Spacer(), - _buildActionButtons(), + const SizedBox(height: 12), + _buildSendButton(), + const SizedBox(height: 12), + _buildNavButtons(), const SizedBox(height: 20), ], ), @@ -367,74 +370,65 @@ class _MainScreenState extends State with TickerProviderStateMixin { ); } - Widget _buildActionButtons() { - return Column( - children: [ - if (_isTracking) - Padding( - padding: const EdgeInsets.only(bottom: 12), - child: SizedBox( - width: double.infinity, - height: 44, - child: OutlinedButton.icon( - onPressed: () async { - final success = await LocationBridge.reportLocation(); - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - success - ? 'Location sent to server' - : 'Failed — check logs', - ), - backgroundColor: const Color(0xFF1a1a1a), - ), - ); - } - }, - style: OutlinedButton.styleFrom( - foregroundColor: const Color(0xFF00bcd4), - side: const BorderSide(color: Color(0xFF00bcd4), width: 1), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(4), - ), - ), - icon: const Icon(Icons.arrow_upward, size: 16), - label: const Text( - 'SEND LOCATION', - style: TextStyle( - fontFamily: 'monospace', - letterSpacing: 1, - fontSize: 13, - ), + Widget _buildSendButton() { + if (!_isTracking) return const SizedBox.shrink(); + return SizedBox( + height: 44, + child: OutlinedButton.icon( + onPressed: () async { + final success = await LocationBridge.reportLocation(); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + success ? 'Location sent to server' : 'Failed — check logs', ), + backgroundColor: const Color(0xFF1a1a1a), ), + ); + } + }, + style: OutlinedButton.styleFrom( + foregroundColor: const Color(0xFF00bcd4), + side: const BorderSide(color: Color(0xFF00bcd4), width: 1), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + ), + icon: const Icon(Icons.arrow_upward, size: 16), + label: const Text( + 'SEND LOCATION', + style: TextStyle( + fontFamily: 'monospace', + letterSpacing: 1, + fontSize: 13, + ), + ), + ), + ); + } + + Widget _buildNavButtons() { + return Row( + children: [ + Expanded( + child: _buildNavButton( + icon: Icons.tune, + label: 'SETTINGS', + onTap: () => Navigator.push( + context, + MaterialPageRoute(builder: (_) => const SettingsScreen()), ), ), - Row( - children: [ - Expanded( - child: _buildNavButton( - icon: Icons.tune, - label: 'SETTINGS', - onTap: () => Navigator.push( - context, - MaterialPageRoute(builder: (_) => const SettingsScreen()), - ), - ), + ), + const SizedBox(width: 12), + Expanded( + child: _buildNavButton( + icon: Icons.terminal, + label: 'LOGS', + onTap: () => Navigator.push( + context, + MaterialPageRoute(builder: (_) => const StatusScreen()), ), - const SizedBox(width: 12), - Expanded( - child: _buildNavButton( - icon: Icons.terminal, - label: 'LOGS', - onTap: () => Navigator.push( - context, - MaterialPageRoute(builder: (_) => const StatusScreen()), - ), - ), - ), - ], + ), ), ], ); diff --git a/lib/status_screen.dart b/lib/status_screen.dart index 7e1e832..eaff22a 100644 --- a/lib/status_screen.dart +++ b/lib/status_screen.dart @@ -102,29 +102,13 @@ class _StatusScreenState extends State { appBar: AppBar( backgroundColor: const Color(0xFF161616), elevation: 0, - title: Row( - children: [ - const Icon(Icons.terminal, color: Color(0xFF00bcd4), size: 18), - const SizedBox(width: 10), - const Text( - 'EVENT LOG', - style: TextStyle( - fontFamily: 'monospace', - fontSize: 14, - fontWeight: FontWeight.w700, - letterSpacing: 2, - color: Color(0xFFe0e0e0), - ), - ), - const Spacer(), - _buildFilterChip('ALL', null), - const SizedBox(width: 6), - _buildFilterChip('LOG', 'LOCATION'), - const SizedBox(width: 6), - _buildFilterChip('SYNC', 'SYNC'), - const SizedBox(width: 6), - _buildFilterChip('ERR', 'ERROR'), - ], + leading: IconButton( + icon: const Icon( + Icons.arrow_back, + color: Color(0xFF9e9e9e), + size: 20, + ), + onPressed: () => Navigator.pop(context), ), actions: [ IconButton( @@ -133,8 +117,44 @@ class _StatusScreenState extends State { ), ], bottom: PreferredSize( - preferredSize: const Size.fromHeight(1), - child: Container(height: 1, color: const Color(0xFF2a2a2a)), + preferredSize: const Size.fromHeight(60), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 16, top: 8), + child: Row( + children: [ + const Icon( + Icons.terminal, + color: Color(0xFF00bcd4), + size: 16, + ), + const SizedBox(width: 8), + const Text( + 'EVENT LOG', + style: TextStyle( + fontFamily: 'monospace', + fontSize: 13, + fontWeight: FontWeight.w700, + letterSpacing: 2, + color: Color(0xFFe0e0e0), + ), + ), + const SizedBox(width: 16), + _buildFilterChip('ALL', null), + const SizedBox(width: 6), + _buildFilterChip('LOG', 'LOCATION'), + const SizedBox(width: 6), + _buildFilterChip('SYNC', 'SYNC'), + const SizedBox(width: 6), + _buildFilterChip('ERR', 'ERROR'), + ], + ), + ), + Container(height: 1, color: const Color(0xFF2a2a2a)), + ], + ), ), ), body: _filteredLogs.isEmpty @@ -142,10 +162,10 @@ class _StatusScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( + const Icon( Icons.inbox_outlined, size: 48, - color: const Color(0xFF2a2a2a), + color: Color(0xFF2a2a2a), ), const SizedBox(height: 16), Text( @@ -176,7 +196,7 @@ class _StatusScreenState extends State { itemCount: _filteredLogs.length, itemBuilder: (context, index) { final log = _filteredLogs[index]; - return _buildLogEntry(log); + return _buildLogEntry(log, index); }, ), ); @@ -216,7 +236,7 @@ class _StatusScreenState extends State { ); } - Widget _buildLogEntry(Map log) { + Widget _buildLogEntry(Map log, int index) { final time = _formatTimestamp(log['timestamp'] as int? ?? 0); final type = log['eventType'] as String? ?? 'UNKNOWN'; final msg = log['message'] as String? ?? ''; @@ -224,58 +244,68 @@ class _StatusScreenState extends State { final icon = _getLogIcon(type); return Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 2), - child: Row( + padding: EdgeInsets.only( + left: 12, + right: 12, + top: index == 0 ? 6 : 8, + bottom: 6, + ), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - width: 100, - child: Text( - time, - style: const TextStyle( - fontFamily: 'monospace', - fontSize: 10, - color: Color(0xFF546e7a), - ), + // Line 1: timestamp + Text( + time, + style: const TextStyle( + fontFamily: 'monospace', + fontSize: 10, + color: Color(0xFF546e7a), ), ), - Container( - width: 20, - height: 20, - decoration: BoxDecoration( - color: color.withOpacity(0.15), - borderRadius: BorderRadius.circular(3), - ), - child: Icon(icon, size: 12, color: color), - ), - const SizedBox(width: 8), - Container( - padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1), - decoration: BoxDecoration( - color: color.withOpacity(0.1), - borderRadius: BorderRadius.circular(2), - ), - child: Text( - type, - style: TextStyle( - fontFamily: 'monospace', - fontSize: 9, - fontWeight: FontWeight.w700, - letterSpacing: 1, - color: color, + const SizedBox(height: 4), + // Line 2: type badge + icon + message + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 18, + height: 18, + decoration: BoxDecoration( + color: color.withOpacity(0.15), + borderRadius: BorderRadius.circular(3), + ), + child: Icon(icon, size: 11, color: color), ), - ), - ), - const SizedBox(width: 10), - Expanded( - child: Text( - msg, - style: const TextStyle( - fontFamily: 'monospace', - fontSize: 11, - color: Color(0xFF9e9e9e), + const SizedBox(width: 7), + Container( + padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 2), + decoration: BoxDecoration( + color: color.withOpacity(0.1), + borderRadius: BorderRadius.circular(2), + ), + child: Text( + type, + style: TextStyle( + fontFamily: 'monospace', + fontSize: 9, + fontWeight: FontWeight.w700, + letterSpacing: 1, + color: color, + ), + ), ), - ), + const SizedBox(width: 10), + Expanded( + child: Text( + msg, + style: const TextStyle( + fontFamily: 'monospace', + fontSize: 11, + color: Color(0xFF9e9e9e), + ), + ), + ), + ], ), ], ),