From b3bee796ef557880ba1c2a5eeefab213bb29e844 Mon Sep 17 00:00:00 2001 From: xMadKing Date: Mon, 18 Dec 2023 16:24:08 +0100 Subject: [PATCH] Fixed up addexpense page and there's a customtextfield widget now --- lib/pages/addexpense.dart | 377 +++++++++++++++++++++++-------- lib/pages/registerpage.dart | 12 +- lib/widgets/customtextfield.dart | 78 +++++++ lib/widgets/navbar.dart | 2 +- 4 files changed, 367 insertions(+), 102 deletions(-) create mode 100644 lib/widgets/customtextfield.dart diff --git a/lib/pages/addexpense.dart b/lib/pages/addexpense.dart index d37914e..524e267 100644 --- a/lib/pages/addexpense.dart +++ b/lib/pages/addexpense.dart @@ -1,125 +1,312 @@ import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; +import 'package:smartspend/widgets/customtextfield.dart'; +import 'package:smartspend/backend/wyrm/database.dart'; +import 'package:smartspend/backend/category.dart'; class AddExpensePage extends StatefulWidget { - const AddExpensePage({super.key}); + List controllers = [ + TextEditingController(), + TextEditingController(), + TextEditingController(), + TextEditingController() + ]; + + AddExpensePage({super.key}); @override _AddExpensePageState createState() => _AddExpensePageState(); } class _AddExpensePageState extends State { - double _amount = 50.00; // Assuming a default or last entered amount - String _selectedCategory = 'Food'; - DateTime _selectedDate = DateTime.now(); - final TextEditingController _descriptionController = TextEditingController(); + late List categories; + late Category selectedCategory; + Wyrm database = Wyrm(); + bool _loading = true; + bool expenseAdded = false; + bool selectingCategory = false; - Future _selectDate(BuildContext context) async { - final DateTime? picked = await showDatePicker( - context: context, - initialDate: _selectedDate, - firstDate: DateTime(2000), - lastDate: DateTime(2101), - ); - if (picked != null && picked != _selectedDate) { - setState(() { - _selectedDate = picked; - }); - } + @override + void initState(){ + super.initState(); + initArgs(); + } + + List getCategories(){ + List res = []; + categories.forEach((element) { + res.add( + GestureDetector( + onTap: () { + setState(() { + selectedCategory = element; + selectingCategory = false; + }); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.8, + height: 40, + margin: EdgeInsets.all(2.5), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + SizedBox(width: 10), + Icon( + Icons.circle, + color: Color(element.categoryColor), + ), + SizedBox(width: 10), + Text( + element.categoryName, + style: TextStyle( + fontFamily: "Montserrat", + fontSize: 16 + ), + ) + ], + ), + ), + ) + ); + }); + + return res; + } + + Future initArgs() async { + categories = await database.categories(); + selectedCategory = categories.first; //just a default + setState(() { + _loading = false; + }); } + void setSelectedCategory() { + + } @override Widget build(BuildContext context) { + if(_loading){ + return const CircularProgressIndicator(); + } return Scaffold( - appBar: AppBar( - title: const Text('Add Expense'), - backgroundColor: Colors.blueGrey[900], // Adjusted to a dark color - ), - body: Container( - color: Colors.blueGrey[50], // Light background color - child: ListView( - // Using ListView for better scrolling behavior - padding: const EdgeInsets.all(16.0), - children: [ - Card( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + body: SingleChildScrollView( + child: Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + Color(0xFF1E2038), + Color.fromARGB(255, 26, 26, 42), + ], + ) + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 20, top: 40), + child: Text( + "Add\nExpense", + style: TextStyle( + color: Colors.white, + fontSize: 60, + fontFamily: "Montserrat", + ), + ), + ), + Spacer(), + Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.7, + decoration: BoxDecoration( + color: Colors.grey.shade100, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(60), + topRight: Radius.circular(60) + ), + ), + child: Stack( children: [ - TextFormField( - initialValue: '50.00', // Set the initial value - decoration: const InputDecoration( - labelText: 'Amount (SEK)', - border: OutlineInputBorder(), - ), - keyboardType: - const TextInputType.numberWithOptions(decimal: true), - onChanged: (value) { - setState(() { - _amount = double.tryParse(value) ?? 0; - }); - }, - ), - const SizedBox(height: 20), - DropdownButtonFormField( - value: _selectedCategory, - decoration: const InputDecoration( - labelText: 'Category', - border: OutlineInputBorder(), + Center( + child: Column( + children: [ + SizedBox(height: 40), + CustomTextField( + topText: "Amount", + icon: Icon(Icons.monetization_on_outlined), + controller: widget.controllers[0], + inBoxText: "SEK", + readOnly: false, + keyboardType: TextInputType.number, + function: () {}, + width: MediaQuery.of(context).size.width * 0.8, + height: MediaQuery.of(context).size.height * 0.06, + ), + SizedBox(height: 20), + CustomTextField( + topText: "Category", + controller: widget.controllers[3], + inBoxText: selectedCategory.categoryName, + icon: Icon( + Icons.circle, + color: Color(selectedCategory.categoryColor), + ), + readOnly: true, + function: (){ + setState(() { + selectingCategory = true; + }); + }, + width: MediaQuery.of(context).size.width * 0.8, + height: MediaQuery.of(context).size.height * 0.06, + ), + SizedBox(height: 20), + CustomTextField( + topText: "Date", + icon: Icon(Icons.date_range), + controller: widget.controllers[1], + inBoxText: "Transaction date", + readOnly: true, + width: MediaQuery.of(context).size.width * 0.8, + height: MediaQuery.of(context).size.height * 0.06, + keyboardType: TextInputType.datetime, + function: () async { + DateTime? date = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(1900), + lastDate: DateTime.now(), + ); + setState(() { + widget.controllers[1].text = + "${date?.day}/${date?.month}/${date?.year}"; + }); + } + ), + SizedBox(height: 20), + CustomTextField( + topText: "Description", + controller: widget.controllers[2], + inBoxText: "Expense description", + icon: Icon(Icons.description), + function: (){}, + width: MediaQuery.of(context).size.width * 0.8, + height: MediaQuery.of(context).size.height * 0.12, + ), + SizedBox(height: 20), + Container( + width: MediaQuery.of(context).size.width * 0.8, + height: 50, + decoration: BoxDecoration( + color: Colors.deepOrangeAccent, + borderRadius: BorderRadius.circular(10), + ), + child: TextButton( + onPressed: () { + setState(() { + expenseAdded = true; + }); + }, + child: const Text( + "Add Expense", + style: TextStyle( + color: Colors.white, + fontFamily: "Montserrat", + fontSize: 18, + fontWeight: FontWeight.bold + ), + ), + ), + ), + ], ), - onChanged: (String? newValue) { - setState(() { - _selectedCategory = newValue!; - }); - }, - items: [ - 'Food', - 'Transportation', - 'Entertainment', - 'Medical' - ].map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList(), ), - const SizedBox(height: 20), - TextFormField( - controller: _descriptionController, - decoration: const InputDecoration( - labelText: 'Description', - border: OutlineInputBorder(), + Center( + child: Visibility( + visible: expenseAdded, + child: GestureDetector( + onDoubleTap: (){ + setState(() { + expenseAdded = false; + }); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.81, + height: MediaQuery.of(context).size.height * 0.6, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.check_circle_rounded, + color: Colors.green, + size: 60, + ), + Text( + "Yay!\nExpense added.", + style: TextStyle( + fontFamily: "Montserrat", + fontSize: 16, + ), + ) + ], + ), + ), + ), + ), ), - maxLines: 3, ), - const SizedBox(height: 20), - ListTile( - title: Text( - DateFormat('EEE, MMM d, yyyy').format( - _selectedDate), // Use intl package to format the date + Center( + child: Visibility ( + visible: selectingCategory, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(80), + boxShadow: [ + BoxShadow( + blurRadius: 10, + color: Color.fromRGBO(0, 0, 0, 0.5), + ), + ] + ), + ), ), - trailing: const Icon(Icons.calendar_today), - onTap: () => _selectDate(context), ), - const SizedBox(height: 20), - ElevatedButton( - onPressed: () { - // TODO: Add expense confirmation logic - }, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.green, // Button color + Center( + child: Visibility ( + visible: selectingCategory, + child: Container( + padding: EdgeInsets.all(10), + margin: EdgeInsets.all(10), + width: MediaQuery.of(context).size.width * 0.81, + height: categories.length * 50, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.grey.shade300, + ), + child: Column( + children: getCategories(), + ), + ) ), - child: const Text('Confirm Expense'), ), ], - ), - ), - ), - ], + ) + ) + ], + ), ), ), ); diff --git a/lib/pages/registerpage.dart b/lib/pages/registerpage.dart index 852ccce..92a867b 100644 --- a/lib/pages/registerpage.dart +++ b/lib/pages/registerpage.dart @@ -150,7 +150,7 @@ class _RegisterPage extends State{ child: TextField( readOnly: true, controller: widget.controllers[1], - onTap: () async{ + onTap: () async { DateTime? date = await showDatePicker( context: context, initialDate: DateTime.now(), @@ -158,11 +158,11 @@ class _RegisterPage extends State{ lastDate: DateTime.now(), ); - setState(() { - widget.controllers[1].text = - "${date?.day}/${date?.month}/${date?.year}"; - }); - }, + setState(() { + widget.controllers[1].text = + "${date?.day}/${date?.month}/${date?.year}"; + }); + }, decoration: const InputDecoration( icon: Icon( Icons.date_range_rounded, diff --git a/lib/widgets/customtextfield.dart b/lib/widgets/customtextfield.dart new file mode 100644 index 0000000..88d1e9e --- /dev/null +++ b/lib/widgets/customtextfield.dart @@ -0,0 +1,78 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class CustomTextField extends StatelessWidget{ + final String topText; + final TextEditingController controller; + final String inBoxText; + final Icon icon; + double width; + double height; + Function() function; + bool readOnly; + TextInputType keyboardType; + + CustomTextField({ + super.key, + required this.topText, + required this.controller, + required this.inBoxText, + required this.icon, + required this.function, + this.readOnly = false, + this.keyboardType = TextInputType.text, + required this.width, + required this.height, + }); + + @override + Widget build(BuildContext context){ + List formatter = []; + if (keyboardType == TextInputType.number) { + formatter = [ + FilteringTextInputFormatter.digitsOnly + ]; + } + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + topText, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + fontFamily: "Montserrat" + ), + ), + Container( + padding: const EdgeInsets.only(left: 10), + width: width, + height: height, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + ), + child: TextField( + keyboardType: keyboardType, + inputFormatters: formatter, + controller: controller, + readOnly: readOnly, + decoration: InputDecoration( + icon: icon, + border: InputBorder.none, + hintText: inBoxText, + hintStyle: TextStyle( + fontFamily: 'Montserrat', + fontSize: 18, + ), + contentPadding: EdgeInsets.only(left: 10), + ), + onTap: function, + ), + ), + ], + ); + } +} \ No newline at end of file diff --git a/lib/widgets/navbar.dart b/lib/widgets/navbar.dart index 078a529..7e3a0d7 100644 --- a/lib/widgets/navbar.dart +++ b/lib/widgets/navbar.dart @@ -20,7 +20,7 @@ class _NavBar extends State{ HomePage( client: widget.client, ), - const AddExpensePage(), + AddExpensePage(), MyAccount(), ];