feat: complete Simple Mode contextual routing and navigation state synchronization

This commit is contained in:
dwindown
2026-03-15 07:24:13 +07:00
parent faadc1865d
commit 25728583b3
21 changed files with 1095 additions and 320 deletions

View File

@@ -1,5 +1,9 @@
import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:hive_flutter/hive_flutter.dart';
import '../../app/theme/app_colors.dart';
import '../../data/local/hive_boxes.dart';
import '../../data/local/models/app_settings.dart';
/// 5-tab bottom navigation bar per PRD §5.1.
/// Uses Material Symbols outlined (inactive) and filled (active).
@@ -15,52 +19,89 @@ class AppBottomNavBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).bottomNavigationBarTheme.backgroundColor,
border: Border(
top: BorderSide(
color: Theme.of(context).dividerColor,
width: 0.5,
return ValueListenableBuilder<Box<AppSettings>>(
valueListenable: Hive.box<AppSettings>(HiveBoxes.settings).listenable(),
builder: (context, box, _) {
final isSimpleMode = box.get('default')?.simpleMode ?? false;
final simpleItems = const [
BottomNavigationBarItem(
icon: Icon(LucideIcons.home),
activeIcon: Icon(LucideIcons.home),
label: 'Beranda',
),
),
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.only(bottom: 8),
child: BottomNavigationBar(
currentIndex: currentIndex,
onTap: onTap,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
activeIcon: Icon(Icons.home),
label: 'Beranda',
),
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today_outlined),
activeIcon: Icon(Icons.calendar_today),
label: 'Jadwal',
),
BottomNavigationBarItem(
icon: Icon(Icons.rule_outlined),
activeIcon: Icon(Icons.rule),
label: 'Ibadah',
),
BottomNavigationBarItem(
icon: Icon(Icons.bar_chart_outlined),
activeIcon: Icon(Icons.bar_chart),
label: 'Laporan',
),
BottomNavigationBarItem(
icon: Icon(Icons.auto_fix_high_outlined),
activeIcon: Icon(Icons.auto_fix_high),
label: 'Alat',
),
],
BottomNavigationBarItem(
icon: Icon(LucideIcons.calendar),
activeIcon: Icon(LucideIcons.calendar),
label: 'Jadwal',
),
),
),
BottomNavigationBarItem(
icon: Icon(LucideIcons.bookOpen),
activeIcon: Icon(LucideIcons.bookOpen),
label: 'Tilawah',
),
BottomNavigationBarItem(
icon: Icon(LucideIcons.headphones),
activeIcon: Icon(LucideIcons.headphones),
label: 'Murattal',
),
BottomNavigationBarItem(
icon: Icon(LucideIcons.sparkles),
activeIcon: Icon(LucideIcons.sparkles),
label: 'Zikir',
),
];
final fullItems = const [
BottomNavigationBarItem(
icon: Icon(LucideIcons.home),
activeIcon: Icon(LucideIcons.home),
label: 'Beranda',
),
BottomNavigationBarItem(
icon: Icon(LucideIcons.calendar),
activeIcon: Icon(LucideIcons.calendar),
label: 'Jadwal',
),
BottomNavigationBarItem(
icon: Icon(LucideIcons.listChecks),
activeIcon: Icon(LucideIcons.listChecks),
label: 'Ibadah',
),
BottomNavigationBarItem(
icon: Icon(LucideIcons.barChart3),
activeIcon: Icon(LucideIcons.barChart3),
label: 'Laporan',
),
BottomNavigationBarItem(
icon: Icon(LucideIcons.wand2),
activeIcon: Icon(LucideIcons.wand2),
label: 'Alat',
),
];
return Container(
decoration: BoxDecoration(
color: Theme.of(context).bottomNavigationBarTheme.backgroundColor,
border: Border(
top: BorderSide(
color: Theme.of(context).dividerColor,
width: 0.5,
),
),
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.only(bottom: 8),
child: BottomNavigationBar(
currentIndex: currentIndex,
onTap: onTap,
items: isSimpleMode ? simpleItems : fullItems,
),
),
),
);
},
);
}
}

View File

@@ -0,0 +1,69 @@
import 'package:flutter/material.dart';
import '../../app/theme/app_colors.dart';
class ToolCard extends StatelessWidget {
final IconData icon;
final String title;
final Color color;
final bool isDark;
final VoidCallback onTap;
const ToolCard({
super.key,
required this.icon,
required this.title,
required this.color,
required this.isDark,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
height: 140,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isDark ? AppColors.surfaceDark : AppColors.surfaceLight,
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: isDark
? color.withValues(alpha: 0.15)
: AppColors.cream,
),
boxShadow: [
BoxShadow(
color: color.withValues(alpha: 0.08),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: color.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(12),
),
child: Icon(icon, color: color, size: 24),
),
Text(
title,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
height: 1.3,
),
),
],
),
),
);
}
}