Skip to content

Commit 1df9ee0

Browse files
Merge pull request #26 from dabblingwithcode/staging
Staging
2 parents e95077f + bc2c6ad commit 1df9ee0

19 files changed

Lines changed: 647 additions & 419 deletions

File tree

school_data_hub_client/lib/src/protocol/client.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,12 +2431,12 @@ class EndpointPupilWorkbooks extends _i1.EndpointRef {
24312431
@override
24322432
String get name => 'pupilWorkbooks';
24332433

2434-
_i2.Future<_i53.PupilWorkbook> postPupilWorkbook(
2434+
_i2.Future<_i53.PupilWorkbook?> postPupilWorkbook(
24352435
int isbn,
24362436
int pupilId,
24372437
String createdBy,
24382438
) =>
2439-
caller.callServerEndpoint<_i53.PupilWorkbook>(
2439+
caller.callServerEndpoint<_i53.PupilWorkbook?>(
24402440
'pupilWorkbooks',
24412441
'postPupilWorkbook',
24422442
{

school_data_hub_flutter/lib/common/widgets/custom_expansion_tile/custom_expansion_tile.dart

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ class CustomExpansionTileController {
132132
/// populated by instances of your new inner widgets, and then in
133133
/// these inner widgets you would use [CustomExpansionTileController.of].
134134
static CustomExpansionTileController of(BuildContext context) {
135-
final _ExpansionTileState? result =
136-
context.findAncestorStateOfType<_ExpansionTileState>();
135+
final _ExpansionTileState? result = context
136+
.findAncestorStateOfType<_ExpansionTileState>();
137137
if (result != null) {
138138
return result._tileController;
139139
}
@@ -251,10 +251,10 @@ class CustomExpansionTile extends StatefulWidget {
251251
this.controlAffinity,
252252
this.controller,
253253
}) : assert(
254-
expandedCrossAxisAlignment != CrossAxisAlignment.baseline,
255-
'CrossAxisAlignment.baseline is not supported since the expanded children '
256-
'are aligned in a column, not a row. Try to use another constant.',
257-
);
254+
expandedCrossAxisAlignment != CrossAxisAlignment.baseline,
255+
'CrossAxisAlignment.baseline is not supported since the expanded children '
256+
'are aligned in a column, not a row. Try to use another constant.',
257+
);
258258

259259
/// A widget to display before the title.
260260
///
@@ -498,10 +498,12 @@ class CustomExpansionTile extends StatefulWidget {
498498

499499
class _ExpansionTileState extends State<CustomExpansionTile>
500500
with SingleTickerProviderStateMixin {
501-
static final Animatable<double> _easeOutTween =
502-
CurveTween(curve: Curves.easeOut);
503-
static final Animatable<double> _easeInTween =
504-
CurveTween(curve: Curves.easeIn);
501+
static final Animatable<double> _easeOutTween = CurveTween(
502+
curve: Curves.easeOut,
503+
);
504+
static final Animatable<double> _easeInTween = CurveTween(
505+
curve: Curves.easeIn,
506+
);
505507
// static final Animatable<double> _halfTween =
506508
// Tween<double>(begin: 0.0, end: 0.5);
507509

@@ -528,14 +530,18 @@ class _ExpansionTileState extends State<CustomExpansionTile>
528530
_heightFactor = _animationController.drive(_easeInTween);
529531
//_iconTurns = _animationController.drive(_halfTween.chain(_easeInTween));
530532
_border = _animationController.drive(_borderTween.chain(_easeOutTween));
531-
_headerColor =
532-
_animationController.drive(_headerColorTween.chain(_easeInTween));
533-
_iconColor =
534-
_animationController.drive(_iconColorTween.chain(_easeInTween));
535-
_backgroundColor =
536-
_animationController.drive(_backgroundColorTween.chain(_easeOutTween));
537-
538-
_isExpanded = PageStorage.maybeOf(context)?.readState(context) as bool? ??
533+
_headerColor = _animationController.drive(
534+
_headerColorTween.chain(_easeInTween),
535+
);
536+
_iconColor = _animationController.drive(
537+
_iconColorTween.chain(_easeInTween),
538+
);
539+
_backgroundColor = _animationController.drive(
540+
_backgroundColorTween.chain(_easeOutTween),
541+
);
542+
543+
_isExpanded =
544+
PageStorage.maybeOf(context)?.readState(context) as bool? ??
539545
widget.initiallyExpanded;
540546
if (_isExpanded) {
541547
_animationController.value = 1.0;
@@ -631,9 +637,11 @@ class _ExpansionTileState extends State<CustomExpansionTile>
631637
// }
632638

633639
Widget _buildChildren(BuildContext context, Widget? child) {
634-
final ExpansionTileThemeData expansionTileTheme =
635-
ExpansionTileTheme.of(context);
636-
final ShapeBorder expansionTileBorder = _border.value ??
640+
final ExpansionTileThemeData expansionTileTheme = ExpansionTileTheme.of(
641+
context,
642+
);
643+
final ShapeBorder expansionTileBorder =
644+
_border.value ??
637645
const Border(
638646
top: BorderSide(color: Colors.transparent),
639647
bottom: BorderSide(color: Colors.transparent),
@@ -644,7 +652,8 @@ class _ExpansionTileState extends State<CustomExpansionTile>
644652
return Container(
645653
clipBehavior: clipBehavior,
646654
decoration: ShapeDecoration(
647-
color: _backgroundColor.value ??
655+
color:
656+
_backgroundColor.value ??
648657
expansionTileTheme.backgroundColor ??
649658
Colors.transparent,
650659
shape: expansionTileBorder,
@@ -653,22 +662,23 @@ class _ExpansionTileState extends State<CustomExpansionTile>
653662
mainAxisSize: MainAxisSize.min,
654663
children: <Widget>[
655664
ListTileTheme.merge(
656-
iconColor: _iconColor.value ?? expansionTileTheme.iconColor,
657-
textColor: _headerColor.value,
658-
child: const SizedBox.shrink()
659-
// ListTile(
660-
// onTap: _handleTap,
661-
// contentPadding:
662-
// widget.tilePadding ?? expansionTileTheme.tilePadding,
663-
// leading: widget.leading ?? _buildLeadingIcon(context),
664-
// title: widget.title,
665-
// subtitle: widget.subtitle,
666-
// trailing: widget.trailing ?? _buildTrailingIcon(context),
667-
// ),
668-
),
665+
iconColor: _iconColor.value ?? expansionTileTheme.iconColor,
666+
textColor: _headerColor.value,
667+
child: const SizedBox.shrink(),
668+
// ListTile(
669+
// onTap: _handleTap,
670+
// contentPadding:
671+
// widget.tilePadding ?? expansionTileTheme.tilePadding,
672+
// leading: widget.leading ?? _buildLeadingIcon(context),
673+
// title: widget.title,
674+
// subtitle: widget.subtitle,
675+
// trailing: widget.trailing ?? _buildTrailingIcon(context),
676+
// ),
677+
),
669678
ClipRect(
670679
child: Align(
671-
alignment: widget.expandedAlignment ??
680+
alignment:
681+
widget.expandedAlignment ??
672682
expansionTileTheme.expandedAlignment ??
673683
Alignment.center,
674684
heightFactor: _heightFactor.value,
@@ -683,49 +693,58 @@ class _ExpansionTileState extends State<CustomExpansionTile>
683693
@override
684694
void didChangeDependencies() {
685695
final ThemeData theme = Theme.of(context);
686-
final ExpansionTileThemeData expansionTileTheme =
687-
ExpansionTileTheme.of(context);
696+
final ExpansionTileThemeData expansionTileTheme = ExpansionTileTheme.of(
697+
context,
698+
);
688699
final ExpansionTileThemeData defaults = theme.useMaterial3
689700
? _ExpansionTileDefaultsM3(context)
690701
: _ExpansionTileDefaultsM2(context);
691702
_borderTween
692-
..begin = widget.collapsedShape ??
703+
..begin =
704+
widget.collapsedShape ??
693705
expansionTileTheme.collapsedShape ??
694706
const Border(
695707
top: BorderSide(color: Colors.transparent),
696708
bottom: BorderSide(color: Colors.transparent),
697709
)
698-
..end = widget.shape ??
710+
..end =
711+
widget.shape ??
699712
expansionTileTheme.collapsedShape ??
700713
Border(
701714
top: BorderSide(color: theme.dividerColor),
702715
bottom: BorderSide(color: theme.dividerColor),
703716
);
704717
_headerColorTween
705-
..begin = widget.collapsedTextColor ??
718+
..begin =
719+
widget.collapsedTextColor ??
706720
expansionTileTheme.collapsedTextColor ??
707721
defaults.collapsedTextColor
708-
..end = widget.textColor ??
722+
..end =
723+
widget.textColor ??
709724
expansionTileTheme.textColor ??
710725
defaults.textColor;
711726
_iconColorTween
712-
..begin = widget.collapsedIconColor ??
727+
..begin =
728+
widget.collapsedIconColor ??
713729
expansionTileTheme.collapsedIconColor ??
714730
defaults.collapsedIconColor
715-
..end = widget.iconColor ??
731+
..end =
732+
widget.iconColor ??
716733
expansionTileTheme.iconColor ??
717734
defaults.iconColor;
718735
_backgroundColorTween
719-
..begin = widget.collapsedBackgroundColor ??
736+
..begin =
737+
widget.collapsedBackgroundColor ??
720738
expansionTileTheme.collapsedBackgroundColor
721739
..end = widget.backgroundColor ?? expansionTileTheme.backgroundColor;
722740
super.didChangeDependencies();
723741
}
724742

725743
@override
726744
Widget build(BuildContext context) {
727-
final ExpansionTileThemeData expansionTileTheme =
728-
ExpansionTileTheme.of(context);
745+
final ExpansionTileThemeData expansionTileTheme = ExpansionTileTheme.of(
746+
context,
747+
);
729748
final bool closed = !_isExpanded && _animationController.isDismissed;
730749
final bool shouldRemoveChildren = closed && !widget.maintainState;
731750

@@ -734,7 +753,8 @@ class _ExpansionTileState extends State<CustomExpansionTile>
734753
child: TickerMode(
735754
enabled: !closed,
736755
child: Padding(
737-
padding: widget.childrenPadding ??
756+
padding:
757+
widget.childrenPadding ??
738758
expansionTileTheme.childrenPadding ??
739759
EdgeInsets.zero,
740760
child: Column(

school_data_hub_flutter/lib/core/init/init_on_user_auth.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import 'package:school_data_hub_flutter/features/school_lists/domain/school_list
2929
import 'package:school_data_hub_flutter/features/timetable/data/timetable_api_service.dart';
3030
import 'package:school_data_hub_flutter/features/timetable/timetable.dart';
3131
import 'package:school_data_hub_flutter/features/user/domain/user_manager.dart';
32+
import 'package:school_data_hub_flutter/features/workbooks/domain/pupil_workbook_manager.dart';
3233
import 'package:school_data_hub_flutter/features/workbooks/domain/workbook_manager.dart';
3334
import 'package:watch_it/watch_it.dart';
3435

@@ -180,6 +181,21 @@ class InitOnUserAuth {
180181
},
181182
);
182183

184+
di.registerSingletonAsync<PupilWorkbookManager>(
185+
() async {
186+
final pupilWorkbookManager = PupilWorkbookManager();
187+
await pupilWorkbookManager.init();
188+
_log.info('[PupilWorkbookManager] initialized ✅️');
189+
return pupilWorkbookManager;
190+
},
191+
dispose: (instance) {
192+
_log.info('[PupilWorkbookManager] disposed 🚮');
193+
instance.dispose();
194+
return;
195+
},
196+
dependsOn: [HubSessionManager, PupilProxyManager],
197+
);
198+
183199
di.registerSingletonAsync<CompetenceManager>(
184200
() async {
185201
final competenceManager = CompetenceManager();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'package:school_data_hub_client/school_data_hub_client.dart';
2+
import 'package:school_data_hub_flutter/core/client/client_helper.dart';
3+
import 'package:school_data_hub_flutter/core/session/hub_session_manager.dart';
4+
import 'package:watch_it/watch_it.dart';
5+
6+
class CompetenceGoalApiService {
7+
// Private constructor
8+
CompetenceGoalApiService._internal();
9+
// Singleton instance
10+
static final CompetenceGoalApiService _instance =
11+
CompetenceGoalApiService._internal();
12+
// Factory constructor to return the singleton instance
13+
factory CompetenceGoalApiService() {
14+
return _instance;
15+
}
16+
Client get _client => di<Client>();
17+
18+
HubSessionManager get _hubSessionManager => di<HubSessionManager>();
19+
// - post a competence goal
20+
Future<PupilData?> postCompetenceGoal({
21+
required int pupilId,
22+
required int competenceId,
23+
required String description,
24+
required List<String> strategies,
25+
}) async {
26+
final response = ClientHelper.apiCall(
27+
call: () => _client.competenceGoal.postCompetenceGoal(
28+
competenceId: competenceId,
29+
pupilId: pupilId,
30+
description: description,
31+
strategies: strategies,
32+
createdBy: _hubSessionManager.userName!,
33+
),
34+
);
35+
return response;
36+
}
37+
}

school_data_hub_flutter/lib/features/learning/domain/competence_manager.dart

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:school_data_hub_flutter/common/services/notification_service.dar
1010
import 'package:school_data_hub_flutter/core/env/env_manager.dart';
1111
import 'package:school_data_hub_flutter/core/session/hub_session_manager.dart';
1212
import 'package:school_data_hub_flutter/features/learning/data/competence_check_api_service.dart';
13+
import 'package:school_data_hub_flutter/features/learning/data/competence_goal_api_service.dart';
1314
import 'package:school_data_hub_flutter/features/learning/domain/competence_helper.dart';
1415
import 'package:school_data_hub_flutter/features/learning/domain/filters/competence_filter_manager.dart';
1516
import 'package:school_data_hub_flutter/features/pupil/domain/pupil_proxy_manager.dart';
@@ -23,7 +24,7 @@ class CompetenceManager {
2324
final _notificationService = di<NotificationService>();
2425

2526
final _competenceCheckApiService = CompetenceCheckApiService();
26-
27+
final _competenceGoalApiService = CompetenceGoalApiService();
2728
final _competences = ValueNotifier<List<Competence>>([]);
2829
ValueListenable<List<Competence>> get competences => _competences;
2930

@@ -289,12 +290,20 @@ class CompetenceManager {
289290
required List<String> strategies,
290291
}) async {
291292
// TODO: Implement backend call when available
292-
// Currently there is no endpoint for posting a competence goal
293-
// We would need something like _client.competence.postCompetenceGoal(...)
293+
final pupilData = await _competenceGoalApiService.postCompetenceGoal(
294+
pupilId: pupilId,
295+
competenceId: competenceId,
296+
description: description,
297+
strategies: strategies,
298+
);
299+
if (pupilData == null) {
300+
return;
301+
}
302+
di<PupilProxyManager>().updatePupilProxyWithPupilData(pupilData);
294303

295304
_notificationService.showSnackBar(
296-
NotificationType.warning,
297-
'Speichern nicht möglich: Backend-Endpunkt fehlt (CompetenceGoal)',
305+
NotificationType.success,
306+
'Lernziel erstellt',
298307
);
299308

300309
return;

0 commit comments

Comments
 (0)