Darkmode+ budgetchecker finished
parent
5582e7b4fa
commit
db9abf9866
|
@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tests/saving_tips.dart';
|
import 'package:tests/saving_tips.dart';
|
||||||
|
import 'package:tests/theme/theme_constants.dart';
|
||||||
import 'package:tests/transaction/transaction_dialog.dart';
|
import 'package:tests/transaction/transaction_dialog.dart';
|
||||||
import 'package:tests/transaction/transaction.dart';
|
import 'package:tests/transaction/transaction.dart';
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
|
@ -30,35 +31,41 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
List<Transaction> incomeTransactions = [];
|
List<Transaction> incomeTransactions = [];
|
||||||
List<Transaction> expenseTransactions = [];
|
List<Transaction> expenseTransactions = [];
|
||||||
List<ExpenseData> expenseData = [];
|
List<ExpenseData> expenseData = [];
|
||||||
String _selectedCurrency="€";
|
String _selectedCurrency = "€";
|
||||||
|
|
||||||
Future<String> getCurrencyFromSharedPreferences(String key) async {
|
Future<String> getCurrencyFromSharedPreferences(String key) async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
if (prefs.getString(key)=="Euro"){
|
if (prefs.getString(key) == "Euro") {
|
||||||
_selectedCurrency="€";
|
_selectedCurrency = "€";
|
||||||
}
|
}
|
||||||
if (prefs.getString(key)=="Dollar"){
|
if (prefs.getString(key) == "Dollar") {
|
||||||
_selectedCurrency=r"$";
|
_selectedCurrency = r"$";
|
||||||
}
|
}
|
||||||
if (prefs.getString(key)=="CHF"){
|
if (prefs.getString(key) == "CHF") {
|
||||||
_selectedCurrency="CHF";
|
_selectedCurrency = "CHF";
|
||||||
}
|
}
|
||||||
|
|
||||||
return prefs.getString(key) ?? 'Euro';
|
return prefs.getString(key) ?? 'Euro';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_tabController = TabController(length: 3, vsync: this);
|
_tabController = TabController(length: 3, vsync: this);
|
||||||
|
|
||||||
getCurrencyFromSharedPreferences("currency").then((value) {
|
getCurrencyFromSharedPreferences("currency").then((value) {
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
loadMaxProgress();
|
||||||
loadTransactions();
|
loadTransactions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loadMaxProgress() async {
|
||||||
|
double storedMaxProgress = await getMaxProgress();
|
||||||
|
setState(() {
|
||||||
|
maxProgress = storedMaxProgress;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_tabController.dispose();
|
_tabController.dispose();
|
||||||
|
@ -141,8 +148,24 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
final _budgetController = TextEditingController();
|
final _budgetController = TextEditingController();
|
||||||
double progress = 0;
|
double progress = 0;
|
||||||
|
|
||||||
double submitbudget() {
|
double submitBudget() {
|
||||||
return progress = double.parse(_budgetController.text.trim());
|
if (_budgetController.text.isNotEmpty) {
|
||||||
|
double budgetValue = double.parse(_budgetController.text);
|
||||||
|
SharedPreferences.getInstance().then((prefs) {
|
||||||
|
prefs.setDouble("maxProgress", budgetValue);
|
||||||
|
});
|
||||||
|
setState(() {
|
||||||
|
maxProgress = budgetValue;
|
||||||
|
});
|
||||||
|
return budgetValue;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<double> getMaxProgress() async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
double maxProgress = prefs.getDouble('maxProgress') ?? 1000;
|
||||||
|
return maxProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -155,9 +178,9 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 10.0),
|
padding: const EdgeInsets.only(right: 10.0),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: const Icon(
|
icon: Icon(
|
||||||
Icons.info,
|
Icons.info,
|
||||||
color: Colors.grey,
|
color: Theme.of(context).unselectedWidgetColor,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
@ -171,11 +194,12 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
toolbarHeight: 80,
|
toolbarHeight: 80,
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.account.name,
|
widget.account.name,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.black54,
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
),
|
? Colors.white70
|
||||||
|
: Colors.black87),
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
|
@ -184,13 +208,12 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
bottomRight: Radius.circular(15),
|
bottomRight: Radius.circular(15),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
shadowColor: Colors.grey.shade300,
|
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
padding: const EdgeInsets.only(left: 16.0),
|
padding: const EdgeInsets.only(left: 16.0),
|
||||||
child: NeumorphicButton(
|
child: NeumorphicButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context); // Zurück zur vorherigen Seite
|
Navigator.pop(context);
|
||||||
Navigator.pushReplacement( // Neue Seite öffnen und vorherige Seite ersetzen
|
Navigator.pushReplacement(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => const HomePage()),
|
MaterialPageRoute(builder: (context) => const HomePage()),
|
||||||
);
|
);
|
||||||
|
@ -199,11 +222,20 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
shape: NeumorphicShape.flat,
|
shape: NeumorphicShape.flat,
|
||||||
boxShape: const NeumorphicBoxShape.circle(),
|
boxShape: const NeumorphicBoxShape.circle(),
|
||||||
depth: 6,
|
depth: 6,
|
||||||
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
intensity: 0.9,
|
intensity: 0.9,
|
||||||
color: Colors.grey.shade100,
|
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(8),
|
||||||
child: const Icon(Icons.arrow_back, color: Colors.black38),
|
child: Icon(Icons.arrow_back,
|
||||||
|
color: Theme.of(context).unselectedWidgetColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -211,12 +243,12 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
children: [
|
children: [
|
||||||
TabBar(
|
TabBar(
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
labelColor: Colors.black,
|
labelColor: Theme.of(context).cardColor,
|
||||||
labelStyle: const TextStyle(fontSize: 14),
|
labelStyle: const TextStyle(fontSize: 14),
|
||||||
unselectedLabelColor: Colors.black54,
|
unselectedLabelColor: Theme.of(context).unselectedWidgetColor,
|
||||||
indicator: MaterialIndicator(
|
indicator: MaterialIndicator(
|
||||||
height: 4,
|
height: 4,
|
||||||
color: Colors.black54,
|
color: Theme.of(context).unselectedWidgetColor,
|
||||||
topLeftRadius: 8,
|
topLeftRadius: 8,
|
||||||
topRightRadius: 8,
|
topRightRadius: 8,
|
||||||
horizontalPadding: 45,
|
horizontalPadding: 45,
|
||||||
|
@ -249,16 +281,27 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
Neumorphic(
|
Neumorphic(
|
||||||
margin: const EdgeInsets.all(14),
|
margin: const EdgeInsets.all(14),
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor:
|
||||||
|
Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(15)),
|
BorderRadius.circular(15)),
|
||||||
depth: -5,
|
depth: -5,
|
||||||
intensity: 0.8,
|
intensity: 0.8,
|
||||||
),
|
),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
controller: _budgetController,
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'enteramount'.tr(),
|
labelText: 'enterbudget'.tr(),
|
||||||
contentPadding: const EdgeInsets.only(
|
contentPadding: const EdgeInsets.only(
|
||||||
left: 16, bottom: 8, top: 8),
|
left: 16, bottom: 8, top: 8),
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
|
@ -268,13 +311,25 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
NeumorphicButton(
|
NeumorphicButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
progress = submitbudget();
|
setState(() {
|
||||||
|
submitBudget();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor:
|
||||||
|
Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
depth: 8,
|
depth: 8,
|
||||||
intensity: 0.9,
|
intensity: 0.9,
|
||||||
),
|
),
|
||||||
|
@ -295,15 +350,23 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: 8,
|
depth: 8,
|
||||||
intensity: 1,
|
intensity: 1,
|
||||||
shadowDarkColor: Colors.grey.shade400,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
color: Colors.grey.shade100,
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: const NeumorphicBoxShape.circle(),
|
boxShape: const NeumorphicBoxShape.circle(),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(16),
|
child: Icon(
|
||||||
child: const Icon(
|
|
||||||
Icons.add,
|
Icons.add,
|
||||||
size: 40,
|
size: 60,
|
||||||
color: Colors.black12,
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? Colors.black12
|
||||||
|
: Colors.white12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -311,14 +374,20 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
|
|
||||||
final ValueNotifier<double> _valueNotifier = ValueNotifier(0);
|
final ValueNotifier<double> _valueNotifier = ValueNotifier(0);
|
||||||
|
|
||||||
|
double maxProgress = 500;
|
||||||
|
|
||||||
Widget monthlybudgetplanner() {
|
Widget monthlybudgetplanner() {
|
||||||
return CircularSeekBar(
|
return CircularSeekBar(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 300,
|
height: 300,
|
||||||
trackColor: Colors.black12,
|
trackColor: Theme.of(context).brightness == Brightness.light
|
||||||
progress: 500,
|
? Colors.black12
|
||||||
|
: Colors.white12,
|
||||||
|
progress: calculateMonthlyExpensesTotal(),
|
||||||
minProgress: 0,
|
minProgress: 0,
|
||||||
maxProgress: 800,
|
maxProgress: calculateMonthlyExpensesTotal() > maxProgress
|
||||||
|
? calculateMonthlyExpensesTotal()
|
||||||
|
: maxProgress,
|
||||||
barWidth: 17,
|
barWidth: 17,
|
||||||
startAngle: 45,
|
startAngle: 45,
|
||||||
sweepAngle: 270,
|
sweepAngle: 270,
|
||||||
|
@ -338,10 +407,9 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
],
|
],
|
||||||
innerThumbRadius: 0,
|
innerThumbRadius: 0,
|
||||||
innerThumbStrokeWidth: 12,
|
innerThumbStrokeWidth: 12,
|
||||||
innerThumbColor: Colors.white,
|
innerThumbColor: Theme.of(context).cardColor,
|
||||||
outerThumbRadius: 0,
|
outerThumbRadius: 0,
|
||||||
outerThumbStrokeWidth: 15,
|
outerThumbStrokeWidth: 15,
|
||||||
outerThumbColor: Colors.blueAccent,
|
|
||||||
dashWidth: 1.5,
|
dashWidth: 1.5,
|
||||||
dashGap: 1.9,
|
dashGap: 1.9,
|
||||||
animation: true,
|
animation: true,
|
||||||
|
@ -350,24 +418,59 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
valueNotifier: _valueNotifier,
|
valueNotifier: _valueNotifier,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: ValueListenableBuilder(
|
child: ValueListenableBuilder(
|
||||||
valueListenable: _valueNotifier,
|
valueListenable: _valueNotifier,
|
||||||
builder: (_, double value, __) => Column(
|
builder: (_, double value, __) {
|
||||||
mainAxisSize: MainAxisSize.min,
|
final isMaxProgressReached = value >= maxProgress;
|
||||||
children: [
|
final textStyle = TextStyle(
|
||||||
Text(
|
fontSize: 15,
|
||||||
'${value.round()}$_selectedCurrency',
|
fontWeight:
|
||||||
),
|
isMaxProgressReached ? FontWeight.w600 : FontWeight.w300,
|
||||||
Text(
|
);
|
||||||
'progress'.tr(),
|
|
||||||
),
|
return Column(
|
||||||
],
|
mainAxisSize: MainAxisSize.min,
|
||||||
)),
|
children: [
|
||||||
|
if (isMaxProgressReached)
|
||||||
|
Text(
|
||||||
|
"budgetmax".tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Theme.of(context).cardColor),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Text(
|
||||||
|
'${value.round()}$_selectedCurrency',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24, color: Theme.of(context).cardColor),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
isMaxProgressReached
|
||||||
|
? Text('hint'.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(color: Theme.of(context).cardColor))
|
||||||
|
: Text('progress'.tr(),
|
||||||
|
style: TextStyle(color: Theme.of(context).cardColor)),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
isMaxProgressReached
|
||||||
|
? Container()
|
||||||
|
: Text(
|
||||||
|
'Budget: $maxProgress',
|
||||||
|
style: textStyle,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTransactionsList(List<Transaction> transactionsList) {
|
Widget _buildTransactionsList(List<Transaction> transactionsList) {
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
itemCount: transactionsList.length,
|
itemCount: transactionsList.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
@ -389,11 +492,25 @@ class AccountDetailPageState extends State<AccountDetailPage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double calculateMonthlyExpensesTotal() {
|
||||||
|
double total = 0;
|
||||||
|
for (var transaction in expenseTransactions) {
|
||||||
|
String month = DateFormat('yyyy-MM').format(transaction.date);
|
||||||
|
if (month == DateFormat('yyyy-MM').format(DateTime.now())) {
|
||||||
|
total += transaction.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildExpenseChart() {
|
Widget _buildExpenseChart() {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Card(
|
child: Card(
|
||||||
elevation: 4.0,
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey400
|
||||||
|
: grey800,
|
||||||
|
elevation: 6.0,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: MonthlyExpensesChart(data: expenseData),
|
child: MonthlyExpensesChart(data: expenseData),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
||||||
|
import '../theme/theme_constants.dart';
|
||||||
import 'account.dart';
|
import 'account.dart';
|
||||||
|
|
||||||
class AddAccountDialog extends StatefulWidget {
|
class AddAccountDialog extends StatefulWidget {
|
||||||
|
@ -33,7 +34,6 @@ class AddAccountDialogState extends State<AddAccountDialog> {
|
||||||
balance: balance,
|
balance: balance,
|
||||||
);
|
);
|
||||||
widget.addAccount(account);
|
widget.addAccount(account);
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ class AddAccountDialogState extends State<AddAccountDialog> {
|
||||||
'addaccount'.tr(),
|
'addaccount'.tr(),
|
||||||
),
|
),
|
||||||
titleTextStyle: const TextStyle(
|
titleTextStyle: const TextStyle(
|
||||||
color: Colors.black54,
|
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
),
|
),
|
||||||
content: Form(
|
content: Form(
|
||||||
|
@ -60,7 +59,16 @@ class AddAccountDialogState extends State<AddAccountDialog> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: -5,
|
depth: -5,
|
||||||
intensity: 0.8,
|
intensity: 0.8,
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
|
@ -85,7 +93,16 @@ class AddAccountDialogState extends State<AddAccountDialog> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: -5,
|
depth: -5,
|
||||||
intensity: 0.8,
|
intensity: 0.8,
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
|
@ -114,6 +131,7 @@ class AddAccountDialogState extends State<AddAccountDialog> {
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
NeumorphicButton(
|
NeumorphicButton(
|
||||||
|
margin: const EdgeInsets.fromLTRB(0, 0, 4, 4),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
|
@ -124,7 +142,15 @@ class AddAccountDialogState extends State<AddAccountDialog> {
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
|
@ -144,7 +170,15 @@ class AddAccountDialogState extends State<AddAccountDialog> {
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
{
|
{
|
||||||
"title" : "My Finance Planner",
|
"title": "My Finance Planner",
|
||||||
"delete" : "Löschen",
|
"delete": "Löschen",
|
||||||
"deleteaccount" : "Account löschen",
|
"deleteaccount": "Account löschen",
|
||||||
"sure" : "Sind Sie sicher, dass Sie dieses Konto löschen möchten?",
|
"sure": "Sind Sie sicher, dass Sie dieses Konto löschen möchten?",
|
||||||
"balance" : "Bilanz",
|
"balance": "Bilanz",
|
||||||
"addaccount" : "Konto hinzufügen",
|
"addaccount": "Konto hinzufügen",
|
||||||
"entername" : "Bitte geben Sie einen Namen ein",
|
"entername": "Bitte geben Sie einen Namen ein",
|
||||||
"enterbalance" : "Bitte geben Sie einen Saldo ein",
|
"enterbalance": "Bitte geben Sie einen Saldo ein",
|
||||||
"entervalidnumber" : "Bitte geben Sie eine gültige Nummer ein",
|
"entervalidnumber": "Bitte geben Sie eine gültige Nummer ein",
|
||||||
"cancel" : "Abbrechen",
|
"cancel": "Abbrechen",
|
||||||
"add" : "Hinzufügen",
|
"add": "Hinzufügen",
|
||||||
"income": "Einnahmen",
|
"income": "Einnahmen",
|
||||||
"expenditures": "Ausgaben",
|
"expenditures": "Ausgaben",
|
||||||
"addtrans": "Transaktion hinzufügen",
|
"addtrans": "Transaktion hinzufügen",
|
||||||
|
@ -24,5 +24,23 @@
|
||||||
"budget": "Budgetcheck",
|
"budget": "Budgetcheck",
|
||||||
"progress": "von deinem Budget ausgegeben",
|
"progress": "von deinem Budget ausgegeben",
|
||||||
"monthlyexpenses": "Monatliche Ausgaben",
|
"monthlyexpenses": "Monatliche Ausgaben",
|
||||||
"close": "Schließen"
|
"close": "Schließen",
|
||||||
|
"tip1": "Spare jeden Monat einen festen Betrag.",
|
||||||
|
"tip2": "Vergleiche Preise, bevor du etwas kaufst.",
|
||||||
|
"tip3": "Vermeide unnötige Ausgaben.",
|
||||||
|
"tip4": "Setze dir konkrete Sparziele.",
|
||||||
|
"tip5": "Überprüfe regelmäßig deine Ausgaben.",
|
||||||
|
"tip6": "Verkaufe Dinge, die du nicht mehr brauchst.",
|
||||||
|
"tip7": "Nutze Cashback-Programme beim Einkaufen.",
|
||||||
|
"tip8": "Koche selbst anstatt auswärts zu essen.",
|
||||||
|
"tip9": "Nutze kostenlose Angebote und Gutscheine.",
|
||||||
|
"tip10": "Vermeide Impulskäufe und schlafe vor größeren Ausgaben eine Nacht darüber.",
|
||||||
|
"tip11": "Fahre mit dem Fahrrad oder öffentlichen Verkehrsmitteln anstatt mit dem Auto.",
|
||||||
|
"tip12": "Plane deine Mahlzeiten im Voraus, um Lebensmittelverschwendung zu vermeiden.",
|
||||||
|
"tip13": "Vergleiche Versicherungen und Verträge, um Geld zu sparen.",
|
||||||
|
"tip14": "Mache deine eigenen Reinigungsmittel statt teure Produkte zu kaufen.",
|
||||||
|
"tip15": "Nutze kostenlose Online-Ressourcen für Weiterbildung und Hobbys.",
|
||||||
|
"hint": "Spartipps gefällig? \nDrücke auf den Info-Button",
|
||||||
|
"budgetmax": "Budget verbraucht!",
|
||||||
|
"enterbudget": "Budget eingeben"
|
||||||
}
|
}
|
|
@ -1,15 +1,15 @@
|
||||||
{
|
{
|
||||||
"title" : "My Finance Planner",
|
"title": "My Finance Planner",
|
||||||
"delete" : "Delete",
|
"delete": "Delete",
|
||||||
"deleteaccount" : "Delete account",
|
"deleteaccount": "Delete account",
|
||||||
"sure" : "Are you sure you want to delete this account?",
|
"sure": "Are you sure you want to delete this account?",
|
||||||
"balance" : "Balance",
|
"balance": "Balance",
|
||||||
"addaccount" : "Add account",
|
"addaccount": "Add account",
|
||||||
"entername" : "Please enter a name",
|
"entername": "Please enter a name",
|
||||||
"enterbalance" : "Please enter a balance",
|
"enterbalance": "Please enter a balance",
|
||||||
"entervalidnumber" : "Please enter a valid number",
|
"entervalidnumber": "Please enter a valid number",
|
||||||
"cancel" : "Cancel",
|
"cancel": "Cancel",
|
||||||
"add" : "Add",
|
"add": "Add",
|
||||||
"income": "Income",
|
"income": "Income",
|
||||||
"expenditures": "Expenses",
|
"expenditures": "Expenses",
|
||||||
"addtrans": "Add transaction",
|
"addtrans": "Add transaction",
|
||||||
|
@ -24,5 +24,23 @@
|
||||||
"budget": "Budget check",
|
"budget": "Budget check",
|
||||||
"progress": "of your budget spent",
|
"progress": "of your budget spent",
|
||||||
"monthlyexpenses": "Monthly Expenses",
|
"monthlyexpenses": "Monthly Expenses",
|
||||||
"close": "Close"
|
"close": "Close",
|
||||||
|
"tip1":"Save a fixed amount every month",
|
||||||
|
"tip2":"Compare prices before you buy anything",
|
||||||
|
"tip3":"Avoid unnecessary spending.",
|
||||||
|
"tip4":"Set specific savings goals.",
|
||||||
|
"tip5":"Review your spending regularly.",
|
||||||
|
"tip6":"Sell things you no longer need",
|
||||||
|
"tip7":"Take advantage of cash-back programs when shopping.",
|
||||||
|
"tip8":"Cook for yourself instead of eating out.",
|
||||||
|
"tip9":"Take advantage of free offers and coupons.",
|
||||||
|
"tip10":"Avoid impulse buys and sleep on it before spending big.",
|
||||||
|
"tip11":"Ride a bike or take public transportation instead of driving.",
|
||||||
|
"tip12":"Plan your meals ahead of time to avoid food waste.",
|
||||||
|
"tip13":"Compare insurance policies and contracts to save money.",
|
||||||
|
"tip14":"Make your own cleaning supplies instead of buying expensive products.",
|
||||||
|
"tip15":"Use free online resources for continuing education and hobbies.",
|
||||||
|
"hint": "Need saving tips? \nPress the info button",
|
||||||
|
"budgetmax": "Budget spent!",
|
||||||
|
"enterbudget": "Enter budget"
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||||
|
import 'package:tests/theme/theme_constants.dart';
|
||||||
import 'expense_data.dart';
|
import 'expense_data.dart';
|
||||||
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
||||||
|
|
||||||
|
@ -16,13 +17,22 @@ class MonthlyExpensesChart extends StatelessWidget {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
shape: NeumorphicShape.flat,
|
shape: NeumorphicShape.flat,
|
||||||
depth: 8,
|
depth: 8,
|
||||||
intensity: 0.6,
|
intensity: 0.7,
|
||||||
surfaceIntensity: 0.25,
|
surfaceIntensity: 0.25,
|
||||||
shadowLightColor: Colors.white,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
shadowDarkColor: Colors.black87,
|
? const NeumorphicStyle().shadowLightColor
|
||||||
color: Colors.grey[100],
|
: grey600,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
),
|
),
|
||||||
child: SfCartesianChart(
|
child: SfCartesianChart(
|
||||||
|
backgroundColor: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey700,
|
||||||
primaryXAxis: CategoryAxis(),
|
primaryXAxis: CategoryAxis(),
|
||||||
series: _buildChartSeries(),
|
series: _buildChartSeries(),
|
||||||
tooltipBehavior: TooltipBehavior(enable: true),
|
tooltipBehavior: TooltipBehavior(enable: true),
|
||||||
|
@ -51,4 +61,4 @@ class MonthlyExpensesChart extends StatelessWidget {
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
244
lib/main.dart
244
lib/main.dart
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||||
import 'package:awesome_dialog/awesome_dialog.dart';
|
import 'package:awesome_dialog/awesome_dialog.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tests/preferences.dart';
|
import 'package:tests/preferences.dart';
|
||||||
import 'package:tests/theme/theme_constants.dart';
|
import 'package:tests/theme/theme_constants.dart';
|
||||||
|
@ -15,14 +16,16 @@ Future<void> main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await EasyLocalization.ensureInitialized();
|
await EasyLocalization.ensureInitialized();
|
||||||
runApp(
|
runApp(
|
||||||
EasyLocalization(
|
ChangeNotifierProvider(
|
||||||
supportedLocales: const [Locale('en', 'US'), Locale('de', 'DE')],
|
create: (context) => ThemeManager(),
|
||||||
path: 'lib/assets/translations',
|
child: EasyLocalization(
|
||||||
// <-- change the path of the translation files
|
supportedLocales: const [Locale('en', 'US'), Locale('de', 'DE')],
|
||||||
fallbackLocale: const Locale('en', 'US'),
|
path: 'lib/assets/translations',
|
||||||
child: const FinancialPlannerApp()),
|
// <-- change the path of the translation files
|
||||||
);
|
fallbackLocale: const Locale('en', 'US'),
|
||||||
}
|
child: const FinancialPlannerApp()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
ThemeManager _themeManager = ThemeManager();
|
ThemeManager _themeManager = ThemeManager();
|
||||||
|
|
||||||
|
@ -31,7 +34,8 @@ class FinancialPlannerApp extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
SystemChrome.setEnabledSystemUIMode(
|
||||||
|
SystemUiMode.manual, overlays: [SystemUiOverlay.top]);
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
localizationsDelegates: context.localizationDelegates,
|
localizationsDelegates: context.localizationDelegates,
|
||||||
supportedLocales: context.supportedLocales,
|
supportedLocales: context.supportedLocales,
|
||||||
|
@ -40,7 +44,7 @@ class FinancialPlannerApp extends StatelessWidget {
|
||||||
title: 'title'.tr(),
|
title: 'title'.tr(),
|
||||||
theme: lightTheme,
|
theme: lightTheme,
|
||||||
darkTheme: darkTheme,
|
darkTheme: darkTheme,
|
||||||
themeMode: _themeManager.themeMode,
|
themeMode: Provider.of<ThemeManager>(context).themeMode,
|
||||||
home: const HomePage(),
|
home: const HomePage(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -55,18 +59,18 @@ class HomePage extends StatefulWidget {
|
||||||
|
|
||||||
class HomePageState extends State<HomePage> {
|
class HomePageState extends State<HomePage> {
|
||||||
List<Account> accounts = [];
|
List<Account> accounts = [];
|
||||||
String _selectedCurrency="€";
|
String _selectedCurrency = "€";
|
||||||
|
|
||||||
Future<String> getCurrencyFromSharedPreferences(String key) async {
|
Future<String> getCurrencyFromSharedPreferences(String key) async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
if (prefs.getString(key)=="Euro"){
|
if (prefs.getString(key) == "Euro") {
|
||||||
_selectedCurrency="€";
|
_selectedCurrency = "€";
|
||||||
}
|
}
|
||||||
if (prefs.getString(key)=="Dollar"){
|
if (prefs.getString(key) == "Dollar") {
|
||||||
_selectedCurrency=r"$";
|
_selectedCurrency = r"$";
|
||||||
}
|
}
|
||||||
if (prefs.getString(key)=="CHF"){
|
if (prefs.getString(key) == "CHF") {
|
||||||
_selectedCurrency="CHF";
|
_selectedCurrency = "CHF";
|
||||||
}
|
}
|
||||||
|
|
||||||
return prefs.getString(key) ?? 'Euro';
|
return prefs.getString(key) ?? 'Euro';
|
||||||
|
@ -77,9 +81,7 @@ class HomePageState extends State<HomePage> {
|
||||||
super.initState();
|
super.initState();
|
||||||
_themeManager.addListener(themeListener);
|
_themeManager.addListener(themeListener);
|
||||||
getCurrencyFromSharedPreferences("currency").then((value) {
|
getCurrencyFromSharedPreferences("currency").then((value) {
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
loadAccounts();
|
loadAccounts();
|
||||||
}
|
}
|
||||||
|
@ -110,7 +112,7 @@ class HomePageState extends State<HomePage> {
|
||||||
Future<void> saveAccounts() async {
|
Future<void> saveAccounts() async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
List<String> accountJsonList =
|
List<String> accountJsonList =
|
||||||
accounts.map((account) => json.encode(account.toJson())).toList();
|
accounts.map((account) => json.encode(account.toJson())).toList();
|
||||||
await prefs.setStringList('accounts', accountJsonList);
|
await prefs.setStringList('accounts', accountJsonList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,26 +136,35 @@ class HomePageState extends State<HomePage> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> saveCurrencyToSharedPreferences(String key, String value) async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setString(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
toolbarHeight: 70,
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
title: Text(
|
title: Text(
|
||||||
'title'.tr(),
|
'title'.tr(),
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.black54,
|
color: Theme
|
||||||
),
|
.of(context)
|
||||||
|
.brightness == Brightness.dark
|
||||||
|
? Colors.white70
|
||||||
|
: Colors.black87),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 16.0, top: 2, bottom: 0),
|
padding: const EdgeInsets.only(right: 16.0, top: 9, bottom: 0),
|
||||||
child: NeumorphicButton(
|
child: NeumorphicButton(
|
||||||
margin: EdgeInsets.only(bottom: 10),
|
margin: const EdgeInsets.only(bottom: 16),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Navigator.push(
|
await Navigator.push(
|
||||||
context,
|
context,
|
||||||
|
@ -164,67 +175,111 @@ class HomePageState extends State<HomePage> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
shape: NeumorphicShape.convex,
|
shape: NeumorphicShape.convex,
|
||||||
boxShape: const NeumorphicBoxShape.circle(),
|
boxShape: const NeumorphicBoxShape.circle(),
|
||||||
depth: 6,
|
depth: 8,
|
||||||
intensity: 0.9,
|
intensity: 0.9,
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor:
|
||||||
|
Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme
|
||||||
|
.of(context)
|
||||||
|
.shadowColor,
|
||||||
|
shadowDarkColor:
|
||||||
|
Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
),
|
),
|
||||||
child: const Icon(Icons.settings, color: Colors.black38),
|
child: Icon(Icons.settings,
|
||||||
|
color: Theme
|
||||||
|
.of(context)
|
||||||
|
.unselectedWidgetColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: ListView.builder(
|
body: Padding(
|
||||||
physics: const BouncingScrollPhysics(),
|
padding: const EdgeInsets.only(top: 5),
|
||||||
itemCount: accounts.length,
|
child: ListView.builder(
|
||||||
itemBuilder: (context, index) {
|
physics: const BouncingScrollPhysics(),
|
||||||
return GestureDetector(
|
itemCount: accounts.length,
|
||||||
onLongPress: () {
|
itemBuilder: (context, index) {
|
||||||
AwesomeDialog(
|
return GestureDetector(
|
||||||
btnOkText: "Delete".tr(),
|
onLongPress: () {
|
||||||
btnOkColor: Colors.lightGreen,
|
AwesomeDialog(
|
||||||
btnCancelColor: Colors.grey,
|
btnOkText: "Delete".tr(),
|
||||||
context: context,
|
btnOkColor: Colors.lightGreen,
|
||||||
animType: AnimType.bottomSlide,
|
btnCancelColor: Theme
|
||||||
dialogType: DialogType.info,
|
.of(context)
|
||||||
title: 'deleteaccount'.tr(),
|
.shadowColor,
|
||||||
headerAnimationLoop: false,
|
context: context,
|
||||||
desc: 'sure'.tr(),
|
animType: AnimType.bottomSlide,
|
||||||
btnCancelOnPress: () {},
|
dialogType: DialogType.info,
|
||||||
btnOkOnPress: () {
|
title: 'deleteaccount'.tr(),
|
||||||
deleteAccount(accounts[index]);
|
headerAnimationLoop: false,
|
||||||
|
desc: 'sure'.tr(),
|
||||||
|
btnCancelOnPress: () {},
|
||||||
|
btnOkOnPress: () {
|
||||||
|
deleteAccount(accounts[index]);
|
||||||
|
},
|
||||||
|
).show();
|
||||||
},
|
},
|
||||||
).show();
|
child: Neumorphic(
|
||||||
},
|
margin: const EdgeInsets.all(16),
|
||||||
child: Neumorphic(
|
style: NeumorphicStyle(
|
||||||
margin: const EdgeInsets.all(16),
|
depth: 8,
|
||||||
style: NeumorphicStyle(
|
intensity: 1,
|
||||||
depth: 7,
|
shadowLightColor:
|
||||||
intensity: 1,
|
Theme
|
||||||
shadowDarkColor: Colors.grey.shade300,
|
.of(context)
|
||||||
color: Colors.grey.shade100,
|
.brightness == Brightness.light
|
||||||
boxShape:
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: grey800,
|
||||||
|
shadowDarkColor:
|
||||||
|
Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: Theme
|
||||||
|
.of(context)
|
||||||
|
.shadowColor,
|
||||||
|
color: Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
|
boxShape:
|
||||||
NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
|
NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
|
||||||
),
|
),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text(accounts[index].name),
|
title: Text(accounts[index].name),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'${'balance'.tr()}: $_selectedCurrency${accounts[index].balance.toStringAsFixed(2)}'),
|
'${'balance'.tr()}: $_selectedCurrency${accounts[index]
|
||||||
onTap: () {
|
.balance.toStringAsFixed(2)}'),
|
||||||
Navigator.push(
|
onTap: () {
|
||||||
context,
|
Navigator.push(
|
||||||
MaterialPageRoute(
|
context,
|
||||||
builder: (context) => AccountDetailPage(
|
MaterialPageRoute(
|
||||||
account: accounts[index],
|
builder: (context) =>
|
||||||
updateAccountBalance: updateAccountBalance,
|
AccountDetailPage(
|
||||||
),
|
account: accounts[index],
|
||||||
),
|
updateAccountBalance: updateAccountBalance,
|
||||||
);
|
),
|
||||||
},
|
),
|
||||||
),
|
);
|
||||||
),
|
},
|
||||||
);
|
),
|
||||||
},
|
),
|
||||||
),
|
);
|
||||||
|
},
|
||||||
|
)),
|
||||||
floatingActionButton: NeumorphicButton(
|
floatingActionButton: NeumorphicButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
@ -239,14 +294,33 @@ class HomePageState extends State<HomePage> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: 8,
|
depth: 8,
|
||||||
intensity: 1,
|
intensity: 1,
|
||||||
shadowDarkColor: Colors.grey.shade400,
|
shadowLightColor: Theme
|
||||||
color: Colors.grey.shade100,
|
.of(context)
|
||||||
|
.brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme
|
||||||
|
.of(context)
|
||||||
|
.shadowColor,
|
||||||
|
shadowDarkColor: Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: const NeumorphicBoxShape.circle(),
|
boxShape: const NeumorphicBoxShape.circle(),
|
||||||
),
|
),
|
||||||
child: const Icon(
|
child: Icon(
|
||||||
Icons.add,
|
Icons.add,
|
||||||
size: 60,
|
size: 60,
|
||||||
color: Colors.black12,
|
color: Theme
|
||||||
|
.of(context)
|
||||||
|
.brightness == Brightness.light
|
||||||
|
? Colors.black12
|
||||||
|
: Colors.white12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:tests/theme/theme_constants.dart';
|
||||||
import 'package:tests/theme/theme_manager.dart';
|
import 'package:tests/theme/theme_manager.dart';
|
||||||
|
|
||||||
import 'main.dart';
|
import 'main.dart';
|
||||||
|
|
||||||
ThemeManager _themeManager = ThemeManager();
|
ThemeManager _themeManager = ThemeManager();
|
||||||
|
@ -50,6 +50,11 @@ class SettingsState extends State<Settings> {
|
||||||
await prefs.setString(key, value);
|
await prefs.setString(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> saveThemeToSharedPreferences(String key, bool value) async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setBool(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> getCurrencyFromSharedPreferences(String key) async {
|
Future<String> getCurrencyFromSharedPreferences(String key) async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
return prefs.getString(key) ?? 'Euro';
|
return prefs.getString(key) ?? 'Euro';
|
||||||
|
@ -84,11 +89,12 @@ class SettingsState extends State<Settings> {
|
||||||
toolbarHeight: 80,
|
toolbarHeight: 80,
|
||||||
title: Text(
|
title: Text(
|
||||||
'settings'.tr(),
|
'settings'.tr(),
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.black54,
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
),
|
? Colors.white70
|
||||||
|
: Colors.black87),
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
|
@ -97,13 +103,14 @@ class SettingsState extends State<Settings> {
|
||||||
bottomRight: Radius.circular(15),
|
bottomRight: Radius.circular(15),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
shadowColor: Colors.grey.shade300,
|
shadowColor: Theme.of(context).shadowColor,
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
padding: const EdgeInsets.only(left: 16.0),
|
padding: const EdgeInsets.only(left: 16.0),
|
||||||
child: NeumorphicButton(
|
child: NeumorphicButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context); // Zurück zur vorherigen Seite
|
Navigator.pop(context); // Zurück zur vorherigen Seite
|
||||||
Navigator.pushReplacement( // Neue Seite öffnen und vorherige Seite ersetzen
|
Navigator.pushReplacement(
|
||||||
|
// Neue Seite öffnen und vorherige Seite ersetzen
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => const HomePage()),
|
MaterialPageRoute(builder: (context) => const HomePage()),
|
||||||
);
|
);
|
||||||
|
@ -111,12 +118,21 @@ class SettingsState extends State<Settings> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
shape: NeumorphicShape.flat,
|
shape: NeumorphicShape.flat,
|
||||||
boxShape: const NeumorphicBoxShape.circle(),
|
boxShape: const NeumorphicBoxShape.circle(),
|
||||||
depth: 6,
|
depth: 7,
|
||||||
intensity: 0.9,
|
intensity: 0.9,
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(8),
|
||||||
child: const Icon(Icons.arrow_back, color: Colors.black38),
|
child: Icon(Icons.arrow_back,
|
||||||
|
color: Theme.of(context).unselectedWidgetColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -127,38 +143,57 @@ class SettingsState extends State<Settings> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: 7,
|
depth: 7,
|
||||||
intensity: 1,
|
intensity: 1,
|
||||||
shadowDarkColor: Colors.grey.shade300,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
color: Colors.grey.shade100,
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: grey800,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
|
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
|
||||||
),
|
),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text('darkmode'.tr()),
|
title: Text('darkmode'.tr()),
|
||||||
trailing: NeumorphicSwitch(
|
trailing:
|
||||||
value: _themeManager.themeMode == ThemeMode.dark,
|
Consumer<ThemeManager>(builder: (context, themeManager, _) {
|
||||||
onChanged: (bool value) {
|
return NeumorphicSwitch(
|
||||||
setState(() {
|
value: themeManager.themeMode == ThemeMode.dark,
|
||||||
_themeManager.toggleTheme(value);
|
onChanged: (bool value) {
|
||||||
});
|
setState(() {
|
||||||
},
|
themeManager.toggleTheme(value);
|
||||||
style: NeumorphicSwitchStyle(
|
});
|
||||||
lightSource: LightSource.topLeft,
|
},
|
||||||
thumbShape: NeumorphicShape.concave,
|
style: NeumorphicSwitchStyle(
|
||||||
trackDepth: 5,
|
lightSource: LightSource.topLeft,
|
||||||
activeTrackColor: Colors.lightGreen,
|
thumbShape: NeumorphicShape.concave,
|
||||||
inactiveTrackColor: Colors.grey.shade300,
|
trackDepth: 5,
|
||||||
activeThumbColor: Colors.grey.shade100,
|
activeTrackColor: Colors.lightGreen,
|
||||||
inactiveThumbColor: Colors.grey.shade200,
|
inactiveTrackColor: Theme.of(context).shadowColor,
|
||||||
),
|
activeThumbColor:
|
||||||
),
|
Theme.of(context).brightness == Brightness.light
|
||||||
),
|
? grey200
|
||||||
|
: grey800,
|
||||||
|
inactiveThumbColor: Theme.of(context).shadowColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Neumorphic(
|
Neumorphic(
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: 7,
|
depth: 7,
|
||||||
intensity: 1,
|
intensity: 1,
|
||||||
shadowDarkColor: Colors.grey.shade300,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
color: Colors.grey.shade100,
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: grey800,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
|
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
|
||||||
),
|
),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
|
@ -196,8 +231,15 @@ class SettingsState extends State<Settings> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: 7,
|
depth: 7,
|
||||||
intensity: 1,
|
intensity: 1,
|
||||||
shadowDarkColor: Colors.grey.shade300,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
color: Colors.grey.shade100,
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: grey800,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
|
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
|
||||||
),
|
),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
|
@ -211,10 +253,12 @@ class SettingsState extends State<Settings> {
|
||||||
onChanged: (String? newValue) {
|
onChanged: (String? newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectedCurrency = newValue!;
|
_selectedCurrency = newValue!;
|
||||||
saveCurrencyToSharedPreferences("currency", _selectedCurrency);
|
saveCurrencyToSharedPreferences(
|
||||||
|
"currency", _selectedCurrency);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
items: _currencies.map<DropdownMenuItem<String>>((String value) {
|
items:
|
||||||
|
_currencies.map<DropdownMenuItem<String>>((String value) {
|
||||||
return DropdownMenuItem<String>(
|
return DropdownMenuItem<String>(
|
||||||
value: value,
|
value: value,
|
||||||
child: Text(value),
|
child: Text(value),
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
import 'package:carousel_slider/carousel_slider.dart';
|
import 'package:carousel_slider/carousel_slider.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
||||||
|
import 'package:tests/theme/theme_constants.dart';
|
||||||
|
|
||||||
class SavingsTipsDialog extends StatelessWidget {
|
class SavingsTipsDialog extends StatelessWidget {
|
||||||
final List<String> savingsTips = [
|
final List<String> savingsTips = [
|
||||||
'Spare jeden Monat einen festen Betrag.',
|
'tip1'.tr(),
|
||||||
'Vergleiche Preise, bevor du etwas kaufst.',
|
'tip2'.tr(),
|
||||||
'Vermeide unnötige Ausgaben.',
|
'tip3'.tr(),
|
||||||
'Setze dir konkrete Sparziele.',
|
'tip4'.tr(),
|
||||||
'Überprüfe regelmäßig deine Ausgaben.',
|
'tip5'.tr(),
|
||||||
'Verkaufe Dinge, die du nicht mehr brauchst.',
|
'tip6'.tr(),
|
||||||
'Nutze Cashback-Programme beim Einkaufen.',
|
'tip7'.tr(),
|
||||||
'Koche selbst anstatt auswärts zu essen.',
|
'tip8'.tr(),
|
||||||
'Nutze kostenlose Angebote und Gutscheine.',
|
'tip9'.tr(),
|
||||||
'Vermeide Impulskäufe und schlafe vor größeren Ausgaben eine Nacht darüber.',
|
'tip10'.tr(),
|
||||||
'Fahre mit dem Fahrrad oder öffentlichen Verkehrsmitteln anstatt mit dem Auto.',
|
'tip11'.tr(),
|
||||||
'Plane deine Mahlzeiten im Voraus, um Lebensmittelverschwendung zu vermeiden.',
|
'tip12'.tr(),
|
||||||
'Vergleiche Versicherungen und Verträge, um Geld zu sparen.',
|
'tip13'.tr(),
|
||||||
'Mache deine eigenen Reinigungsmittel statt teure Produkte zu kaufen.',
|
'tip14'.tr(),
|
||||||
'Nutze kostenlose Online-Ressourcen für Weiterbildung und Hobbys.',
|
'tip15'.tr(),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
SavingsTipsDialog({super.key});
|
SavingsTipsDialog({super.key});
|
||||||
|
@ -38,30 +40,40 @@ class SavingsTipsDialog extends StatelessWidget {
|
||||||
itemCount: savingsTips.length,
|
itemCount: savingsTips.length,
|
||||||
itemBuilder: (BuildContext context, int index, int realIndex) {
|
itemBuilder: (BuildContext context, int index, int realIndex) {
|
||||||
return Neumorphic(
|
return Neumorphic(
|
||||||
margin: const EdgeInsets.only(bottom: 5),
|
margin: const EdgeInsets.fromLTRB(0, 11, 0, 7),
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
shadowLightColor:
|
||||||
BorderRadius.circular(13.0)),
|
Theme.of(context).brightness == Brightness.light
|
||||||
),
|
? const NeumorphicStyle().shadowLightColor
|
||||||
child: Container(
|
: Theme.of(context).shadowColor,
|
||||||
decoration: BoxDecoration(
|
shadowDarkColor:
|
||||||
|
Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
|
BorderRadius.circular(13.0)),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
color: Colors.grey
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
.shade100, // Setze die Hintergrundfarbe auf rot
|
? grey700
|
||||||
),
|
: grey200),
|
||||||
padding: const EdgeInsets.all(14.0),
|
padding: const EdgeInsets.all(14.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
savingsTips[index],
|
savingsTips[index],
|
||||||
style: const TextStyle(fontSize: 18.0),
|
style: const TextStyle(fontSize: 18.0),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
options: CarouselOptions(
|
options: CarouselOptions(
|
||||||
|
@ -83,14 +95,26 @@ class SavingsTipsDialog extends StatelessWidget {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
depth: 10,
|
depth: 10,
|
||||||
intensity: 0.9,
|
intensity: 0.9,
|
||||||
shape: NeumorphicShape.flat,
|
shape: NeumorphicShape.flat,
|
||||||
boxShape:
|
boxShape:
|
||||||
NeumorphicBoxShape.roundRect(BorderRadius.circular(15.0)),
|
NeumorphicBoxShape.roundRect(BorderRadius.circular(15.0)),
|
||||||
),
|
),
|
||||||
child: Text('close'.tr()),
|
child: Text(
|
||||||
|
'close'.tr(),
|
||||||
|
style: TextStyle(color: Theme.of(context).cardColor),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,17 +1,66 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
const COLOR_PRIMARY = Colors.deepOrangeAccent;
|
final grey200=Colors.grey[200];
|
||||||
|
final grey300=Colors.grey[300];
|
||||||
ThemeData lightTheme = ThemeData(
|
final grey400=Colors.grey[400];
|
||||||
brightness: Brightness.light,
|
final grey700=Colors.grey[700];
|
||||||
primaryColor: COLOR_PRIMARY,
|
final grey800=Colors.grey[800];
|
||||||
fontFamily: "Montserrat");
|
final grey600=Colors.grey[600];
|
||||||
|
final ThemeData lightTheme = ThemeData(
|
||||||
ThemeData darkTheme = ThemeData(
|
scaffoldBackgroundColor: Colors.grey[100],
|
||||||
fontFamily: "Montserrat",
|
textTheme: const TextTheme(
|
||||||
brightness: Brightness.dark,
|
displayLarge:(TextStyle(color: Colors.black87)),
|
||||||
switchTheme: SwitchThemeData(
|
displayMedium: (TextStyle(color: Colors.black87)),
|
||||||
trackColor: MaterialStateProperty.all<Color>(Colors.grey),
|
displaySmall:(TextStyle(color: Colors.black87)),
|
||||||
thumbColor: MaterialStateProperty.all<Color>(Colors.white),
|
labelLarge:(TextStyle(color: Colors.black87)),
|
||||||
|
labelMedium:(TextStyle(color: Colors.black87)),
|
||||||
|
labelSmall:(TextStyle(color: Colors.black87)),
|
||||||
|
headlineLarge:(TextStyle(color: Colors.black87)),
|
||||||
|
headlineMedium:(TextStyle(color: Colors.black87)),
|
||||||
|
headlineSmall:(TextStyle(color: Colors.black87)),
|
||||||
|
titleLarge:(TextStyle(color: Colors.black87)),
|
||||||
|
titleMedium:(TextStyle(color: Colors.black87)),
|
||||||
|
titleSmall:(TextStyle(color: Colors.black87)),
|
||||||
|
bodyLarge: (TextStyle(color: Colors.black54)),
|
||||||
|
bodyMedium:(TextStyle(color: Colors.black54)),
|
||||||
|
bodySmall: (TextStyle(color: Colors.black54))
|
||||||
),
|
),
|
||||||
|
brightness: Brightness.light,
|
||||||
|
shadowColor: Colors.grey[300],
|
||||||
|
cardColor: Colors.black87,
|
||||||
|
unselectedWidgetColor: Colors.black54,
|
||||||
|
fontFamily: "Montserrat",
|
||||||
|
buttonTheme: ButtonThemeData(
|
||||||
|
buttonColor: Colors.grey[100],
|
||||||
|
textTheme: ButtonTextTheme.primary
|
||||||
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final ThemeData darkTheme = ThemeData(
|
||||||
|
textTheme: const TextTheme(
|
||||||
|
displayLarge:(TextStyle(color: Colors.white70)),
|
||||||
|
displayMedium: (TextStyle(color: Colors.white70)),
|
||||||
|
displaySmall:(TextStyle(color: Colors.white70)),
|
||||||
|
labelLarge:(TextStyle(color: Colors.white70)),
|
||||||
|
labelMedium:(TextStyle(color: Colors.white70)),
|
||||||
|
labelSmall:(TextStyle(color: Colors.white70)),
|
||||||
|
headlineLarge:(TextStyle(color: Colors.white70)),
|
||||||
|
headlineMedium:(TextStyle(color: Colors.white70)),
|
||||||
|
headlineSmall:(TextStyle(color: Colors.white70)),
|
||||||
|
titleLarge:(TextStyle(color: Colors.white70)),
|
||||||
|
titleMedium:(TextStyle(color: Colors.white70)),
|
||||||
|
titleSmall:(TextStyle(color: Colors.white70)),
|
||||||
|
bodyLarge: (TextStyle(color: Colors.white54)),
|
||||||
|
bodyMedium:(TextStyle(color: Colors.white54)),
|
||||||
|
bodySmall: (TextStyle(color: Colors.white54)),
|
||||||
|
),
|
||||||
|
shadowColor: Colors.grey[700],
|
||||||
|
fontFamily: "Montserrat",
|
||||||
|
cardColor: Colors.white70,
|
||||||
|
unselectedWidgetColor: Colors.white54,
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
buttonTheme: ButtonThemeData(
|
||||||
|
buttonColor: Colors.grey[900],
|
||||||
|
),
|
||||||
|
);
|
|
@ -1,14 +1,13 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ThemeManager with ChangeNotifier{
|
class ThemeManager with ChangeNotifier {
|
||||||
|
|
||||||
ThemeMode _themeMode = ThemeMode.light;
|
ThemeMode _themeMode = ThemeMode.light;
|
||||||
|
|
||||||
get themeMode => _themeMode;
|
ThemeMode get themeMode => _themeMode;
|
||||||
|
|
||||||
toggleTheme(bool isDark){
|
void toggleTheme(bool isDark) {
|
||||||
_themeMode = isDark?ThemeMode.dark:ThemeMode.light;
|
_themeMode = isDark ? ThemeMode.dark : ThemeMode.light;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
|
||||||
import 'package:tests/transaction/transaction.dart';
|
import 'package:tests/transaction/transaction.dart';
|
||||||
|
import '../theme/theme_constants.dart';
|
||||||
|
|
||||||
class AddTransactionDialog extends StatefulWidget {
|
class AddTransactionDialog extends StatefulWidget {
|
||||||
final Function addTransaction;
|
final Function addTransaction;
|
||||||
|
|
||||||
const AddTransactionDialog({super.key, required this.addTransaction});
|
const AddTransactionDialog({super.key, required this.addTransaction});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -48,11 +50,10 @@ class AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||||
'addtrans'.tr(),
|
'addtrans'.tr(),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Colors.black54,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
content: Form(
|
content: Form(
|
||||||
key: _formKey, // Hier wird das _formKey dem Form-Widget zugewiesen
|
key: _formKey, //
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
@ -60,7 +61,17 @@ class AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: -5,
|
depth: -5,
|
||||||
intensity: 0.8,
|
intensity: 0.8,
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor:
|
||||||
|
Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
|
@ -88,7 +99,17 @@ class AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
depth: -5,
|
depth: -5,
|
||||||
intensity: 0.8,
|
intensity: 0.8,
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor:
|
||||||
|
Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
|
@ -121,7 +142,10 @@ class AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||||
NeumorphicCheckbox(
|
NeumorphicCheckbox(
|
||||||
style: NeumorphicCheckboxStyle(
|
style: NeumorphicCheckboxStyle(
|
||||||
selectedColor: Colors.lightGreen,
|
selectedColor: Colors.lightGreen,
|
||||||
disabledColor: Colors.grey.shade200,
|
disabledColor:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
selectedDepth: -10,
|
selectedDepth: -10,
|
||||||
unselectedDepth: 8),
|
unselectedDepth: 8),
|
||||||
value: _isExpense,
|
value: _isExpense,
|
||||||
|
@ -134,7 +158,6 @@ class AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
'expense'.tr(),
|
'expense'.tr(),
|
||||||
style: const TextStyle(color: Colors.black87),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -152,7 +175,15 @@ class AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
|
@ -164,6 +195,7 @@ class AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
NeumorphicButton(
|
NeumorphicButton(
|
||||||
|
margin: const EdgeInsets.fromLTRB(0, 0, 4, 4),
|
||||||
onPressed: _submitForm,
|
onPressed: _submitForm,
|
||||||
style: NeumorphicStyle(
|
style: NeumorphicStyle(
|
||||||
shape: NeumorphicShape.concave,
|
shape: NeumorphicShape.concave,
|
||||||
|
@ -172,7 +204,15 @@ class AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||||
boxShape: NeumorphicBoxShape.roundRect(
|
boxShape: NeumorphicBoxShape.roundRect(
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
color: Colors.grey.shade100,
|
shadowLightColor: Theme.of(context).brightness == Brightness.light
|
||||||
|
? const NeumorphicStyle().shadowLightColor
|
||||||
|
: Theme.of(context).shadowColor,
|
||||||
|
shadowDarkColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? const NeumorphicStyle().shadowDarkColor
|
||||||
|
: grey400,
|
||||||
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? grey200
|
||||||
|
: grey800,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
16
pubspec.lock
16
pubspec.lock
|
@ -261,6 +261,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0"
|
version: "1.8.0"
|
||||||
|
nested:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: nested
|
||||||
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -333,6 +341,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.4"
|
version: "4.2.4"
|
||||||
|
provider:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: provider
|
||||||
|
sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.5"
|
||||||
rive:
|
rive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -44,6 +44,7 @@ dependencies:
|
||||||
flutter_svg: ^2.0.0
|
flutter_svg: ^2.0.0
|
||||||
circular_seek_bar: ^1.1.0
|
circular_seek_bar: ^1.1.0
|
||||||
tab_indicator_styler: ^2.0.0
|
tab_indicator_styler: ^2.0.0
|
||||||
|
provider: ^6.0.5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in New Issue