diff --git a/lib/fonts/Montserrat-Bold.ttf b/lib/fonts/Montserrat-Bold.ttf new file mode 100644 index 0000000..58dbd49 Binary files /dev/null and b/lib/fonts/Montserrat-Bold.ttf differ diff --git a/lib/fonts/Montserrat-ExtraBold.ttf b/lib/fonts/Montserrat-ExtraBold.ttf new file mode 100644 index 0000000..3a904f1 Binary files /dev/null and b/lib/fonts/Montserrat-ExtraBold.ttf differ diff --git a/lib/fonts/Montserrat-ExtraLight.ttf b/lib/fonts/Montserrat-ExtraLight.ttf new file mode 100644 index 0000000..8a787b7 Binary files /dev/null and b/lib/fonts/Montserrat-ExtraLight.ttf differ diff --git a/lib/fonts/Montserrat-Light.ttf b/lib/fonts/Montserrat-Light.ttf new file mode 100644 index 0000000..d1afa35 Binary files /dev/null and b/lib/fonts/Montserrat-Light.ttf differ diff --git a/lib/fonts/Montserrat-Medium.ttf b/lib/fonts/Montserrat-Medium.ttf new file mode 100644 index 0000000..c854b8e Binary files /dev/null and b/lib/fonts/Montserrat-Medium.ttf differ diff --git a/lib/fonts/Montserrat-Regular.ttf b/lib/fonts/Montserrat-Regular.ttf new file mode 100644 index 0000000..f8fbbfe Binary files /dev/null and b/lib/fonts/Montserrat-Regular.ttf differ diff --git a/lib/fonts/Montserrat-SemiBold.ttf b/lib/fonts/Montserrat-SemiBold.ttf new file mode 100644 index 0000000..43144ce Binary files /dev/null and b/lib/fonts/Montserrat-SemiBold.ttf differ diff --git a/lib/fonts/Montserrat-Thin.ttf b/lib/fonts/Montserrat-Thin.ttf new file mode 100644 index 0000000..4b82e7b Binary files /dev/null and b/lib/fonts/Montserrat-Thin.ttf differ diff --git a/lib/main.dart b/lib/main.dart index 83fa217..b242f1a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,48 +1,65 @@ import 'dart:convert'; -import 'package:flutter/material.dart'; +import 'package:awesome_dialog/awesome_dialog.dart'; +import 'package:flutter_neumorphic/flutter_neumorphic.dart'; import 'package:intl/intl.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:charts_flutter/flutter.dart' as charts; import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:tests/preferences.dart'; +import 'package:tests/theme/theme_constants.dart'; +import 'package:tests/theme/theme_manager.dart'; void main() { - runApp(FinancialPlannerApp()); + runApp(const FinancialPlannerApp()); } +ThemeManager _themeManager = ThemeManager(); class FinancialPlannerApp extends StatelessWidget { + const FinancialPlannerApp({super.key}); + @override Widget build(BuildContext context) { return MaterialApp( + debugShowCheckedModeBanner: false, title: 'Financial Planner', - theme: ThemeData( - brightness: Brightness.light, - primarySwatch: Colors.blue, - ), - darkTheme: ThemeData( - brightness: Brightness.dark, - primarySwatch: Colors.blue, - ), - home: HomePage(), + theme: lightTheme, + darkTheme: darkTheme, + themeMode: _themeManager.themeMode, + home: const HomePage(), ); } } class HomePage extends StatefulWidget { + const HomePage({super.key}); + @override - _HomePageState createState() => _HomePageState(); + HomePageState createState() => HomePageState(); } -class _HomePageState extends State { +class HomePageState extends State { List accounts = []; @override void initState() { super.initState(); + _themeManager.addListener(themeListener); loadAccounts(); - } + } + @override + void dispose() { + _themeManager.removeListener(themeListener); + super.dispose(); + } + themeListener(){ + if(mounted){ + setState(() { + + }); + } + } Future loadAccounts() async { SharedPreferences prefs = await SharedPreferences.getInstance(); final accountList = prefs.getStringList('accounts') ?? []; @@ -82,58 +99,91 @@ class _HomePageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Financial Planner'), - ), - body: ListView.builder( - itemCount: accounts.length, - itemBuilder: (context, index) { - return ListTile( - title: Text(accounts[index].name), - subtitle: Text('Balance: \$${accounts[index].balance.toStringAsFixed(2)}'), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AccountDetailPage( - account: accounts[index], - updateAccountBalance: updateAccountBalance, - ), - ), - ); - }, - trailing: IconButton( - icon: Icon(Icons.delete), + centerTitle: true, + backgroundColor: Colors.transparent, + elevation: 0, + title: const Text( + 'Financial Planner', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.black54, + ), + ), + actions: [ + Padding( + padding: const EdgeInsets.only(right: 16.0, top: 3, bottom: 7), + child: NeumorphicButton( onPressed: () { - showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: Text('Delete Account'), - content: Text('Are you sure you want to delete this account?'), - actions: [ - TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: Text('Cancel'), - ), - TextButton( - onPressed: () { - deleteAccount(accounts[index]); - Navigator.of(context).pop(); - }, - child: Text('Delete'), - ), - ], - ); - }, + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Settings()), ); }, + style: NeumorphicStyle( + shape: NeumorphicShape.convex, + boxShape: NeumorphicBoxShape.circle(), + depth: 6, + intensity: 0.9, + color: Colors.grey.shade100, + ), + child: Icon(Icons.settings, color: Colors.black38), + ), + ), + ], + ), + body: ListView.builder( + physics: const BouncingScrollPhysics(), + itemCount: accounts.length, + itemBuilder: (context, index) { + return GestureDetector( + onLongPress: () { + AwesomeDialog( + btnOkText: "Delete", + btnOkColor: Colors.lightGreen, + btnCancelColor: Colors.grey, + context: context, + animType: AnimType.bottomSlide, + dialogType: DialogType.info, + title: 'Delete Account', + headerAnimationLoop: false, + desc: 'Are you sure you want to delete this account?', + btnCancelOnPress: () {}, + btnOkOnPress: () { + deleteAccount(accounts[index]); + }, + ).show(); + + }, + child: Neumorphic( + margin: const EdgeInsets.all(16), + style: NeumorphicStyle( + depth: 7, + intensity: 1, + shadowDarkColor: Colors.grey.shade300, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)), + ), + child: ListTile( + title: Text(accounts[index].name), + subtitle: Text('Balance: \$${accounts[index].balance.toStringAsFixed(2)}'), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AccountDetailPage( + account: accounts[index], + updateAccountBalance: updateAccountBalance, + ), + ), + ); + }, + ), ), ); }, ), - floatingActionButton: FloatingActionButton( + floatingActionButton: NeumorphicButton( onPressed: () { showDialog( context: context, @@ -144,7 +194,14 @@ class _HomePageState extends State { }, ); }, - child: Icon(Icons.add), + style: NeumorphicStyle( + depth: 8, + intensity: 1, + shadowDarkColor: Colors.grey.shade400, + color: Colors.grey.shade100, + boxShape: const NeumorphicBoxShape.circle(), + ), + child: const Icon(Icons.add,size:60,color: Colors.black12,), ), ); } @@ -178,13 +235,13 @@ class Account { class AddAccountDialog extends StatefulWidget { final Function addAccount; - AddAccountDialog({required this.addAccount}); + const AddAccountDialog({super.key, required this.addAccount}); @override - _AddAccountDialogState createState() => _AddAccountDialogState(); + AddAccountDialogState createState() => AddAccountDialogState(); } -class _AddAccountDialogState extends State { +class AddAccountDialogState extends State { final _formKey = GlobalKey(); final _nameController = TextEditingController(); final _balanceController = TextEditingController(); @@ -214,52 +271,123 @@ class _AddAccountDialogState extends State { @override Widget build(BuildContext context) { return AlertDialog( - title: Text('Add Account'), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + title: const Text( + 'Add Account', + ), + titleTextStyle: TextStyle( + color: Colors.black54, + fontSize: 20, + ), content: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ - TextFormField( - controller: _nameController, - decoration: InputDecoration(labelText: 'Name'), - validator: (value) { - if (value!.isEmpty) { - return 'Please enter a name'; - } - return null; - }, + Neumorphic( + style: NeumorphicStyle( + depth: -5, + intensity: 0.8, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.roundRect( + BorderRadius.circular(12), + ), + ), + child: TextFormField( + controller: _nameController, + decoration: InputDecoration( + labelText: 'Name', + border: InputBorder.none, + contentPadding: EdgeInsets.fromLTRB(12, 16, 12, 16), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter a name'; + } + return null; + }, + ), ), - TextFormField( - controller: _balanceController, - decoration: InputDecoration(labelText: 'Balance'), - keyboardType: TextInputType.number, - validator: (value) { - if (value!.isEmpty) { - return 'Please enter a balance'; - } - if (double.tryParse(value) == null) { - return 'Please enter a valid number'; - } - return null; - }, + SizedBox(height: 16), + Neumorphic( + style: NeumorphicStyle( + depth: -5, + intensity: 0.8, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.roundRect( + BorderRadius.circular(12), + ), + ), + child: TextFormField( + controller: _balanceController, + decoration: InputDecoration( + labelText: 'Balance', + border: InputBorder.none, + contentPadding: EdgeInsets.fromLTRB(12, 16, 12, 16), + ), + keyboardType: TextInputType.number, + validator: (value) { + if (value!.isEmpty) { + return 'Please enter a balance'; + } + if (double.tryParse(value) == null) { + return 'Please enter a valid number'; + } + return null; + }, + ), ), ], ), ), actions: [ - TextButton( + NeumorphicButton( onPressed: () { Navigator.of(context).pop(); }, - child: Text('Cancel'), + style: NeumorphicStyle( + shape: NeumorphicShape.concave, + intensity: 0.9, + depth: 9, + boxShape: NeumorphicBoxShape.roundRect( + BorderRadius.circular(12), + ), + color: Colors.grey.shade100, + ), + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: Text( + 'Cancel', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), ), - TextButton( + NeumorphicButton( onPressed: _submitForm, - child: Text('Add'), + style: NeumorphicStyle( + shape: NeumorphicShape.concave, + intensity: 0.8, + depth: 9, + boxShape: NeumorphicBoxShape.roundRect( + BorderRadius.circular(12), + ), + color: Colors.grey.shade100, + ), + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: Text( + 'Add', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), ), ], ); + } } @@ -268,13 +396,13 @@ class AccountDetailPage extends StatefulWidget { final Account account; final Function(Account) updateAccountBalance; - AccountDetailPage({required this.account, required this.updateAccountBalance}); + const AccountDetailPage({super.key, required this.account, required this.updateAccountBalance}); @override - _AccountDetailPageState createState() => _AccountDetailPageState(); + AccountDetailPageState createState() => AccountDetailPageState(); } -class _AccountDetailPageState extends State with SingleTickerProviderStateMixin { +class AccountDetailPageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; List transactions = []; List incomeTransactions = []; @@ -363,14 +491,49 @@ class _AccountDetailPageState extends State with SingleTicker Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text(widget.account.name), + backgroundColor: Colors.transparent, + elevation: 0, + toolbarHeight: 80, + title: Text( + widget.account.name, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.black54, + ), + ), + centerTitle: true, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(15), + bottomRight: Radius.circular(15), + ), + ), + shadowColor: Colors.grey.shade300, + leading: Padding( + padding: const EdgeInsets.only(left: 16.0), + child: NeumorphicButton( + onPressed: () { + Navigator.pop(context); + }, + style: NeumorphicStyle( + shape: NeumorphicShape.flat, + boxShape: NeumorphicBoxShape.circle(), + depth: 6, + intensity: 0.9, + color: Colors.grey.shade100, + ), + padding: EdgeInsets.all(10), + child: Icon(Icons.arrow_back, color: Colors.black38), + ), + ), ), body: Column( children: [ TabBar( controller: _tabController, labelColor: Colors.black, - tabs: [ + tabs: const [ Tab(text: 'Einnahmen'), Tab(text: 'Ausgaben'), ], @@ -391,12 +554,24 @@ class _AccountDetailPageState extends State with SingleTicker ), ], ), - floatingActionButton: FloatingActionButton( + floatingActionButton: NeumorphicButton( onPressed: () => showDialog( context: context, builder: (_) => AddTransactionDialog(addTransaction: addTransaction), ), - child: Icon(Icons.add), + style: NeumorphicStyle( + depth: 8, + intensity: 1, + shadowDarkColor: Colors.grey.shade400, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.circle(), + ), + padding: EdgeInsets.all(16), + child: Icon( + Icons.add, + size: 40, + color: Colors.black12, + ), ), ); } @@ -425,11 +600,11 @@ class _AccountDetailPageState extends State with SingleTicker Widget _buildExpenseChart() { return Padding( - padding: EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8.0), child: Card( elevation: 4.0, child: Padding( - padding: EdgeInsets.all(16.0), + padding: const EdgeInsets.all(16.0), child: MonthlyExpensesChart(data: expenseData), ), ), @@ -484,13 +659,13 @@ class Transaction { class AddTransactionDialog extends StatefulWidget { final Function addTransaction; - AddTransactionDialog({required this.addTransaction}); + const AddTransactionDialog({super.key, required this.addTransaction}); @override - _AddTransactionDialogState createState() => _AddTransactionDialogState(); + AddTransactionDialogState createState() => AddTransactionDialogState(); } -class _AddTransactionDialogState extends State { +class AddTransactionDialogState extends State { final _formKey = GlobalKey(); final _titleController = TextEditingController(); final _amountController = TextEditingController(); @@ -523,15 +698,38 @@ class _AddTransactionDialogState extends State { @override Widget build(BuildContext context) { return AlertDialog( - title: Text('Add Transaction'), - content: Form( - key: _formKey, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TextFormField( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + title: Text( + 'Add Transaction', + style: TextStyle( + fontSize: 20, + color: Colors.black54, + ), + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Neumorphic( + style: NeumorphicStyle( + depth: -5, + intensity: 0.8, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.roundRect( + BorderRadius.circular(12), + ), + ), + child: TextFormField( controller: _titleController, - decoration: InputDecoration(labelText: 'Title'), + decoration: InputDecoration( + labelText: 'Title', + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric( + vertical: 12, + horizontal: 16, + ), + ), validator: (value) { if (value!.isEmpty) { return 'Please enter a title'; @@ -539,9 +737,27 @@ class _AddTransactionDialogState extends State { return null; }, ), - TextFormField( + ), + SizedBox(height: 16), + Neumorphic( + style: NeumorphicStyle( + depth: -5, + intensity: 0.8, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.roundRect( + BorderRadius.circular(12), + ), + ), + child: TextFormField( controller: _amountController, - decoration: InputDecoration(labelText: 'Amount'), + decoration: InputDecoration( + labelText: 'Amount', + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric( + vertical: 12, + horizontal: 16, + ), + ), keyboardType: TextInputType.number, validator: (value) { if (value!.isEmpty) { @@ -553,35 +769,71 @@ class _AddTransactionDialogState extends State { return null; }, ), - Row( - children: [ - Checkbox( - value: _isExpense, - onChanged: (value) { - setState(() { - _isExpense = value!; - }); - }, - ), - Text('Expense'), - ], - ), - ], - ), + ), + SizedBox(height: 16), + Row( + children: [ + NeumorphicCheckbox( + style: NeumorphicCheckboxStyle(selectedColor: Colors.lightGreen, disabledColor: Colors.grey.shade200,selectedDepth: -10, unselectedDepth: 8), + value: _isExpense, + onChanged: (value) { + setState(() { + _isExpense = value!; + }); + }, + ), + SizedBox(width: 8), + Text('Expense', style: TextStyle(color: Colors.black87),), + ], + ), + ], ), actions: [ - TextButton( + NeumorphicButton( onPressed: () { Navigator.of(context).pop(); }, - child: Text('Cancel'), + style: NeumorphicStyle( + shape: NeumorphicShape.concave, + intensity: 0.8, + depth: 9, + boxShape: NeumorphicBoxShape.roundRect( + BorderRadius.circular(12), + ), + color: Colors.grey.shade100, + ), + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: Text( + 'Cancel', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), ), - TextButton( + NeumorphicButton( onPressed: _submitForm, - child: Text('Add'), + style: NeumorphicStyle( + shape: NeumorphicShape.concave, + intensity: 0.8, + depth: 9, + boxShape: NeumorphicBoxShape.roundRect( + BorderRadius.circular(12), + ), + color: Colors.grey.shade100, + ), + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: Text( + 'Add', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), ), ], ); + } } @@ -589,11 +841,11 @@ class _AddTransactionDialogState extends State { class MonthlyExpensesChart extends StatelessWidget { final List data; - MonthlyExpensesChart({required this.data}); + const MonthlyExpensesChart({super.key, required this.data}); @override Widget build(BuildContext context) { - return Container( + return SizedBox( height: 300, child: SfCartesianChart( primaryXAxis: CategoryAxis(), diff --git a/lib/monthly_expenses.dart b/lib/monthly_expenses.dart index 48da208..3e191e0 100644 --- a/lib/monthly_expenses.dart +++ b/lib/monthly_expenses.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; -import 'main.dart'; class MonthlyExpensesChart extends StatelessWidget { final List data; - MonthlyExpensesChart({required this.data}); + const MonthlyExpensesChart({super.key, required this.data}); @override Widget build(BuildContext context) { @@ -22,18 +21,18 @@ class MonthlyExpensesChart extends StatelessWidget { return Container( height: 200, - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: charts.BarChart( series, animate: true, - domainAxis: charts.OrdinalAxisSpec( + domainAxis: const charts.OrdinalAxisSpec( renderSpec: charts.SmallTickRendererSpec( labelStyle: charts.TextStyleSpec( fontSize: 12, ), ), ), - primaryMeasureAxis: charts.NumericAxisSpec( + primaryMeasureAxis: const charts.NumericAxisSpec( renderSpec: charts.GridlineRendererSpec( labelStyle: charts.TextStyleSpec( fontSize: 12, diff --git a/lib/preferences.dart b/lib/preferences.dart new file mode 100644 index 0000000..d49a967 --- /dev/null +++ b/lib/preferences.dart @@ -0,0 +1,177 @@ +import 'package:flutter_neumorphic/flutter_neumorphic.dart'; +import 'package:tests/theme/theme_manager.dart'; + +ThemeManager _themeManager = ThemeManager(); + +class Settings extends StatefulWidget { + const Settings({Key? key}) : super(key: key); + + @override + SettingsState createState() => SettingsState(); +} + +class SettingsState extends State { + + String _selectedLanguage = 'English'; + String _selectedCurrency = 'Euro'; + + final List _languages = ['English', 'Deutsch']; + final List _currencies = ['Euro', 'Dollar', 'CHF']; + + @override + void dispose() { + _themeManager.removeListener(themeListener); + super.dispose(); + } + themeListener(){ + if(mounted){ + setState(() { + + }); + } + } + + @override + void initState() { + super.initState(); + _themeManager.addListener(themeListener); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + toolbarHeight: 80, + title: Text( + 'Settings', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.black54, + ), + ), + centerTitle: true, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(15), + bottomRight: Radius.circular(15), + ), + ), + shadowColor: Colors.grey.shade300, + leading: Padding( + padding: const EdgeInsets.only(left: 16.0), + child: NeumorphicButton( + onPressed: () { + Navigator.pop(context); + }, + style: NeumorphicStyle( + shape: NeumorphicShape.flat, + boxShape: NeumorphicBoxShape.circle(), + depth: 6, + intensity: 0.9, + color: Colors.grey.shade100, + ), + padding: EdgeInsets.all(10), + child: Icon(Icons.arrow_back, color: Colors.black38), + ), + ), + ), + body: ListView( + padding: const EdgeInsets.all(16.0), + children: [ + Neumorphic( + style: NeumorphicStyle( + depth: 7, + intensity: 1, + shadowDarkColor: Colors.grey.shade300, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)), + ), + child: ListTile( + title: const Text('Dark Mode'), + trailing: NeumorphicSwitch( + value: _themeManager.themeMode == ThemeMode.dark, + onChanged: (bool value) { + setState(() { + _themeManager.toggleTheme(value); + }); + }, + style: NeumorphicSwitchStyle( + lightSource: LightSource.topLeft, + thumbShape: NeumorphicShape.concave, + trackDepth: 5, + // Weitere Style-Eigenschaften hier anpassen + // Um den Switch heller zu machen, kannst du die Farben anpassen + activeTrackColor: Colors.lightGreen, // Farbe für den aktiven Track + inactiveTrackColor: Colors.grey.shade300, // Farbe für den inaktiven Track + activeThumbColor: Colors.grey.shade100, // Farbe für den aktiven Thumb + inactiveThumbColor: Colors.grey.shade200, // Farbe für den inaktiven Thumb + ), + ), + ), + ), + const SizedBox(height: 16), + Neumorphic( + style: NeumorphicStyle( + depth: 7, + intensity: 1, + shadowDarkColor: Colors.grey.shade300, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)), + ), + child: ListTile( + title: const Text('Language'), + trailing: DropdownButton( + value: _selectedLanguage, + onChanged: (String? newValue) { + setState(() { + _selectedLanguage = newValue!; + // Hier kannst du die Spracheinstellung entsprechend anpassen + // z.B. mit einer Funktion, die die App-Sprache ändert. + }); + }, + items: _languages.map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + ), + ), + ), + const SizedBox(height: 16), + Neumorphic( + style: NeumorphicStyle( + depth: 7, + intensity: 1, + shadowDarkColor: Colors.grey.shade300, + color: Colors.grey.shade100, + boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)), + ), + child: ListTile( + title: const Text('Currency'), + trailing: DropdownButton( + value: _selectedCurrency, + onChanged: (String? newValue) { + setState(() { + _selectedCurrency = newValue!; + // Hier kannst du die Währungseinstellung entsprechend anpassen + // z.B. mit einer Funktion, die die Währung ändert. + }); + }, + items: _currencies.map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/theme/theme_constants.dart b/lib/theme/theme_constants.dart new file mode 100644 index 0000000..ca5fdc7 --- /dev/null +++ b/lib/theme/theme_constants.dart @@ -0,0 +1,20 @@ + +import 'package:flutter/material.dart'; + +const COLOR_PRIMARY = Colors.deepOrangeAccent; + +ThemeData lightTheme = ThemeData( + brightness: Brightness.light, + primaryColor: COLOR_PRIMARY, + fontFamily: "Montserrat" + +); + +ThemeData darkTheme = ThemeData( + fontFamily: "Montserrat", + brightness: Brightness.dark, + switchTheme: SwitchThemeData( + trackColor: MaterialStateProperty.all(Colors.grey), + thumbColor: MaterialStateProperty.all(Colors.white), + ), +); diff --git a/lib/theme/theme_manager.dart b/lib/theme/theme_manager.dart new file mode 100644 index 0000000..4af4ddb --- /dev/null +++ b/lib/theme/theme_manager.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +class ThemeManager with ChangeNotifier{ + + ThemeMode _themeMode = ThemeMode.light; + + get themeMode => _themeMode; + + toggleTheme(bool isDark){ + _themeMode = isDark?ThemeMode.dark:ThemeMode.light; + notifyListeners(); + } + +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index d0c6fe0..b59f42d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.10.0" + awesome_dialog: + dependency: "direct main" + description: + name: awesome_dialog + sha256: "7da175ea284fa5da0a4d0cbdfe835c5b71d30c7b38c1770c0f27f48272ff5a08" + url: "https://pub.dev" + source: hosted + version: "3.1.0" boolean_selector: dependency: transitive description: @@ -102,6 +110,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + flutter_neumorphic: + dependency: "direct main" + description: + name: flutter_neumorphic + sha256: "02606d937a3ceaa497b8a7c25f3efa95188bf93d77ebf0bd6552e432db4c2ec6" + url: "https://pub.dev" + source: hosted + version: "3.2.0" flutter_test: dependency: "direct dev" description: flutter @@ -112,8 +128,32 @@ packages: description: flutter source: sdk version: "0.0.0" - intl: + graphs: dependency: transitive + description: + name: graphs + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" + source: hosted + version: "2.3.1" + http: + dependency: transitive + description: + name: http + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + url: "https://pub.dev" + source: hosted + version: "0.13.6" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + intl: + dependency: "direct main" description: name: intl sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" @@ -224,6 +264,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.4" + rive: + dependency: transitive + description: + name: rive + sha256: "55e1f8bf249444545a7c832830d2bbb9adae759193fb879294bc6018b9f0eedd" + url: "https://pub.dev" + source: hosted + version: "0.11.3" + rive_common: + dependency: transitive + description: + name: rive_common + sha256: "7e17937b790bb2f631767b3d505da8c298309c0a6ab08cd317fa6fe081ed5b63" + url: "https://pub.dev" + source: hosted + version: "0.0.10" shared_preferences: dependency: "direct main" description: @@ -349,6 +405,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.16" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" vector_math: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1ac76d9..8093ac7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,14 +30,15 @@ environment: dependencies: flutter: sdk: flutter - - + intl: ^0.17.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 shared_preferences: ^2.1.2 charts_flutter: ^0.12.0 syncfusion_flutter_charts: ^21.2.4 + flutter_neumorphic: ^3.2.0 + awesome_dialog: ^3.1.0 dev_dependencies: flutter_test: @@ -61,33 +62,24 @@ flutter: # the material Icons class. uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # + fonts: + - family: Montserrat + fonts: + - asset: lib/fonts/Montserrat-Regular.ttf + weight: 400 + - asset: lib/fonts/Montserrat-Bold.ttf + weight: 700 + - asset: lib/fonts/Montserrat-ExtraBold.ttf + weight: 800 + - asset: lib/fonts/Montserrat-Light.ttf + weight: 300 + - asset: lib/fonts/Montserrat-ExtraLight.ttf + weight: 200 + - asset: lib/fonts/Montserrat-Medium.ttf + weight: 500 + - asset: lib/fonts/Montserrat-SemiBold.ttf + weight: 600 + - asset: lib/fonts/Montserrat-Thin.ttf + weight: 100 # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages