Compare commits
	
		
			7 Commits
		
	
	
		
			develop
			...
			feature-hi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5d264f7651 | |||
| a6f7c09671 | |||
| eaf6d9f547 | |||
| 5b34afd6cb | |||
| 25d901d093 | |||
| 6237a2e9cf | |||
| c4f5be2205 | 
@@ -1,9 +1,9 @@
 | 
				
			|||||||
import 'dart:convert';
 | 
					import 'dart:convert';
 | 
				
			||||||
 | 
					import 'dart:developer';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:localstore/localstore.dart';
 | 
					import 'package:localstore/localstore.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'apiResponse.dart';
 | 
					import 'apiResponse.dart';
 | 
				
			||||||
import 'webuntis/webuntisError.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class RequestCache<T extends ApiResponse?> {
 | 
					abstract class RequestCache<T extends ApiResponse?> {
 | 
				
			||||||
  static const int cacheNothing = 0;
 | 
					  static const int cacheNothing = 0;
 | 
				
			||||||
@@ -30,16 +30,18 @@ abstract class RequestCache<T extends ApiResponse?> {
 | 
				
			|||||||
      if(renew == null || !renew!) return;
 | 
					      if(renew == null || !renew!) return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    T? newValue;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      T newValue = await onLoad();
 | 
					      newValue = await onLoad();
 | 
				
			||||||
      onUpdate(newValue);
 | 
					      onUpdate(newValue as T);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Localstore.instance.collection(file).doc(document).set({
 | 
					      Localstore.instance.collection(file).doc(document).set({
 | 
				
			||||||
        'json': jsonEncode(newValue),
 | 
					        'json': jsonEncode(newValue),
 | 
				
			||||||
        'lastupdate': DateTime.now().millisecondsSinceEpoch
 | 
					        'lastupdate': DateTime.now().millisecondsSinceEpoch
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    } on WebuntisError catch(e) {
 | 
					    } catch(e) {
 | 
				
			||||||
      onError(e);
 | 
					      log("Error while fetching/ parsing. Raw server response: ${newValue?.rawResponse.body ?? "no response"}");
 | 
				
			||||||
 | 
					      onError(Exception(e.toString()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,7 @@ import 'storage/base/settingsProvider.dart';
 | 
				
			|||||||
import 'theming/darkAppTheme.dart';
 | 
					import 'theming/darkAppTheme.dart';
 | 
				
			||||||
import 'theming/lightAppTheme.dart';
 | 
					import 'theming/lightAppTheme.dart';
 | 
				
			||||||
import 'view/login/login.dart';
 | 
					import 'view/login/login.dart';
 | 
				
			||||||
 | 
					import 'view/pages/more/abiturCalculator/models/abiturCalculatorModel.dart';
 | 
				
			||||||
import 'widget/placeholderView.dart';
 | 
					import 'widget/placeholderView.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Future<void> main() async {
 | 
					Future<void> main() async {
 | 
				
			||||||
@@ -68,6 +69,8 @@ Future<void> main() async {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          ChangeNotifierProvider(create: (context) => MessageProps()),
 | 
					          ChangeNotifierProvider(create: (context) => MessageProps()),
 | 
				
			||||||
          ChangeNotifierProvider(create: (context) => HolidaysProps()),
 | 
					          ChangeNotifierProvider(create: (context) => HolidaysProps()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          ChangeNotifierProvider(create: (context) => AbiturCalculatorModel()),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        child: const Main(),
 | 
					        child: const Main(),
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'models/subject.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					abstract class AbiturCalculatorStep extends Step {
 | 
				
			||||||
 | 
					  const AbiturCalculatorStep({required super.title, required super.content});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool canGoNextStep(SubjectCollection subjects);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import '../../../../widget/confirmDialog.dart';
 | 
				
			||||||
 | 
					import 'models/abiturCalculatorModel.dart';
 | 
				
			||||||
 | 
					import 'models/subject.dart';
 | 
				
			||||||
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AbiturCalculatorView extends StatelessWidget {
 | 
				
			||||||
 | 
					  const AbiturCalculatorView({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static RichText listSubjects(List<Subject> subjects) {
 | 
				
			||||||
 | 
					    return RichText(
 | 
				
			||||||
 | 
					      textAlign: TextAlign.center,
 | 
				
			||||||
 | 
					      text: TextSpan(
 | 
				
			||||||
 | 
					        children: subjects.map((subject) {
 | 
				
			||||||
 | 
					          return List<InlineSpan>.from([
 | 
				
			||||||
 | 
					            WidgetSpan(child: Icon(subject.icon, size: 15)),
 | 
				
			||||||
 | 
					            const WidgetSpan(child: SizedBox(width: 3)),
 | 
				
			||||||
 | 
					            TextSpan(text: subject.displayName),
 | 
				
			||||||
 | 
					            if(subjects.last != subject) const WidgetSpan(child: SizedBox(width: 10)),
 | 
				
			||||||
 | 
					          ]);
 | 
				
			||||||
 | 
					        }).expand((e) => e).toList(),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Consumer<AbiturCalculatorModel>(builder: (context, state, child) {
 | 
				
			||||||
 | 
					      return Scaffold(
 | 
				
			||||||
 | 
					          appBar: AppBar(
 | 
				
			||||||
 | 
					            title: const Text('Abitur Notenrechner'),
 | 
				
			||||||
 | 
					            actions: [
 | 
				
			||||||
 | 
					              IconButton(
 | 
				
			||||||
 | 
					                onPressed: () => ConfirmDialog(
 | 
				
			||||||
 | 
					                  title: 'Zurücksetzen',
 | 
				
			||||||
 | 
					                  content: 'Alle Felder werden zurückgesetzt',
 | 
				
			||||||
 | 
					                  confirmButton: 'Löschen',
 | 
				
			||||||
 | 
					                  onConfirm: state.reset,
 | 
				
			||||||
 | 
					                ).asDialog(context),
 | 
				
			||||||
 | 
					                icon: const Icon(Icons.delete_outline_outlined),
 | 
				
			||||||
 | 
					              )
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          body: Stepper(
 | 
				
			||||||
 | 
					            type: StepperType.vertical,
 | 
				
			||||||
 | 
					            steps: state.getSteps,
 | 
				
			||||||
 | 
					            currentStep: state.getCurrentStepIndex,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            onStepContinue: () => state.increaseStep(),
 | 
				
			||||||
 | 
					            onStepCancel: () => state.decreaseStep(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            stepIconBuilder: (stepIndex, stepState) => _stepIconBuilder(context, stepIndex, stepState),
 | 
				
			||||||
 | 
					            controlsBuilder: _controlsBuilder,
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _stepIconBuilder(BuildContext context, int stepIndex, StepState stepState) {
 | 
				
			||||||
 | 
					    return Consumer<AbiturCalculatorModel>(builder: (context, state, child) {
 | 
				
			||||||
 | 
					      return Container(
 | 
				
			||||||
 | 
					        decoration: BoxDecoration(
 | 
				
			||||||
 | 
					          borderRadius: BorderRadius.circular(20),
 | 
				
			||||||
 | 
					          color: state.getCurrentStepIndex == stepIndex
 | 
				
			||||||
 | 
					              ? Theme.of(context).primaryColor
 | 
				
			||||||
 | 
					              : Theme.of(context).colorScheme.surfaceVariant,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        child: Center(
 | 
				
			||||||
 | 
					          child: Text((++stepIndex).toString()),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _controlsBuilder(BuildContext context, ControlsDetails details) {
 | 
				
			||||||
 | 
					    return Row(
 | 
				
			||||||
 | 
					      children: [
 | 
				
			||||||
 | 
					        TextButton(
 | 
				
			||||||
 | 
					          onPressed: details.onStepCancel,
 | 
				
			||||||
 | 
					          child: const Text('Zurück'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        TextButton(
 | 
				
			||||||
 | 
					          onPressed: details.onStepContinue,
 | 
				
			||||||
 | 
					          child: const Text('Weiter'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../abiturCalculatorStep.dart';
 | 
				
			||||||
 | 
					import '../steps/resultStep.dart';
 | 
				
			||||||
 | 
					import '../steps/selectGkStep.dart';
 | 
				
			||||||
 | 
					import '../steps/selectLkStep.dart';
 | 
				
			||||||
 | 
					import '../steps/selectPfStep.dart';
 | 
				
			||||||
 | 
					import '../steps/welcomeStep.dart';
 | 
				
			||||||
 | 
					import 'subject.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AbiturCalculatorModel extends ChangeNotifier {
 | 
				
			||||||
 | 
					  static final SubjectCollection _collection = SubjectCollection([
 | 
				
			||||||
 | 
					    Subject(displayName: 'Deutsch', icon: Icons.translate_outlined, canBeLk: true, importantLk: true),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Erste Fremdsprache', icon: Icons.translate_outlined, canBeLk: true, importantLk: true),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Zweite Fremdsprache', icon: Icons.translate_outlined, canBeLk: true, importantLk: true),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Zweite Fremdsprache ab Kl. 11', icon: Icons.translate_outlined, canBeLk: false, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Kunst', icon: Icons.brush_outlined, canBeLk: true, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Musik', icon: Icons.music_note_outlined, canBeLk: true, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Darstellendes Spiel', icon: Icons.theater_comedy_outlined, canBeLk: false, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'PoWi', icon: Icons.book_outlined, canBeLk: true, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Geschichte', icon: Icons.history_outlined, canBeLk: true, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Religion', icon: Icons.church_outlined, canBeLk: true, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Erdkunde', icon: Icons.map_outlined, canBeLk: true, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Mathematik', icon: Icons.calculate_outlined, canBeLk: true, importantLk: true),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Chemie', icon: Icons.science_outlined, canBeLk: true, importantLk: true),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Physik', icon: Icons.add, canBeLk: true, importantLk: true),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Biologie', icon: Icons.add, canBeLk: true, importantLk: true),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Biochemie', icon: Icons.biotech_outlined, canBeLk: false, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Informatik', icon: Icons.code_outlined, canBeLk: true, importantLk: false),
 | 
				
			||||||
 | 
					    Subject(displayName: 'Sport', icon: Icons.sports_basketball_outlined, canBeLk: true, importantLk: false),
 | 
				
			||||||
 | 
					  ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static final List<AbiturCalculatorStep> _steps = [
 | 
				
			||||||
 | 
					    const WelcomeStep(),
 | 
				
			||||||
 | 
					    SelectLkStep(),
 | 
				
			||||||
 | 
					    SelectGkStep(),
 | 
				
			||||||
 | 
					    const SelectPfStep(),
 | 
				
			||||||
 | 
					    const ResultStep(),
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  List<AbiturCalculatorStep> get getSteps => _steps;
 | 
				
			||||||
 | 
					  AbiturCalculatorStep getCurrentStep() => _steps[getCurrentStepIndex];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static AbiturCalculatorModel get(BuildContext context) {
 | 
				
			||||||
 | 
					    return Provider.of<AbiturCalculatorModel>(context, listen: false);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int _currentStep = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SubjectCollection getSubjects({bool update = false}) {
 | 
				
			||||||
 | 
					    if(update) notifyListeners();
 | 
				
			||||||
 | 
					    return _collection;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void update() {
 | 
				
			||||||
 | 
					    notifyListeners();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int get getCurrentStepIndex => _currentStep;
 | 
				
			||||||
 | 
					  void increaseStep() {
 | 
				
			||||||
 | 
					    if(getCurrentStep().canGoNextStep(getSubjects())) _currentStep++;
 | 
				
			||||||
 | 
					    notifyListeners();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void decreaseStep() {
 | 
				
			||||||
 | 
					    if(_currentStep >= 1) _currentStep--;
 | 
				
			||||||
 | 
					    notifyListeners();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void reset() {
 | 
				
			||||||
 | 
					    _currentStep = 0;
 | 
				
			||||||
 | 
					    for (var e in _collection.collection) {
 | 
				
			||||||
 | 
					      e.reset();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    notifyListeners();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AbiturCalculatorModel() {
 | 
				
			||||||
 | 
					    reset();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								lib/view/pages/more/abiturCalculator/models/subject.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								lib/view/pages/more/abiturCalculator/models/subject.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/cupertino.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum SubjectState {
 | 
				
			||||||
 | 
					  none,
 | 
				
			||||||
 | 
					  isLk,
 | 
				
			||||||
 | 
					  isGk,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HighEduGraduationConstants {
 | 
				
			||||||
 | 
					  static const int maxLks = 2;
 | 
				
			||||||
 | 
					  static const int maxGks = 9;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SubjectCollection {
 | 
				
			||||||
 | 
					  List<Subject> collection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SubjectCollection(this.collection);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Subject {
 | 
				
			||||||
 | 
					  final String displayName;
 | 
				
			||||||
 | 
					  final IconData icon;
 | 
				
			||||||
 | 
					  final bool canBeLk;
 | 
				
			||||||
 | 
					  final bool importantLk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SubjectState _subjectState = SubjectState.none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool isLk() => _subjectState == SubjectState.isLk;
 | 
				
			||||||
 | 
					  bool isGk() => _subjectState == SubjectState.isGk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool canLk(List<Subject> other) {
 | 
				
			||||||
 | 
					    Subject? otherLk() => other.where((s) => s.isLk()).firstOrNull;
 | 
				
			||||||
 | 
					    bool hasOtherLk() => otherLk() != null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					      ((hasOtherLk() && otherLk()!.importantLk) || importantLk)
 | 
				
			||||||
 | 
					      && canBeLk
 | 
				
			||||||
 | 
					      && !isGk()
 | 
				
			||||||
 | 
					      && other.where((s) => s.isLk()).length < HighEduGraduationConstants.maxLks;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool canGk(List<Subject> other) => !isLk() && other.where((s) => s.isGk()).length < HighEduGraduationConstants.maxGks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  set unsafeSubjectSet(SubjectState newState) => _subjectState = newState;
 | 
				
			||||||
 | 
					  set unsafeLkToggle(bool isLk) {
 | 
				
			||||||
 | 
					    if(isLk) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _subjectState = isLk ? SubjectState.isLk : SubjectState.none;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  set unsafeGkToggle(bool isGk) {
 | 
				
			||||||
 | 
					    _subjectState = isGk ? SubjectState.isGk : SubjectState.none;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void reset() {
 | 
				
			||||||
 | 
					    _subjectState = SubjectState.none;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Subject({required this.displayName, required this.icon, required this.canBeLk, required this.importantLk});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								lib/view/pages/more/abiturCalculator/notes.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								lib/view/pages/more/abiturCalculator/notes.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					Standart auswahl nach LK änderung
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Deutsch
 | 
				
			||||||
 | 
					Erste Fremdsprache
 | 
				
			||||||
 | 
					Powi
 | 
				
			||||||
 | 
					Geschichte
 | 
				
			||||||
 | 
					Religion
 | 
				
			||||||
 | 
					Mathe
 | 
				
			||||||
 | 
					Sport
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Kunst
 | 
				
			||||||
 | 
					Musik
 | 
				
			||||||
 | 
					DS
 | 
				
			||||||
 | 
					Exklusiv -> Nur eins der 3 wählbar
 | 
				
			||||||
 | 
					Plichtgruppe -> EIns der drei muss gewählt sein (nur bei den Grundkursen)
 | 
				
			||||||
							
								
								
									
										16
									
								
								lib/view/pages/more/abiturCalculator/steps/resultStep.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								lib/view/pages/more/abiturCalculator/steps/resultStep.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../abiturCalculatorStep.dart';
 | 
				
			||||||
 | 
					import '../models/subject.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ResultStep extends AbiturCalculatorStep {
 | 
				
			||||||
 | 
					  const ResultStep() : super(
 | 
				
			||||||
 | 
					    title: const Text('Ergebnis'),
 | 
				
			||||||
 | 
					    content: const SizedBox.shrink(),
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool canGoNextStep(SubjectCollection subjects) {
 | 
				
			||||||
 | 
					    throw UnimplementedError();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										66
									
								
								lib/view/pages/more/abiturCalculator/steps/selectGkStep.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								lib/view/pages/more/abiturCalculator/steps/selectGkStep.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import '../../../../../widget/centeredLeading.dart';
 | 
				
			||||||
 | 
					import '../../../../../widget/providerBridge.dart';
 | 
				
			||||||
 | 
					import '../abiturCalculatorStep.dart';
 | 
				
			||||||
 | 
					import '../abiturCalculatorView.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../models/abiturCalculatorModel.dart';
 | 
				
			||||||
 | 
					import '../models/subject.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SelectGkStep extends AbiturCalculatorStep {
 | 
				
			||||||
 | 
					  SelectGkStep() : super(
 | 
				
			||||||
 | 
					    title: const Text('Grundkurse'),
 | 
				
			||||||
 | 
					    content: Builder(builder: (context) {
 | 
				
			||||||
 | 
					      var model = AbiturCalculatorModel.get(context);
 | 
				
			||||||
 | 
					      var gkSubjects = model.getSubjects().collection.where((e) => e.isGk()).toList();
 | 
				
			||||||
 | 
					      return Column(
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          AbiturCalculatorView.listSubjects(gkSubjects),
 | 
				
			||||||
 | 
					          TextButton(
 | 
				
			||||||
 | 
					            onPressed: () {
 | 
				
			||||||
 | 
					              ProviderBridge.toDialog(context, model, (context, value) {
 | 
				
			||||||
 | 
					                return AlertDialog(
 | 
				
			||||||
 | 
					                  title: const Text('Grundkurse'),
 | 
				
			||||||
 | 
					                  content: SingleChildScrollView(
 | 
				
			||||||
 | 
					                    child: Column(
 | 
				
			||||||
 | 
					                      mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
 | 
					                      children: model.getSubjects().collection.map((e) {
 | 
				
			||||||
 | 
					                        return ListTile(
 | 
				
			||||||
 | 
					                          leading: CenteredLeading(Icon(e.icon)),
 | 
				
			||||||
 | 
					                          title: Text(e.displayName),
 | 
				
			||||||
 | 
					                          trailing: Checkbox(
 | 
				
			||||||
 | 
					                            value: e.isGk(),
 | 
				
			||||||
 | 
					                            onChanged: e.isGk() || e.canGk(model.getSubjects().collection) ? (value) {
 | 
				
			||||||
 | 
					                              e.unsafeGkToggle = value!;
 | 
				
			||||||
 | 
					                              model.update();
 | 
				
			||||||
 | 
					                            } : null,
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                      }).toList(),
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                  actions: [
 | 
				
			||||||
 | 
					                    TextButton(
 | 
				
			||||||
 | 
					                      onPressed: () {
 | 
				
			||||||
 | 
					                        Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                      },
 | 
				
			||||||
 | 
					                      child: const Text('Fertig'),
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                  ],
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            child: Text(
 | 
				
			||||||
 | 
					                "Grundkurse ${gkSubjects.isEmpty ? "auswählen" : "ändern"}"),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool canGoNextStep(SubjectCollection subjects) {
 | 
				
			||||||
 | 
					    // TODO: implement canGoNextStepp
 | 
				
			||||||
 | 
					    throw UnimplementedError();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										72
									
								
								lib/view/pages/more/abiturCalculator/steps/selectLkStep.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								lib/view/pages/more/abiturCalculator/steps/selectLkStep.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import '../../../../../widget/providerBridge.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../../../../../widget/centeredLeading.dart';
 | 
				
			||||||
 | 
					import '../abiturCalculatorStep.dart';
 | 
				
			||||||
 | 
					import '../abiturCalculatorView.dart';
 | 
				
			||||||
 | 
					import '../models/abiturCalculatorModel.dart';
 | 
				
			||||||
 | 
					import '../models/subject.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SelectLkStep extends AbiturCalculatorStep {
 | 
				
			||||||
 | 
					  SelectLkStep() : super(
 | 
				
			||||||
 | 
					    title: const Text('Leistungskurse'),
 | 
				
			||||||
 | 
					    content: StatefulBuilder(builder: (context, setState) {
 | 
				
			||||||
 | 
					      var model = AbiturCalculatorModel.get(context);
 | 
				
			||||||
 | 
					      var lkSubjects = model.getSubjects().collection.where((e) => e.isLk()).toList();
 | 
				
			||||||
 | 
					      return Column(
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          AbiturCalculatorView.listSubjects(lkSubjects),
 | 
				
			||||||
 | 
					          TextButton(
 | 
				
			||||||
 | 
					            onPressed: () {
 | 
				
			||||||
 | 
					              ProviderBridge.toDialog(context, model, (context, value) {
 | 
				
			||||||
 | 
					                return AlertDialog(
 | 
				
			||||||
 | 
					                  title: const Text('Leistungskurse'),
 | 
				
			||||||
 | 
					                  content: SingleChildScrollView(
 | 
				
			||||||
 | 
					                    child: Column(
 | 
				
			||||||
 | 
					                      mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
 | 
					                      children: model.getSubjects().collection.map((e) {
 | 
				
			||||||
 | 
					                        return ListTile(
 | 
				
			||||||
 | 
					                          leading: CenteredLeading(Icon(e.icon)),
 | 
				
			||||||
 | 
					                          title: Text(e.displayName),
 | 
				
			||||||
 | 
					                          trailing: Checkbox(
 | 
				
			||||||
 | 
					                            value: e.isLk(),
 | 
				
			||||||
 | 
					                            onChanged: e.isLk() || e.canLk(model.getSubjects().collection) ? (value) {
 | 
				
			||||||
 | 
					                              e.unsafeLkToggle = value!;
 | 
				
			||||||
 | 
					                              model.update();
 | 
				
			||||||
 | 
					                            } : null,
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                      }).toList(),
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                  actions: [
 | 
				
			||||||
 | 
					                    TextButton(
 | 
				
			||||||
 | 
					                      onPressed: () {
 | 
				
			||||||
 | 
					                        Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                      },
 | 
				
			||||||
 | 
					                      child: const Text('Fertig'),
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                  ],
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            child: Text("Leistungskurse ${lkSubjects.isEmpty ? "auswählen" : "ändern"}"),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool canGoNextStep(SubjectCollection subjects) {
 | 
				
			||||||
 | 
					    return subjects.collection.where((element) => element.isLk()).length >= 2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					class SelectLkStepTest extends StatelessWidget {
 | 
				
			||||||
 | 
					  const SelectLkStepTest({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return const Placeholder();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								lib/view/pages/more/abiturCalculator/steps/selectPfStep.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								lib/view/pages/more/abiturCalculator/steps/selectPfStep.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../abiturCalculatorStep.dart';
 | 
				
			||||||
 | 
					import '../models/subject.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SelectPfStep extends AbiturCalculatorStep {
 | 
				
			||||||
 | 
					  const SelectPfStep() : super(
 | 
				
			||||||
 | 
					    title: const Text('Prüfungsfächer'),
 | 
				
			||||||
 | 
					    content: const SizedBox.shrink(),
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool canGoNextStep(SubjectCollection subjects) {
 | 
				
			||||||
 | 
					    // TODO: implement canGoNextStepp
 | 
				
			||||||
 | 
					    throw UnimplementedError();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								lib/view/pages/more/abiturCalculator/steps/welcomeStep.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								lib/view/pages/more/abiturCalculator/steps/welcomeStep.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../abiturCalculatorStep.dart';
 | 
				
			||||||
 | 
					import '../models/subject.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WelcomeStep extends AbiturCalculatorStep {
 | 
				
			||||||
 | 
					  const WelcomeStep() : super(
 | 
				
			||||||
 | 
					      title: const Text('Willkommen'),
 | 
				
			||||||
 | 
					      content: const Text('In den folgenden Schritten werden alle nötigen Informationen zur Ermittlung deiner Abiturzulassung abgefragt.')
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool canGoNextStep(SubjectCollection subjects) {
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -10,6 +10,7 @@ import '../../widget/ListItem.dart';
 | 
				
			|||||||
import '../../widget/centeredLeading.dart';
 | 
					import '../../widget/centeredLeading.dart';
 | 
				
			||||||
import '../../widget/infoDialog.dart';
 | 
					import '../../widget/infoDialog.dart';
 | 
				
			||||||
import '../settings/settings.dart';
 | 
					import '../settings/settings.dart';
 | 
				
			||||||
 | 
					import 'more/abiturCalculator/abiturCalculatorView.dart';
 | 
				
			||||||
import 'more/feedback/feedbackDialog.dart';
 | 
					import 'more/feedback/feedbackDialog.dart';
 | 
				
			||||||
import 'more/gradeAverages/gradeAverage.dart';
 | 
					import 'more/gradeAverages/gradeAverage.dart';
 | 
				
			||||||
import 'more/holidays/holidays.dart';
 | 
					import 'more/holidays/holidays.dart';
 | 
				
			||||||
@@ -35,6 +36,7 @@ class Overhang extends StatelessWidget {
 | 
				
			|||||||
          const ListItemNavigator(icon: Icons.newspaper, text: 'Marianum Message', target: Message()),
 | 
					          const ListItemNavigator(icon: Icons.newspaper, text: 'Marianum Message', target: Message()),
 | 
				
			||||||
          const ListItemNavigator(icon: Icons.room, text: 'Raumplan', target: Roomplan()),
 | 
					          const ListItemNavigator(icon: Icons.room, text: 'Raumplan', target: Roomplan()),
 | 
				
			||||||
          const ListItemNavigator(icon: Icons.calculate, text: 'Notendurschnittsrechner', target: GradeAverage()),
 | 
					          const ListItemNavigator(icon: Icons.calculate, text: 'Notendurschnittsrechner', target: GradeAverage()),
 | 
				
			||||||
 | 
					          const ListItemNavigator(icon: Icons.school_outlined, text: 'Abiturrechner', target: AbiturCalculatorView()),
 | 
				
			||||||
          const ListItemNavigator(icon: Icons.calendar_month, text: 'Schulferien', target: Holidays()),
 | 
					          const ListItemNavigator(icon: Icons.calendar_month, text: 'Schulferien', target: Holidays()),
 | 
				
			||||||
          const Divider(),
 | 
					          const Divider(),
 | 
				
			||||||
          ListTile(
 | 
					          ListTile(
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								lib/widget/providerBridge.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/widget/providerBridge.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProviderBridge {
 | 
				
			||||||
 | 
					  static void toDialog<T extends ChangeNotifier>(BuildContext context, T data, Widget Function(BuildContext context, T value) builder) {
 | 
				
			||||||
 | 
					    showDialog(
 | 
				
			||||||
 | 
					      context: context,
 | 
				
			||||||
 | 
					      builder: (context) {
 | 
				
			||||||
 | 
					        return ChangeNotifierProvider.value(
 | 
				
			||||||
 | 
					          value: data,
 | 
				
			||||||
 | 
					          builder: (context, child) {
 | 
				
			||||||
 | 
					            return Consumer<T>(builder: (context, value, child) => builder(context, value));
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user