diff --git a/expense_tracker/.vscode/launch.json b/expense_tracker/.vscode/launch.json deleted file mode 100644 index 92b93a0..0000000 --- a/expense_tracker/.vscode/launch.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - - { - "type": "chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:64885/", - "webRoot": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/expense_tracker/lib/Components/navbar.dart b/expense_tracker/lib/Components/navbar.dart index 3a5c039..2021d08 100644 --- a/expense_tracker/lib/Components/navbar.dart +++ b/expense_tracker/lib/Components/navbar.dart @@ -1,4 +1,5 @@ import 'package:expense_tracker/Screens/addexpenses.dart'; +import 'package:expense_tracker/Screens/myhomepage.dart'; import 'package:expense_tracker/Screens/profile.dart'; import 'package:flutter/material.dart'; import '../Screens/activity.dart'; @@ -42,9 +43,15 @@ class DesktopNavbar extends StatelessWidget { ), Row( children: [ - const Text( - "Home", - style: TextStyle(color: Colors.white), + GestureDetector( + onTap: () => { + Navigator.push(context, + MaterialPageRoute(builder: (context) => MyHomePage())) + }, + child: const Text( + "Home", + style: TextStyle(color: Colors.white, fontSize: 20), + ), ), const SizedBox( width: 30, @@ -56,7 +63,7 @@ class DesktopNavbar extends StatelessWidget { }, child: const Text( "Add expenses", - style: TextStyle(color: Colors.white), + style: TextStyle(color: Colors.white, fontSize: 20), ), ), const SizedBox( @@ -69,7 +76,7 @@ class DesktopNavbar extends StatelessWidget { }, child: const Text( "Activity", - style: TextStyle(color: Colors.white), + style: TextStyle(color: Colors.white, fontSize: 20), ), ), const SizedBox( @@ -82,7 +89,7 @@ class DesktopNavbar extends StatelessWidget { }, child: const Text( "Profile", - style: TextStyle(color: Colors.white), + style: TextStyle(color: Colors.white, fontSize: 20), ), ), const SizedBox( @@ -95,7 +102,7 @@ class DesktopNavbar extends StatelessWidget { onPressed: () {}, child: const Text( "Get Started", - style: TextStyle(color: Colors.white), + style: TextStyle(color: Colors.white, fontSize: 20), ), ) ], @@ -128,28 +135,28 @@ class MobileNavbar extends StatelessWidget { children: [ Text( "Home", - style: TextStyle(color: Colors.white), + style: TextStyle(color: Colors.white, fontSize: 20), ), SizedBox( width: 30, ), Text( "Activity", - style: TextStyle(color: Colors.white), + style: TextStyle(color: Colors.white, fontSize: 20), ), SizedBox( width: 30, ), Text( "Profile", - style: TextStyle(color: Colors.white), + style: TextStyle(color: Colors.white, fontSize: 20), ), SizedBox( width: 30, ), Text( "About us", - style: TextStyle(color: Colors.white), + style: TextStyle(color: Colors.white, fontSize: 20), ), ], ), diff --git a/expense_tracker/lib/Screens/Login.dart b/expense_tracker/lib/Screens/Login.dart index 4f000f3..8b13dec 100644 --- a/expense_tracker/lib/Screens/Login.dart +++ b/expense_tracker/lib/Screens/Login.dart @@ -102,7 +102,7 @@ class LoginState extends State { ), autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) => value != null && value.length < 8 - ? 'Enter min 6 char' + ? 'Enter min 8 char' : null, ), ), @@ -110,7 +110,7 @@ class LoginState extends State { RichText( text: TextSpan( style: TextStyle( - color: Colors.orangeAccent[700], fontSize: 20), + color: Colors.orangeAccent[700], fontSize: 15), text: 'No account?', children: [ TextSpan( @@ -119,7 +119,8 @@ class LoginState extends State { text: 'Sign up', style: TextStyle( decoration: TextDecoration.underline, - color: Colors.orangeAccent[700])), + color: Colors.orangeAccent[700], + fontSize: 15)), ], ), ), diff --git a/expense_tracker/lib/Screens/activity.dart b/expense_tracker/lib/Screens/activity.dart index 0e01b09..714fbaf 100644 --- a/expense_tracker/lib/Screens/activity.dart +++ b/expense_tracker/lib/Screens/activity.dart @@ -1,3 +1,5 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import '../Components/navbar.dart'; import './myhomepage.dart'; @@ -12,49 +14,141 @@ class Activity extends StatefulWidget { } class _ActivityState extends State { + late DatabaseReference expensesRef; + List expenseList = []; + @override + void initState() { + super.initState(); + expensesRef = FirebaseDatabase.instance + .ref('expenses/${FirebaseAuth.instance.currentUser!.uid}'); + expensesRef.onValue.listen((event) { + setState(() { + expenseList = event.snapshot.children.toList(); + }); + }); + } + @override Widget build(BuildContext context) { return Scaffold( - body: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height, - width: MediaQuery.of(context).size.width, - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [ - Color.fromARGB(255, 83, 78, 212), - Color.fromARGB(255, 28, 28, 28) - ])), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Navbar(), - const Padding( - padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 40.0), - ), - Container( - width: 600, - // height: 50, - child: Card( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), - child: const ListTile( - title: Text('kjasdhksgjdv'), - subtitle: Text('jdfndnhgvfvdsjn'), - ), + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + Color.fromARGB(255, 83, 78, 212), + Color.fromARGB(255, 28, 28, 28) + ])), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Navbar(), + const Padding( + padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 40.0), + ), + Expanded( + child: expenseList.length == 0 + ? Center( + child: Text( + 'No Expense Added', + style: TextStyle(color: Colors.white), + ), + ) + : Container( + width: 900, + child: ListView.builder( + itemCount: expenseList.length, + itemBuilder: (context, index) { + var childData = expenseList[index]; + return Card( + child: Padding( + padding: EdgeInsets.all(10), + child: Row( + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + '${childData.child('Marchantname').value} - ${childData.child('category').value}', + style: TextStyle( + fontWeight: FontWeight.bold), + ), + SizedBox(height: 20), + Text( + '${childData.child('Description').value}'), + ], + ), + Spacer(), + Column( + children: [ + Text( + '\$20.0', + style: TextStyle( + fontWeight: FontWeight.bold), + ), + SizedBox(height: 20), + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text('Alert'), + content: const Text( + 'Do you want to remove this expense? '), + actions: [ + TextButton( + style: + TextButton.styleFrom( + textStyle: + Theme.of(context) + .textTheme + .labelLarge, + ), + child: const Text('No'), + onPressed: () { + Navigator.of(context) + .pop(); + }, + ), + TextButton( + style: + TextButton.styleFrom( + textStyle: + Theme.of(context) + .textTheme + .labelLarge, + ), + child: const Text('Yes'), + onPressed: () { + childData.ref.remove(); + Navigator.of(context) + .pop(); + }, + ), + ], + ); + }); + // + }, + child: Icon( + Icons.delete, + color: Colors.redAccent, + ), + ) + ], + ), + ], + ), + ), + ); + }, ), - ], - ), - ), - ), - ], - ), + ), + ), + ], ), ), ); diff --git a/expense_tracker/lib/Screens/addexpenses.dart b/expense_tracker/lib/Screens/addexpenses.dart index cb8b347..db31739 100644 --- a/expense_tracker/lib/Screens/addexpenses.dart +++ b/expense_tracker/lib/Screens/addexpenses.dart @@ -1,3 +1,4 @@ +import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import 'package:file_picker/file_picker.dart'; @@ -19,17 +20,18 @@ class _AddExpensesState extends State { // final entertainmentController = dropdownValue; var merchantnameController = new TextEditingController(); var descriptionController = new TextEditingController(); - // final dateController = TextEditingController(); - // final documentController = TextEditingController(); + var amountController = new TextEditingController(); final databaseRef = FirebaseDatabase.instance.ref(); void openFiles() async { FilePickerResult? resultFile = - await FilePicker.platform.pickFiles(allowMultiple: true); + await FilePicker.platform.pickFiles(allowMultiple: false); if (resultFile != null) { PlatformFile file = resultFile.files.first; - + setState(() { + fileresult = file; + }); print(file.name); print(file.bytes); print(file.extension); @@ -39,6 +41,7 @@ class _AddExpensesState extends State { } } + PlatformFile? fileresult; DateTime _dateTime = DateTime.now(); void _showdate() { showDatePicker( @@ -48,7 +51,7 @@ class _AddExpensesState extends State { lastDate: DateTime(2025), ).then((value) { setState(() { - _dateTime = value!; + _dateTime = value ?? DateTime.now(); }); }); } @@ -97,40 +100,40 @@ class _AddExpensesState extends State { color: Color.fromARGB(255, 255, 255, 255)), ), SizedBox(height: 30), - // Row( - // children: [ - // Padding( - // padding: - // EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), - // child: Text( - // "Category", - // style: TextStyle( - // color: - // Color.fromARGB(255, 255, 255, 255)), - // )), - // SizedBox(width: 30), - // DropdownButton( - // value: dropdownValue, - // icon: const Icon(Icons.arrow_downward), - // elevation: 16, - // style: const TextStyle(color: Colors.deepPurple), - // underline: Container( - // height: 2, - // color: Colors.deepPurpleAccent, - // ), - // onChanged: (String? value) => setState(() { - // dropdownValue = value!; - // }), - // items: list.map>( - // (String value) { - // return DropdownMenuItem( - // value: value, - // child: Text(value), - // ); - // }).toList(), - // ), - // ], - // ), + Row( + children: [ + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), + child: Text( + "Category", + style: TextStyle( + color: + Color.fromARGB(255, 255, 255, 255)), + )), + SizedBox(width: 30), + DropdownButton( + value: dropdownValue, + icon: const Icon(Icons.arrow_downward), + elevation: 16, + style: const TextStyle(color: Colors.deepPurple), + underline: Container( + height: 2, + color: Colors.deepPurpleAccent, + ), + onChanged: (String? value) => setState(() { + dropdownValue = value!; + }), + items: list.map>( + (String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + ), + ], + ), SizedBox(height: 20), Row( children: [ @@ -159,6 +162,33 @@ class _AddExpensesState extends State { ], ), SizedBox(height: 20), + Row( + children: [ + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), + child: Text("Amount in Pound", + style: TextStyle( + color: Color.fromARGB( + 255, 255, 255, 255)))), + SizedBox(width: 30), + // Text("hi", + // style: TextStyle( + // color: Color.fromARGB(255, 255, 255, 255))) + Container( + // height: 70, + width: 120, + child: TextFormField( + controller: amountController, + decoration: const InputDecoration( + border: UnderlineInputBorder(), + labelText: 'amount', + ), + ), + ), + ], + ), + SizedBox(height: 20), Row( children: [ Padding( @@ -184,79 +214,83 @@ class _AddExpensesState extends State { ), ], ), - // SizedBox(height: 20), - // Row( - // children: [ - // Padding( - // padding: - // EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), - // child: Text("Date", - // style: TextStyle( - // color: Color.fromARGB( - // 255, 255, 255, 255)))), - // SizedBox(width: 60), - // GestureDetector( - // onTap: () { - // _showdate(); - // }, - // child: Container( - // width: 100, - // height: 20, - // color: Colors.blue, - // child: Center( - // child: Text( - // "Choose date", - // style: TextStyle( - // color: Color.fromARGB( - // 255, 255, 255, 255)), - // ), - // )), - // ), - // SizedBox(width: 20), - // Text(_dateTime.toString(), - // style: TextStyle( - // color: Color.fromARGB(255, 255, 255, 255))) - // ], - // ), - // SizedBox(height: 20), - // Row( - // children: [ - // Padding( - // padding: - // EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), - // child: Text("Attach bills", - // style: TextStyle( - // color: Color.fromARGB( - // 255, 255, 255, 255)))), - // SizedBox(width: 20), - // GestureDetector( - // onTap: () { - // openFiles(); - // }, - // child: Container( - // width: 100, - // height: 20, - // color: Colors.blue, - // child: Center( - // child: Text( - // "Open File", - // style: TextStyle( - // color: Color.fromARGB( - // 255, 255, 255, 255)), - // ), - // )), - // ), - // SizedBox(width: 20), - // Text("dhaksfhk", - // style: TextStyle( - // color: Color.fromARGB(255, 255, 255, 255))) - // ], - // ), + SizedBox(height: 20), + Row( + children: [ + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), + child: Text("Date", + style: TextStyle( + color: Color.fromARGB( + 255, 255, 255, 255)))), + SizedBox(width: 60), + GestureDetector( + onTap: () { + _showdate(); + }, + child: Container( + width: 100, + height: 20, + color: Colors.blue, + child: Center( + child: Text( + "Choose date", + style: TextStyle( + color: Color.fromARGB( + 255, 255, 255, 255)), + ), + )), + ), + SizedBox(width: 20), + Text(_dateTime.toString(), + style: TextStyle( + color: Color.fromARGB(255, 255, 255, 255))) + ], + ), + SizedBox(height: 20), + Row( + children: [ + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(20, 0, 0, 0), + child: Text("Attach bills", + style: TextStyle( + color: Color.fromARGB( + 255, 255, 255, 255)))), + SizedBox(width: 20), + GestureDetector( + onTap: () { + openFiles(); + }, + child: Container( + width: 100, + height: 20, + color: Colors.blue, + child: Center( + child: Text( + "Open File", + style: TextStyle( + color: Color.fromARGB( + 255, 255, 255, 255)), + ), + )), + ), + SizedBox(width: 20), + Text(fileresult?.name ?? 'no file', + style: TextStyle( + color: Color.fromARGB(255, 255, 255, 255))) + ], + ), SizedBox(height: 20), GestureDetector( onTap: () { - insertData(merchantnameController.text, - descriptionController.text); + insertData( + merchantnameController.text, + descriptionController.text, + dropdownValue, + _dateTime.toString(), + amountController.toString()); }, child: Container( alignment: Alignment.center, @@ -295,11 +329,22 @@ class _AddExpensesState extends State { ); } - void insertData(String Merchantname, String Description) { - databaseRef - .child("users") - .set({'Marchantname': Merchantname, 'Description': Description}); + void insertData(String Merchantname, String Description, String dropdownValue, + String dateTime, String amount) { + var userExpenseRef = databaseRef + .child("expenses") + .child(FirebaseAuth.instance.currentUser!.uid) + .ref + .push(); + userExpenseRef.set({ + 'Marchantname': Merchantname, + 'Description': Description, + 'category': dropdownValue, + 'Date': dateTime, + 'Amount': amount + }); merchantnameController.clear(); descriptionController.clear(); + amountController.clear(); } } diff --git a/expense_tracker/lib/Screens/myhomepage.dart b/expense_tracker/lib/Screens/myhomepage.dart index 3696600..5075b1a 100644 --- a/expense_tracker/lib/Screens/myhomepage.dart +++ b/expense_tracker/lib/Screens/myhomepage.dart @@ -43,7 +43,7 @@ class MyHomePage extends StatelessWidget { children: [ const SizedBox(height: 60), const Text( - 'Monthly Expenses', + 'Expenses', textAlign: TextAlign.center, style: TextStyle( fontSize: 50, @@ -60,7 +60,7 @@ class MyHomePage extends StatelessWidget { padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 0), child: Icon( - Icons.favorite, + Icons.food_bank_outlined, color: Colors.pink, size: 24.0, ), @@ -94,7 +94,7 @@ class MyHomePage extends StatelessWidget { padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 0), child: Icon( - Icons.favorite, + Icons.home_max_outlined, color: Colors.pink, size: 24.0, ), @@ -128,7 +128,7 @@ class MyHomePage extends StatelessWidget { padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 0), child: Icon( - Icons.favorite, + Icons.travel_explore_outlined, color: Colors.pink, size: 24.0, ), @@ -162,7 +162,7 @@ class MyHomePage extends StatelessWidget { padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 0), child: Icon( - Icons.favorite, + Icons.book_online_outlined, color: Colors.pink, size: 24.0, ), diff --git a/expense_tracker/lib/Screens/profile.dart b/expense_tracker/lib/Screens/profile.dart index 3afe730..a25bdab 100644 --- a/expense_tracker/lib/Screens/profile.dart +++ b/expense_tracker/lib/Screens/profile.dart @@ -1,4 +1,5 @@ import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import '../Components/navbar.dart'; import 'Login.dart'; diff --git a/expense_tracker/lib/Screens/register.dart b/expense_tracker/lib/Screens/register.dart index cbb00dd..a613e93 100644 --- a/expense_tracker/lib/Screens/register.dart +++ b/expense_tracker/lib/Screens/register.dart @@ -1,5 +1,5 @@ -import 'package:expense_tracker/Screens/myhomepage.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import '../main.dart'; @@ -21,10 +21,13 @@ class RegisterPageState extends State { final formKey = GlobalKey(); final emailController = TextEditingController(); final passwordController = TextEditingController(); + final nameController = TextEditingController(); + @override void dispose() { emailController.dispose(); passwordController.dispose(); + nameController.dispose(); super.dispose(); } @@ -82,6 +85,7 @@ class RegisterPageState extends State { Container( width: 250, child: TextFormField( + controller: nameController, decoration: InputDecoration( labelText: 'Name', // suffixIcon: Icon(FontAwesomeIcons.envelope), @@ -132,6 +136,7 @@ class RegisterPageState extends State { ), ), ), + const SizedBox(height: 20), RichText( text: TextSpan( style: TextStyle( @@ -144,7 +149,8 @@ class RegisterPageState extends State { text: 'Sign in', style: TextStyle( decoration: TextDecoration.underline, - color: Colors.orangeAccent[700])), + color: Colors.orangeAccent[700], + fontSize: 20)), ], ), ), @@ -175,6 +181,7 @@ class RegisterPageState extends State { ), )), ), + const SizedBox(height: 20), ], ), ), @@ -195,12 +202,25 @@ class RegisterPageState extends State { builder: (context) => Center(child: CircularProgressIndicator()), ); try { - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: emailController.text.trim(), - password: passwordController.text.trim()); + var usercredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: emailController.text.trim(), + password: passwordController.text.trim()); + if (usercredential.user != null) + signupobject(emailController.text.trim(), nameController.text.trim(), + usercredential.user!.uid); } on FirebaseAuthException catch (e) { print(e); } navigatorKey.currentState!.popUntil((route) => route.isFirst); } } + +Future signupobject( + String emailController, String nameController, String uid) async { + await FirebaseDatabase.instance + .ref() + .child('users') + .child(uid) + .set({"Email": emailController, "Name": nameController}); +} diff --git a/expense_tracker/lib/main.dart b/expense_tracker/lib/main.dart index 7b02a78..b206c45 100644 --- a/expense_tracker/lib/main.dart +++ b/expense_tracker/lib/main.dart @@ -36,6 +36,7 @@ class MainPage extends StatelessWidget { Widget build(BuildContext context) => Scaffold( body: StreamBuilder( stream: FirebaseAuth.instance.authStateChanges(), + initialData: null, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator());