added guardian letters with chat and multiple answer functionalities
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../../api/marianumconnect/queries/get_capabilities/guardian_child.dart';
|
||||
import '../../../push/notification_permission_prompt.dart';
|
||||
import '../../../routing/app_routes.dart';
|
||||
import '../../../state/app/infrastructure/loadable_state/view/loadable_state_consumer.dart';
|
||||
import '../../../state/app/modules/capabilities/bloc/capabilities_cubit.dart';
|
||||
import '../../../state/app/modules/parent_letters/bloc/parent_letters_bloc.dart';
|
||||
import '../../../state/app/modules/parent_letters/bloc/parent_letters_state.dart';
|
||||
import '../../../state/app/modules/parent_letters/parent_letters_logic.dart';
|
||||
import '../../../widget/async_action_button.dart';
|
||||
import '../../../widget/child_switcher.dart';
|
||||
import '../../../widget/placeholder_view.dart';
|
||||
import 'widgets/parent_letter_tile.dart';
|
||||
|
||||
class ParentLettersView extends StatefulWidget {
|
||||
const ParentLettersView({super.key});
|
||||
|
||||
@override
|
||||
State<ParentLettersView> createState() => _ParentLettersViewState();
|
||||
}
|
||||
|
||||
class _ParentLettersViewState extends State<ParentLettersView> {
|
||||
/// Null shows the letters of all children. Deliberately independent of the
|
||||
/// app-wide child selection: the inbox must not hide a sibling's letters.
|
||||
String? _childFilter;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
context.read<ParentLettersBloc>().refresh(silent: true);
|
||||
maybePromptParentLetterNotifications(context);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final children = context.watch<CapabilitiesCubit>().state.children;
|
||||
final filter = children.any((child) => child.id == _childFilter)
|
||||
? _childFilter
|
||||
: null;
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Elternbriefe')),
|
||||
body: Column(
|
||||
children: [
|
||||
if (children.length > 1)
|
||||
_ChildFilterBar(
|
||||
children: children,
|
||||
selected: filter,
|
||||
onSelected: (id) => setState(() => _childFilter = id),
|
||||
),
|
||||
Expanded(
|
||||
child: LoadableStateConsumer<ParentLettersBloc, ParentLettersState>(
|
||||
child: (state, loading) {
|
||||
if (children.isEmpty) return const NoChildrenPlaceholder();
|
||||
final letters = filterLettersByChild(state.letters, filter);
|
||||
if (letters.isEmpty && !state.hasMore) {
|
||||
return const PlaceholderView(
|
||||
icon: Icons.mark_email_read_outlined,
|
||||
text: 'Keine Elternbriefe vorhanden.',
|
||||
);
|
||||
}
|
||||
return ListView.separated(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemCount: letters.length + (state.hasMore ? 1 : 0),
|
||||
separatorBuilder: (_, _) => const Divider(height: 1),
|
||||
itemBuilder: (context, index) {
|
||||
if (index == letters.length) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: AsyncTextButton(
|
||||
onPressed: context
|
||||
.read<ParentLettersBloc>()
|
||||
.loadOlder,
|
||||
child: const Text('Ältere Elternbriefe laden'),
|
||||
),
|
||||
);
|
||||
}
|
||||
final letter = letters[index];
|
||||
return ParentLetterTile(
|
||||
letter: letter,
|
||||
children: children,
|
||||
onTap: () =>
|
||||
AppRoutes.openParentLetter(context, id: letter.id),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ChildFilterBar extends StatelessWidget {
|
||||
final List<GuardianChild> children;
|
||||
final String? selected;
|
||||
final ValueChanged<String?> onSelected;
|
||||
|
||||
const _ChildFilterBar({
|
||||
required this.children,
|
||||
required this.selected,
|
||||
required this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
label: const Text('Alle'),
|
||||
selected: selected == null,
|
||||
onSelected: (_) => onSelected(null),
|
||||
),
|
||||
for (final child in children)
|
||||
ChoiceChip(
|
||||
label: Text(child.firstName),
|
||||
selected: selected == child.id,
|
||||
onSelected: (_) => onSelected(child.id),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user