diff --git a/lib/screens/common_widgets/button_navbar.dart b/lib/screens/common_widgets/button_navbar.dart new file mode 100644 index 00000000..1daf31cd --- /dev/null +++ b/lib/screens/common_widgets/button_navbar.dart @@ -0,0 +1,99 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:apidash/providers/providers.dart'; + +class NavbarButton extends ConsumerWidget { + const NavbarButton({ + super.key, + required this.railIdx, + this.buttonIdx, + required this.selectedIcon, + required this.icon, + required this.label, + this.showLabel = true, + this.isCompact = false, + this.onTap, + }); + final int railIdx; + final int? buttonIdx; + final IconData selectedIcon; + final IconData icon; + final String label; + final bool showLabel; + final Function()? onTap; + final bool isCompact; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final bool isSelected = railIdx == buttonIdx; + final Size size = isCompact ? const Size(56, 32) : const Size(65, 32); + return MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: isSelected + ? null + : () { + if (buttonIdx != null) { + ref.read(navRailIndexStateProvider.notifier).state = + buttonIdx!; + if (railIdx > 1 && buttonIdx! <= 1) { + ref.read(leftDrawerStateProvider.notifier).state = false; + } + } + onTap?.call(); + }, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TextButton( + style: isSelected + ? TextButton.styleFrom( + fixedSize: size, + backgroundColor: + Theme.of(context).colorScheme.secondaryContainer, + ) + : TextButton.styleFrom( + fixedSize: size, + ), + onPressed: isSelected + ? null + : () { + if (buttonIdx != null) { + ref.read(navRailIndexStateProvider.notifier).state = + buttonIdx!; + if (railIdx > 1 && buttonIdx! <= 1) { + ref.read(leftDrawerStateProvider.notifier).state = + false; + } + } + onTap?.call(); + }, + child: Icon( + isSelected ? selectedIcon : icon, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + showLabel ? const SizedBox(height: 4) : const SizedBox.shrink(), + showLabel + ? Text( + label, + style: Theme.of(context).textTheme.labelSmall!.copyWith( + fontWeight: FontWeight.w600, + color: isSelected + ? Theme.of(context) + .colorScheme + .onSecondaryContainer + : Theme.of(context) + .colorScheme + .onSurface + .withOpacity(0.65), + ), + ) + : const SizedBox.shrink(), + ], + ), + ), + ); + } +} diff --git a/lib/screens/common_widgets/common_widgets.dart b/lib/screens/common_widgets/common_widgets.dart index 57282325..6c08887a 100644 --- a/lib/screens/common_widgets/common_widgets.dart +++ b/lib/screens/common_widgets/common_widgets.dart @@ -1,3 +1,4 @@ +export 'button_navbar.dart'; export 'editor_title.dart'; export 'editor_title_actions.dart'; export 'envfield_url.dart'; diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 3be66748..9699e581 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:apidash/providers/providers.dart'; import 'package:apidash/consts.dart'; +import 'common_widgets/common_widgets.dart'; import 'envvar/environment_page.dart'; import 'home_page/home_page.dart'; -import 'intro_page.dart'; import 'settings_page.dart'; class Dashboard extends ConsumerWidget { @@ -52,6 +52,19 @@ class Dashboard extends ConsumerWidget { 'Variables', style: Theme.of(context).textTheme.labelSmall, ), + kVSpacer10, + IconButton( + isSelected: railIdx == 2, + onPressed: () { + ref.read(navRailIndexStateProvider.notifier).state = 2; + }, + icon: const Icon(Icons.history_outlined), + selectedIcon: const Icon(Icons.history), + ), + Text( + 'History', + style: Theme.of(context).textTheme.labelSmall, + ), ], ), Expanded( @@ -60,30 +73,31 @@ class Dashboard extends ConsumerWidget { children: [ Padding( padding: const EdgeInsets.only(bottom: 16.0), - child: bottomButton(context, ref, railIdx, 2, - Icons.help, Icons.help_outline), + child: NavbarButton( + railIdx: railIdx, + selectedIcon: Icons.help, + icon: Icons.help_outline, + label: 'About', + showLabel: false, + isCompact: true, + ), ), Padding( padding: const EdgeInsets.only(bottom: 16.0), - child: bottomButton(context, ref, railIdx, 3, - Icons.settings, Icons.settings_outlined), + child: NavbarButton( + railIdx: railIdx, + buttonIdx: 3, + selectedIcon: Icons.settings, + icon: Icons.settings_outlined, + label: 'Settings', + showLabel: false, + isCompact: true, + ), ), ], ), ), ], - // destinations: const [ - // // NavigationRailDestination( - // // icon: Icon(Icons.home_outlined), - // // selectedIcon: Icon(Icons.home), - // // label: Text('Home'), - // // ), - // NavigationRailDestination( - // icon: Icon(Icons.auto_awesome_mosaic_outlined), - // selectedIcon: Icon(Icons.auto_awesome_mosaic), - // label: Text('Requests'), - // ), - // ], ), VerticalDivider( thickness: 1, @@ -99,7 +113,7 @@ class Dashboard extends ConsumerWidget { EnvironmentPage( scaffoldKey: mobileScaffoldKey, ), - const IntroPage(), + const SizedBox(), const SettingsPage(), ], ), @@ -109,31 +123,4 @@ class Dashboard extends ConsumerWidget { ), ); } - - TextButton bottomButton( - BuildContext context, - WidgetRef ref, - int railIdx, - int buttonIdx, - IconData selectedIcon, - IconData icon, - ) { - bool isSelected = railIdx == buttonIdx; - return TextButton( - style: isSelected - ? TextButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - ) - : null, - onPressed: isSelected - ? null - : () { - ref.read(navRailIndexStateProvider.notifier).state = buttonIdx; - }, - child: Icon( - isSelected ? selectedIcon : icon, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ); - } } diff --git a/lib/screens/mobile/dashboard.dart b/lib/screens/mobile/dashboard.dart index d1642be8..d6e73490 100644 --- a/lib/screens/mobile/dashboard.dart +++ b/lib/screens/mobile/dashboard.dart @@ -4,7 +4,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:apidash/extensions/extensions.dart'; import 'package:apidash/providers/providers.dart'; -import '../intro_page.dart'; import '../settings_page.dart'; import 'navbar.dart'; import 'requests_page/requests_page.dart'; @@ -74,9 +73,10 @@ class PageBranch extends ConsumerWidget { scaffoldKey: scaffoldKey, ); case 2: + // TODO: Implement history page return const PageBase( - title: 'About', - scaffoldBody: IntroPage(), + title: 'History', + scaffoldBody: SizedBox(), ); case 3: return const PageBase( diff --git a/lib/screens/mobile/navbar.dart b/lib/screens/mobile/navbar.dart index 99ad861d..5449f45f 100644 --- a/lib/screens/mobile/navbar.dart +++ b/lib/screens/mobile/navbar.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:apidash/providers/providers.dart'; +import '../common_widgets/common_widgets.dart'; class BottomNavBar extends ConsumerWidget { const BottomNavBar({super.key}); @@ -30,39 +31,39 @@ class BottomNavBar extends ConsumerWidget { mainAxisSize: MainAxisSize.min, children: [ Expanded( - child: customNavigationDestination(context, ref, railIdx, 0, - Icons.dashboard, Icons.dashboard_outlined, 'Requests'), - ), - Expanded( - child: customNavigationDestination( - context, - ref, - railIdx, - 1, - Icons.laptop_windows, - Icons.laptop_windows_outlined, - 'Variables'), - ), - Expanded( - child: customNavigationDestination( - context, - ref, - railIdx, - 2, - Icons.help, - Icons.help_outline, - 'About', + child: NavbarButton( + railIdx: railIdx, + buttonIdx: 0, + selectedIcon: Icons.dashboard, + icon: Icons.dashboard_outlined, + label: 'Requests', ), ), Expanded( - child: customNavigationDestination( - context, - ref, - railIdx, - 3, - Icons.settings, - Icons.settings_outlined, - 'Settings', + child: NavbarButton( + railIdx: railIdx, + buttonIdx: 1, + selectedIcon: Icons.laptop_windows, + icon: Icons.laptop_windows_outlined, + label: 'Variables', + ), + ), + Expanded( + child: NavbarButton( + railIdx: railIdx, + buttonIdx: 2, + selectedIcon: Icons.history, + icon: Icons.history_outlined, + label: 'History', + ), + ), + Expanded( + child: NavbarButton( + railIdx: railIdx, + buttonIdx: 3, + selectedIcon: Icons.settings, + icon: Icons.settings_outlined, + label: 'Settings', ), ), ], @@ -73,82 +74,3 @@ class BottomNavBar extends ConsumerWidget { ); } } - -Widget customNavigationDestination( - BuildContext context, - WidgetRef ref, - int railIdx, - int buttonIdx, - IconData selectedIcon, - IconData icon, - String label, { - bool showLabel = true, - Function()? onTap, -}) { - bool isSelected = railIdx == buttonIdx; - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: isSelected - ? null - : () { - ref.read(navRailIndexStateProvider.notifier).state = buttonIdx; - if (railIdx > 1 && buttonIdx <= 1) { - ref.read(leftDrawerStateProvider.notifier).state = false; - } - onTap?.call(); - }, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Ink( - width: 65, - height: 32, - decoration: BoxDecoration( - color: isSelected - ? Theme.of(context).colorScheme.secondaryContainer - : Colors.transparent, - borderRadius: BorderRadius.circular(30), - ), - child: InkWell( - borderRadius: BorderRadius.circular(30), - onTap: isSelected - ? null - : () { - ref.read(navRailIndexStateProvider.notifier).state = - buttonIdx; - if (railIdx > 1 && buttonIdx <= 1) { - ref.read(leftDrawerStateProvider.notifier).state = - false; - } - onTap?.call(); - }, - child: Icon( - isSelected ? selectedIcon : icon, - color: isSelected - ? Theme.of(context).colorScheme.onSecondaryContainer - : Theme.of(context).colorScheme.onSurface.withOpacity(0.65), - ), - ), - ), - showLabel ? const SizedBox(height: 4) : const SizedBox.shrink(), - showLabel - ? Text( - label, - style: Theme.of(context).textTheme.labelSmall!.copyWith( - fontWeight: FontWeight.w600, - color: isSelected - ? Theme.of(context).colorScheme.onSecondaryContainer - : Theme.of(context) - .colorScheme - .onSurface - .withOpacity(0.65), - ), - ) - : const SizedBox.shrink(), - ], - ), - ), - ); -}