uaestats_fe/lib/presentation/components/my_bottom_nav_bar.dart
2024-10-28 16:45:11 +05:30

179 lines
4.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bottom_bar_asset_icon_path.dart';
import 'package:uae_stat/infrastructure/services/packages/go_router.dart';
import 'package:uae_stat/infrastructure/services/packages/list.dart';
class MyBottomNavBar extends HookConsumerWidget {
const MyBottomNavBar({super.key});
static double height = 72.125;
BottomNavBarItem? _calculateSelectedItem(BuildContext context) {
final path = GoRouterState.of(context).pathWithParameters;
final pathComponents = path.split('/');
final tabSubPath = pathComponents[2];
final e = BottomNavBarItem.values.firstWhereOrNull(
(e) => e.routePath == tabSubPath,
);
return e;
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedItem = _calculateSelectedItem(context);
final itemButtons = BottomNavBarItem.values
.map<Widget>(
(e) => Padding(
padding: EdgeInsets.symmetric(
horizontal: e == BottomNavBarItem.home ? 20 : 12,
),
child: _BottomNavBarButton(
e,
isSelected: e == selectedItem,
onTap: () => context.go('/${context.language}/${e.routePath}'),
),
),
)
.toList();
return FittedBox(
fit: BoxFit.scaleDown,
child: Padding(
padding: EdgeInsets.only(
top: 8,
bottom: 8 + MediaQuery.of(context).padding.bottom,
),
child: SizedBox(
height: 58,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: itemButtons,
),
),
),
);
}
}
class _BottomNavBarButton extends HookConsumerWidget {
const _BottomNavBarButton(
this.e, {
required this.isSelected,
required this.onTap,
});
final BottomNavBarItem e;
final bool isSelected;
final void Function() onTap;
@override
Widget build(BuildContext context, WidgetRef ref) {
final animCtl = useAnimationController(
duration: kThemeAnimationDuration,
);
if (isSelected) {
animCtl.forward();
} else {
animCtl.reverse();
}
final img = AnimatedBuilder(
animation: animCtl,
builder: (context, child) => Image.asset(
e.imgPath,
height: e.imgHeight.toDouble(),
// width: e.imgWidth.toDouble(),
color: isSelected
? Color.lerp(
Colors.grey[600],
Colors.black,
animCtl.value,
)
: Colors.grey[600],
),
);
final title = AnimatedBuilder(
animation: animCtl,
builder: (context, _) => Text(
context.translate(e.titleEN, e.titleAR),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 10,
color: isSelected
? Color.lerp(
Colors.grey[600],
Colors.black,
animCtl.value,
)
: Colors.grey[600],
),
overflow: TextOverflow.fade,
maxLines: 1,
),
);
return InkWell(
onTap: onTap,
child: Column(
children: [
Expanded(child: Center(child: img)),
title,
],
),
);
}
}
enum BottomNavBarItem {
home(
titleEN: 'HOME',
titleAR: 'الصفحة الرئيسية',
imgPath: BottomBarAssetIconPath.home,
imgHeight: 23.5,
imgWidth: 23.5,
routePath: 'home',
),
uaeNumbers(
titleEN: 'UAE Numbers',
titleAR: 'أرقام الإمارات',
imgPath: BottomBarAssetIconPath.uaeMap,
imgHeight: 25.86,
imgWidth: 25,
routePath: 'uae-numbers',
),
competitiveness(
titleEN: 'Competitiveness',
titleAR: 'التقارير التنافسية',
imgPath: BottomBarAssetIconPath.ranking,
imgHeight: 24.0,
imgWidth: 25.35,
routePath: 'competitiveness',
),
countryStatistics(
titleEN: 'Country Statistics',
titleAR: 'إحصاءات الدول',
imgPath: BottomBarAssetIconPath.globe,
imgHeight: 25.0,
imgWidth: 25.01,
routePath: 'countries',
);
const BottomNavBarItem({
required this.titleEN,
required this.titleAR,
required this.imgPath,
required this.routePath,
required this.imgHeight,
required this.imgWidth,
});
final String titleEN;
final String titleAR;
final String imgPath;
final String routePath;
final double imgHeight;
final double imgWidth;
}