feat: complete Simple Mode contextual routing and navigation state synchronization
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import '../../../app/theme/app_colors.dart';
|
||||
import '../../../core/providers/theme_provider.dart';
|
||||
import '../../../core/widgets/ios_toggle.dart';
|
||||
@@ -136,7 +138,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => _showEditProfileDialog(context),
|
||||
icon: Icon(Icons.edit,
|
||||
icon: Icon(LucideIcons.pencil,
|
||||
size: 20, color: AppColors.primary),
|
||||
),
|
||||
],
|
||||
@@ -149,7 +151,22 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
const SizedBox(height: 12),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.dark_mode,
|
||||
icon: LucideIcons.layoutDashboard,
|
||||
iconColor: const Color(0xFF0984E3),
|
||||
title: 'Mode Aplikasi',
|
||||
subtitle: _settings.simpleMode ? 'Simpel — Jadwal & Al-Quran' : 'Lengkap — Dengan Checklist & Poin',
|
||||
trailing: IosToggle(
|
||||
value: !_settings.simpleMode,
|
||||
onChanged: (v) {
|
||||
_settings.simpleMode = !v;
|
||||
_saveSettings();
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: LucideIcons.moon,
|
||||
iconColor: const Color(0xFF6C5CE7),
|
||||
title: 'Mode Gelap',
|
||||
trailing: IosToggle(
|
||||
@@ -160,7 +177,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
const SizedBox(height: 10),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.notifications,
|
||||
icon: LucideIcons.bell,
|
||||
iconColor: const Color(0xFFE17055),
|
||||
title: 'Notifikasi',
|
||||
trailing: IosToggle(
|
||||
@@ -170,32 +187,32 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// ── CHECKLIST IBADAH ──
|
||||
// ── CHECKLIST IBADAH (always visible, even in Simple Mode per user request) ──
|
||||
_sectionLabel('CHECKLIST IBADAH'),
|
||||
const SizedBox(height: 12),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.mosque_outlined,
|
||||
icon: LucideIcons.building,
|
||||
iconColor: Colors.teal,
|
||||
title: 'Tingkat Sholat Rawatib',
|
||||
subtitle: _settings.rawatibLevel == 0 ? 'Mati' : (_settings.rawatibLevel == 1 ? 'Muakkad Saja' : 'Lengkap (Semua)'),
|
||||
trailing: const Icon(Icons.chevron_right, size: 20),
|
||||
trailing: const Icon(LucideIcons.chevronRight, size: 20),
|
||||
onTap: () => _showRawatibDialog(context),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.menu_book,
|
||||
icon: LucideIcons.bookOpen,
|
||||
iconColor: Colors.amber,
|
||||
title: 'Target Tilawah',
|
||||
subtitle: '${_settings.tilawahTargetValue} ${_settings.tilawahTargetUnit}',
|
||||
trailing: const Icon(Icons.chevron_right, size: 20),
|
||||
trailing: const Icon(LucideIcons.chevronRight, size: 20),
|
||||
onTap: () => _showTilawahDialog(context),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.sync,
|
||||
icon: LucideIcons.refreshCw,
|
||||
iconColor: Colors.blue,
|
||||
title: 'Auto-Sync Tilawah',
|
||||
subtitle: 'Catat otomatis dari menu Al-Quran',
|
||||
@@ -218,11 +235,11 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
const SizedBox(height: 10),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.library_add_check,
|
||||
icon: LucideIcons.listChecks,
|
||||
iconColor: Colors.indigo,
|
||||
title: 'Amalan Tambahan',
|
||||
subtitle: 'Dzikir & Puasa Sunnah',
|
||||
trailing: const Icon(Icons.chevron_right, size: 20),
|
||||
trailing: const Icon(LucideIcons.chevronRight, size: 20),
|
||||
onTap: () => _showAmalanDialog(context),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
@@ -232,31 +249,31 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
const SizedBox(height: 12),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.mosque,
|
||||
icon: LucideIcons.building,
|
||||
iconColor: AppColors.primary,
|
||||
title: 'Metode Perhitungan',
|
||||
subtitle: 'Kemenag RI',
|
||||
trailing: const Icon(Icons.chevron_right, size: 20),
|
||||
trailing: const Icon(LucideIcons.chevronRight, size: 20),
|
||||
onTap: () => _showMethodDialog(context),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.location_on,
|
||||
icon: LucideIcons.mapPin,
|
||||
iconColor: const Color(0xFF00B894),
|
||||
title: 'Lokasi',
|
||||
subtitle: _displayCityName,
|
||||
trailing: const Icon(Icons.chevron_right, size: 20),
|
||||
trailing: const Icon(LucideIcons.chevronRight, size: 20),
|
||||
onTap: () => _showLocationDialog(context),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.timer,
|
||||
icon: LucideIcons.timer,
|
||||
iconColor: const Color(0xFFFDAA5E),
|
||||
title: 'Waktu Iqamah',
|
||||
subtitle: 'Atur per waktu sholat',
|
||||
trailing: const Icon(Icons.chevron_right, size: 20),
|
||||
trailing: const Icon(LucideIcons.chevronRight, size: 20),
|
||||
onTap: () => _showIqamahDialog(context),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
@@ -266,7 +283,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
const SizedBox(height: 12),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.text_fields,
|
||||
icon: LucideIcons.type,
|
||||
iconColor: const Color(0xFF636E72),
|
||||
title: 'Ukuran Font Arab',
|
||||
subtitle: '${_settings.arabicFontSize.round()}pt',
|
||||
@@ -292,7 +309,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
const SizedBox(height: 12),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.info_outline,
|
||||
icon: LucideIcons.info,
|
||||
iconColor: AppColors.sage,
|
||||
title: 'Versi Aplikasi',
|
||||
subtitle: '1.0.0',
|
||||
@@ -300,10 +317,10 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
const SizedBox(height: 10),
|
||||
_settingRow(
|
||||
isDark,
|
||||
icon: Icons.favorite_outline,
|
||||
icon: LucideIcons.heart,
|
||||
iconColor: Colors.red,
|
||||
title: 'Beri Nilai Kami',
|
||||
trailing: const Icon(Icons.chevron_right, size: 20),
|
||||
trailing: const Icon(LucideIcons.chevronRight, size: 20),
|
||||
onTap: () {},
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
@@ -324,7 +341,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
child: const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.logout, color: Colors.red, size: 20),
|
||||
Icon(LucideIcons.logOut, color: Colors.red, size: 20),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'Hapus Semua Data',
|
||||
@@ -447,6 +464,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
final searchCtrl = TextEditingController();
|
||||
bool isSearching = false;
|
||||
List<Map<String, dynamic>> results = [];
|
||||
Timer? debounce;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
@@ -466,7 +484,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
hintText: 'Cth: Jakarta',
|
||||
border: const OutlineInputBorder(),
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(Icons.search),
|
||||
icon: const Icon(LucideIcons.search),
|
||||
onPressed: () async {
|
||||
if (searchCtrl.text.trim().isEmpty) return;
|
||||
setDialogState(() => isSearching = true);
|
||||
@@ -479,15 +497,45 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
},
|
||||
),
|
||||
),
|
||||
onChanged: (val) {
|
||||
if (val.trim().length < 3) return;
|
||||
|
||||
if (debounce?.isActive ?? false) debounce!.cancel();
|
||||
debounce = Timer(const Duration(milliseconds: 500), () async {
|
||||
if (!mounted) return;
|
||||
setDialogState(() => isSearching = true);
|
||||
|
||||
try {
|
||||
final res = await MyQuranSholatService.instance.searchCity(val.trim());
|
||||
if (mounted) {
|
||||
setDialogState(() {
|
||||
results = res;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Error searching city: $e');
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setDialogState(() {
|
||||
isSearching = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
onSubmitted: (val) async {
|
||||
if (val.trim().isEmpty) return;
|
||||
if (debounce?.isActive ?? false) debounce!.cancel();
|
||||
setDialogState(() => isSearching = true);
|
||||
final res = await MyQuranSholatService.instance
|
||||
.searchCity(val.trim());
|
||||
setDialogState(() {
|
||||
results = res;
|
||||
isSearching = false;
|
||||
});
|
||||
|
||||
if (mounted) {
|
||||
setDialogState(() {
|
||||
results = res;
|
||||
isSearching = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -670,7 +718,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
const Text('Sholat Rawatib', style: TextStyle(fontSize: 18)),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.info_outline, color: AppColors.primary),
|
||||
icon: const Icon(LucideIcons.info, color: AppColors.primary),
|
||||
onPressed: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
|
||||
Reference in New Issue
Block a user