import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:search_engine/screens/config.dart'; import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart' as nav; class BaseScreen extends StatelessWidget { final Widget child; final String? title; final bool showSearchBar; final bool showSettingsButton; final bool showUserAvatar; final TextEditingController? searchController; final Function(String)? onSearchChanged; final Function(String)? onSearchSubmitted; final String? searchHintText; final Widget? searchSuffixIcon; final EdgeInsetsGeometry contentPadding; final Widget? drawer; final bool returnButton; const BaseScreen({ super.key, required this.child, this.title, this.showSearchBar = false, this.showSettingsButton = false, this.showUserAvatar = false, this.searchController, this.onSearchChanged, this.onSearchSubmitted, this.searchHintText, this.searchSuffixIcon, this.contentPadding = const EdgeInsets.all(20.0), this.drawer, this.returnButton = false, }); @override Widget build(BuildContext context) { final isLandscape = MediaQuery.of(context).orientation == Orientation.landscape; return Scaffold( drawer: drawer, drawerEnableOpenDragGesture: true, drawerEdgeDragWidth: 50, onDrawerChanged: (isOpened) {}, body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Layout adaptativo según la orientación if (isLandscape) _buildLandscapeHeader(context) else _buildPortraitHeader(context), // Content area Expanded( child: child, ), ], ), ), ); } // Layout para orientación horizontal (landscape) Widget _buildLandscapeHeader(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 4.0), child: Row( children: [ // Navigation icon (back button or drawer) if (returnButton) IconButton( icon: const Icon(Icons.arrow_back, size: 20), onPressed: () => Navigator.pop(context), padding: EdgeInsets.zero, constraints: const BoxConstraints(), visualDensity: VisualDensity.compact, ) else if (drawer != null) IconButton( icon: const Icon(Icons.menu, size: 20), onPressed: () => Scaffold.of(context).openDrawer(), padding: EdgeInsets.zero, constraints: const BoxConstraints(), visualDensity: VisualDensity.compact, ), // Title if (title != null) Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: Text( title!, style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), ), const SizedBox(width: 8), // Search bar inline if (showSearchBar && searchController != null) Expanded( child: SizedBox( height: 34, child: TextFormField( decoration: InputDecoration( fillColor: const Color(0xFFEBEBEB), filled: true, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), prefixIcon: const Icon(Icons.search, color: Colors.grey, size: 18), hintText: searchHintText ?? 'search_placeholder'.tr(), hintStyle: const TextStyle( color: Colors.grey, fontSize: 14, ), contentPadding: const EdgeInsets.symmetric(horizontal: 4), isDense: true, suffixIcon: searchController?.text.isNotEmpty ?? false ? IconButton( icon: const Icon(Icons.clear, size: 18), padding: EdgeInsets.zero, constraints: const BoxConstraints(), onPressed: () { searchController?.clear(); onSearchChanged?.call(''); }, ) : null, ), controller: searchController, onChanged: onSearchChanged, onFieldSubmitted: onSearchSubmitted, autofocus: false, autocorrect: true, style: const TextStyle(fontSize: 14), ), ), ), // Settings button if (showSettingsButton) IconButton( onPressed: () => nav.pushScreenWithoutNavBar(context, const ConfigView()), icon: const Icon(Icons.settings, size: 20), padding: EdgeInsets.zero, constraints: const BoxConstraints(), visualDensity: VisualDensity.compact, ), // User avatar if (showUserAvatar) const Padding( padding: EdgeInsets.only(left: 4), child: CircleAvatar( backgroundColor: Colors.grey, radius: 12, ), ), ], ), ); } // Layout para orientación vertical (portrait) Widget _buildPortraitHeader(BuildContext context) { return Column( children: [ // Header row with title and buttons Padding( padding: const EdgeInsets.only( left: 12.0, right: 12.0, top: 6.0, bottom: 4.0, ), child: Row( children: [ // Navigation icon (back button or drawer) if (returnButton) IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => Navigator.pop(context), padding: const EdgeInsets.all(4), constraints: const BoxConstraints(), iconSize: 20, ) else if (drawer != null) IconButton( icon: const Icon(Icons.menu), onPressed: () => Scaffold.of(context).openDrawer(), padding: const EdgeInsets.all(4), constraints: const BoxConstraints(), iconSize: 20, ), // Title if (title != null) Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: Text( title!, style: const TextStyle( fontSize: 28, fontWeight: FontWeight.bold, ), ), ), ), // Settings button if (showSettingsButton) IconButton( onPressed: () => nav.pushScreenWithoutNavBar(context, const ConfigView()), icon: const Icon(Icons.settings, size: 20), padding: const EdgeInsets.all(4), constraints: const BoxConstraints(), visualDensity: VisualDensity.compact, ), // User avatar if (showUserAvatar) const Padding( padding: EdgeInsets.only(left: 4), child: CircleAvatar( backgroundColor: Colors.grey, radius: 12, ), ), ], ), ), // Search bar in a separate row if (showSearchBar && searchController != null) Padding( padding: const EdgeInsets.only( left: 12.0, right: 12.0, bottom: 6.0, ), child: SizedBox( height: 34, child: TextFormField( decoration: InputDecoration( fillColor: const Color(0xFFEBEBEB), filled: true, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), prefixIcon: const Icon(Icons.search, color: Colors.grey, size: 18), hintText: searchHintText ?? 'search_placeholder'.tr(), hintStyle: const TextStyle( color: Colors.grey, fontSize: 14, ), contentPadding: const EdgeInsets.symmetric(horizontal: 4), isDense: true, suffixIcon: searchController?.text.isNotEmpty ?? false ? IconButton( icon: const Icon(Icons.clear, size: 18), padding: EdgeInsets.zero, constraints: const BoxConstraints(), onPressed: () { searchController?.clear(); onSearchChanged?.call(''); }, ) : null, ), controller: searchController, onChanged: onSearchChanged, onFieldSubmitted: onSearchSubmitted, autofocus: false, autocorrect: true, style: const TextStyle(fontSize: 14), ), ), ), ], ); } }