import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_application_1/calculator.dart'; import 'package:flutter_application_1/enums.dart'; import 'package:flutter_application_1/utils.dart'; import 'package:flutter_application_1/widgets/input_widget.dart'; import 'package:flutter_application_1/widgets/interval_widget.dart'; import 'package:flutter_application_1/widgets/result_widget.dart'; import 'package:flutter_application_1/widgets/error_widget.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Zinseszinsrechner', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: CupertinoColors.white, background: CupertinoColors.white), useMaterial3: true, ), home: const MyHomePage(title: 'Zinseszinsrechner',), debugShowCheckedModeBanner: false, ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { // Controller und Fokus-Knoten für die Eingabefelder final TextEditingController _initialCapitalController = TextEditingController(); final TextEditingController _monthlySavingsRateController = TextEditingController(); final TextEditingController _interestRateController = TextEditingController(); final TextEditingController _timeController = TextEditingController(); final FocusNode _initialCapitalFocusNode = FocusNode(); final FocusNode _monthlySavingsRateFocusNode = FocusNode(); final FocusNode _interestRateFocusNode = FocusNode(); final FocusNode _timeFocusNode = FocusNode(); // Zustandsvariablen für die Validierung der Eingaben bool _isInitialCapitalEntered = false; bool _isMonthlySavingsRateEntered = false; bool _isInterestRateEntered = false; bool _isTimeEntered = false; @override void initState() { super.initState(); // Listener für die Eingabefelder, um die Validierung durchzuführen und Standardwerte wiederherzustellen _initialCapitalController.addListener(() { setState(() { _isInitialCapitalEntered = _initialCapitalController.text.isNotEmpty && isNumeric(_initialCapitalController.text); restoreDefaultValuesIfEmpty(_initialCapitalController); }); }); _monthlySavingsRateController.addListener(() { setState(() { _isMonthlySavingsRateEntered = _monthlySavingsRateController.text.isNotEmpty && isNumeric(_monthlySavingsRateController.text); restoreDefaultValuesIfEmpty(_monthlySavingsRateController); }); }); _interestRateController.addListener(() { setState(() { _isInterestRateEntered = _interestRateController.text.isNotEmpty && isNumeric(_interestRateController.text); restoreDefaultValuesIfEmpty(_interestRateController); }); }); _timeController.addListener(() { setState(() { _isTimeEntered = _timeController.text.isNotEmpty && isNumeric(_timeController.text); restoreDefaultValuesIfEmpty(_timeController); }); }); // Listener für die Fokus-Knoten, um die Eingabe zu runden, wenn der Fokus verloren geht _initialCapitalFocusNode.addListener(() { if (!_initialCapitalFocusNode.hasFocus) { roundToInteger(_initialCapitalController); } }); _monthlySavingsRateFocusNode.addListener(() { if (!_monthlySavingsRateFocusNode.hasFocus) { roundToInteger(_monthlySavingsRateController); } }); _interestRateFocusNode.addListener(() { if (!_interestRateFocusNode.hasFocus) { roundToInteger(_interestRateController); } }); _timeFocusNode.addListener(() { if (!_timeFocusNode.hasFocus) { roundToInteger(_timeController); } }); // Setzen von Beispielwerten für die Eingabefelder _initialCapitalController.text = '1000'; _monthlySavingsRateController.text = '50'; _interestRateController.text = '5'; _timeController.text = '10'; } double _initialCapital = 0.0; // Das anfängliche Kapital double _monthlySavingsRate = 0.0; // Der monatliche Sparbetrag double _interestRate = 0.0; // Der jährliche Zinssatz double _time = 0.0; // Der Anlagezeitraum in Jahren double _investedMoney = 0.0; // Das investierte Geld final List _investedMoneyList = []; // Liste, die das investierte Geld pro Jahr speichert PayoutInterval _payoutInterval = PayoutInterval.yearly; // Das Auszahlungsintervall (jährlich oder monatlich) double _compoundInterest = 0.0; // Der Zinseszins final List _compoundInterestList = []; // Liste, die den Zinseszins pro Jahr speichert // Methoden zum Festlegen der Werte aus den Eingabefeldern void setInitialCapital() { setState(() { _initialCapital = double.parse(_initialCapitalController.text); }); } void setMonthlySavingsRate() { setState(() { _monthlySavingsRate = double.parse(_monthlySavingsRateController.text); }); } void setInterestRate() { setState(() { _interestRate = double.parse(_interestRateController.text); }); } void setTime() { setState(() { _time = double.parse(_timeController.text); }); } CalculationPerformed _isCalculated = CalculationPerformed.noFirstTimeItLoaded; @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( padding: const EdgeInsets.all(20.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ InputWidget( label: 'Anfangskapital', controller: _initialCapitalController, focusNode: _initialCapitalFocusNode, isValid: _isInitialCapitalEntered, suffixText: '€', tooltipText: 'Das Anfangskapital ist der Betrag, den Sie zu Beginn Ihrer Anlage haben.' ), InputWidget( label: 'Monatliche Sparrate', controller: _monthlySavingsRateController, focusNode: _monthlySavingsRateFocusNode, isValid: _isMonthlySavingsRateEntered, suffixText: '€', tooltipText: 'Die monatliche Sparrate ist der Betrag, den Sie jeden Monat zu Ihrer Investition hinzufügen.' ), InputWidget( label: 'Jährlicher Zinssatz', controller: _interestRateController, focusNode: _interestRateFocusNode, isValid: _isInterestRateEntered, suffixText: '%', tooltipText: 'Der jährliche Zinssatz ist der Prozentsatz, zu dem Ihr investiertes Kapital jedes Jahr wächst.' ), InputWidget( label: 'Anlagezeitraum', controller: _timeController, focusNode: _timeFocusNode, isValid: _isTimeEntered, suffixText: 'Jahre', tooltipText: 'Der Anlagezeitraum ist die Zeitspanne, für die Sie planen, Ihr Geld anzulegen.' ), IntervalWidget( selectedInterval: translateInterval(_payoutInterval), onChanged: (newInterval) { setState(() { _payoutInterval = newInterval == 'jährlich' ? PayoutInterval.yearly : PayoutInterval.monthly; }); }, ), ElevatedButton( onPressed: () { if (_isInitialCapitalEntered && _isMonthlySavingsRateEntered && _isInterestRateEntered && _isTimeEntered) { setInitialCapital(); setMonthlySavingsRate(); setInterestRate(); setTime(); _investedMoney = calculateInvestedMoney(_initialCapital, _monthlySavingsRate, _time, _investedMoneyList); _compoundInterest = calculateCompoundInterest( _initialCapital, _monthlySavingsRate, _interestRate, _time, _payoutInterval, _investedMoneyList, _compoundInterestList ); _isCalculated = CalculationPerformed.yes; } else { _isCalculated = CalculationPerformed.no; } setState(() {}); }, style: ButtonStyle( backgroundColor: MaterialStateProperty.all(CupertinoColors.black), foregroundColor: MaterialStateProperty.all(CupertinoColors.white), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), ), ), child: const Text( 'Berechnen', style: TextStyle( fontWeight: FontWeight.bold, ), ), ), const SizedBox(height: 20), if(_isCalculated == CalculationPerformed.yes) ResultWidget( compoundInterest: '$_compoundInterest', investedMoney: '$_investedMoney', time: '$_time', monthlySavingsRate: '$_monthlySavingsRate', interestRate: '$_interestRate', payoutInterval: _payoutInterval, investedMoneyList: _investedMoneyList, compoundInterestList: _compoundInterestList, ), if(_isCalculated == CalculationPerformed.no) const ErrWidget( errorMessage: 'Ungültige Eingabe', ), ], ), ) ) ) ); } }