feat(07-02): build SortDropdown widget and integrate into HomeScreen and TaskListScreen
- Create SortDropdown ConsumerWidget using PopupMenuButton<TaskSortOption> - Displays current sort label with sort icon in AppBar actions - Check mark shown on active option via Opacity widget - Add Scaffold with AppBar (title: Übersicht, actions: SortDropdown) to HomeScreen - Add SortDropdown before edit/delete IconButtons in TaskListScreen AppBar
This commit is contained in:
@@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:household_keeper/features/home/presentation/calendar_day_list.dart';
|
||||
import 'package:household_keeper/features/home/presentation/calendar_providers.dart';
|
||||
import 'package:household_keeper/features/home/presentation/calendar_strip.dart';
|
||||
import 'package:household_keeper/features/tasks/presentation/sort_dropdown.dart';
|
||||
import 'package:household_keeper/l10n/app_localizations.dart';
|
||||
|
||||
/// The app's primary screen: a horizontal calendar strip at the top with a
|
||||
@@ -30,40 +31,46 @@ class _HomeScreenState extends ConsumerState<HomeScreen> {
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
CalendarStrip(
|
||||
controller: _stripController,
|
||||
onTodayVisibilityChanged: (visible) {
|
||||
setState(() => _showTodayButton = !visible);
|
||||
},
|
||||
),
|
||||
const Expanded(child: CalendarDayList()),
|
||||
],
|
||||
),
|
||||
if (_showTodayButton)
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
final now = DateTime.now();
|
||||
final today = DateTime(now.year, now.month, now.day);
|
||||
ref
|
||||
.read(selectedDateProvider.notifier)
|
||||
.selectDate(today);
|
||||
_stripController.scrollToToday();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(l10n.tabHome),
|
||||
actions: const [SortDropdown()],
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
CalendarStrip(
|
||||
controller: _stripController,
|
||||
onTodayVisibilityChanged: (visible) {
|
||||
setState(() => _showTodayButton = !visible);
|
||||
},
|
||||
icon: const Icon(Icons.today),
|
||||
label: Text(l10n.calendarTodayButton),
|
||||
),
|
||||
const Expanded(child: CalendarDayList()),
|
||||
],
|
||||
),
|
||||
if (_showTodayButton)
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
final now = DateTime.now();
|
||||
final today = DateTime(now.year, now.month, now.day);
|
||||
ref
|
||||
.read(selectedDateProvider.notifier)
|
||||
.selectDate(today);
|
||||
_stripController.scrollToToday();
|
||||
},
|
||||
icon: const Icon(Icons.today),
|
||||
label: Text(l10n.calendarTodayButton),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
71
lib/features/tasks/presentation/sort_dropdown.dart
Normal file
71
lib/features/tasks/presentation/sort_dropdown.dart
Normal file
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:household_keeper/features/tasks/domain/task_sort_option.dart';
|
||||
import 'package:household_keeper/features/tasks/presentation/sort_preference_notifier.dart';
|
||||
import 'package:household_keeper/l10n/app_localizations.dart';
|
||||
|
||||
/// A reusable sort dropdown widget for use in AppBar actions.
|
||||
///
|
||||
/// Displays the current sort option as a labelled button with a sort icon.
|
||||
/// Tapping opens a popup menu with three options: A–Z, Intervall, Aufwand.
|
||||
/// The active option is indicated with a visible check mark.
|
||||
///
|
||||
/// Reads sort state from [sortPreferenceProvider] and writes via
|
||||
/// [SortPreferenceNotifier.setSortOption].
|
||||
class SortDropdown extends ConsumerWidget {
|
||||
const SortDropdown({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final current = ref.watch(sortPreferenceProvider);
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return PopupMenuButton<TaskSortOption>(
|
||||
onSelected: (value) =>
|
||||
ref.read(sortPreferenceProvider.notifier).setSortOption(value),
|
||||
itemBuilder: (context) => TaskSortOption.values.map((option) {
|
||||
final isSelected = option == current;
|
||||
return PopupMenuItem<TaskSortOption>(
|
||||
value: option,
|
||||
child: Row(
|
||||
children: [
|
||||
Opacity(
|
||||
opacity: isSelected ? 1.0 : 0.0,
|
||||
child: const Icon(Icons.check, size: 18),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(_label(option, l10n)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.sort),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
_label(current, l10n),
|
||||
style: theme.textTheme.labelLarge,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _label(TaskSortOption option, AppLocalizations l10n) {
|
||||
switch (option) {
|
||||
case TaskSortOption.alphabetical:
|
||||
return l10n.sortAlphabetical;
|
||||
case TaskSortOption.interval:
|
||||
return l10n.sortInterval;
|
||||
case TaskSortOption.effort:
|
||||
return l10n.sortEffort;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:household_keeper/core/database/database.dart';
|
||||
import 'package:household_keeper/core/providers/database_provider.dart';
|
||||
import 'package:household_keeper/features/tasks/presentation/sort_dropdown.dart';
|
||||
import 'package:household_keeper/features/tasks/presentation/task_providers.dart';
|
||||
import 'package:household_keeper/features/tasks/presentation/task_row.dart';
|
||||
import 'package:household_keeper/l10n/app_localizations.dart';
|
||||
@@ -27,6 +28,7 @@ class TaskListScreen extends ConsumerWidget {
|
||||
appBar: AppBar(
|
||||
title: _RoomTitle(roomId: roomId),
|
||||
actions: [
|
||||
const SortDropdown(),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit),
|
||||
onPressed: () => context.go('/rooms/$roomId/edit'),
|
||||
|
||||
Reference in New Issue
Block a user