cleanup, 'recurring' now is submitted too

also getting ready to add categories
This commit is contained in:
Felix 2019-07-16 12:54:55 +01:00
parent 3ff1f7053d
commit 4ec386019d
No known key found for this signature in database
GPG Key ID: 130EF6DC43E4DD07
9 changed files with 109 additions and 275 deletions

View File

@ -6,9 +6,6 @@ import 'package:http/http.dart' as http;
import 'package:local_spend/common/functions/save_current_login.dart';
import 'package:local_spend/common/functions/show_dialog_single_button.dart';
import 'package:local_spend/model/json/login_model.dart';
import 'package:local_spend/config.dart';
// debug
import 'package:flutter/foundation.dart';
Future<LoginModel> requestLoginAPI(
BuildContext context, String email, String password) async {

View File

@ -6,9 +6,6 @@ import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:local_spend/common/functions/show_dialog_single_button.dart';
import 'package:local_spend/model/json/login_model.dart';
import 'package:local_spend/config.dart';
// debug
import 'package:flutter/foundation.dart';
class Receipt {
var amount = "";

View File

@ -3,6 +3,6 @@ import 'package:shared_preferences/shared_preferences.dart';
getToken() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
String getToken = await preferences.getString("LastToken");
String getToken = preferences.getString("LastToken");
return getToken;
}

View File

@ -1,69 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_spend/common/apifunctions/request_logout_api.dart';
import 'package:local_spend/common/functions/get_token.dart';
import 'package:local_spend/common/functions/logout.dart';
// debug
import 'package:flutter/foundation.dart';
class BasicDrawer extends StatefulWidget {
@override
_BasicDrawerState createState() => _BasicDrawerState();
}
class _BasicDrawerState extends State<BasicDrawer> {
var token;
// TODO: add getter with getToken to check logged in
@override
Widget build(BuildContext context) {
return Drawer(
child: Container(
padding: new EdgeInsets.all(32),
child: ListView(
children: <Widget>[
ListTile(
title: Text (
"Home",
style: TextStyle(color: Colors.black, fontSize: 20.0),
),
onTap: () {
Navigator.of(context).pushNamed('/HomePage');
}
),
ListTile(
title: Text(
"Submit Receipt",
style: TextStyle(color: Colors.black, fontSize: 20.0),
),
onTap: () {
// debugPrint('$token');
Navigator.of(context).pushNamed('/ReceiptPage');
},
// enabled: token != null && token.isNotEmpty,
),
ListTile(
title: Text(
"About",
style: TextStyle(color: Colors.black, fontSize: 20.0),
),
onTap: () {
SystemChannels.textInput.invokeMethod('TextInput.hide');
Navigator.of(context).pushReplacementNamed('/AboutPage');
},
),
ListTile(
title: Text(
"Logout",
style: TextStyle(color: Colors.black, fontSize: 20.0),
),
onTap: () {
logout(context);
},
),
],
),
),
);
}
}

View File

@ -3,9 +3,7 @@ import 'package:local_spend/pages/home_page.dart';
import 'package:local_spend/pages/login_page.dart';
import 'package:local_spend/pages/receipt_page.dart';
import 'package:local_spend/pages/spash_screen.dart';
import 'package:local_spend/pages/about_screen.dart';
import 'package:local_spend/pages/settings.dart';
import 'package:local_spend/config.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() {
@ -34,7 +32,6 @@ class MyApp extends StatelessWidget {
"/HomePage": (BuildContext context) => HomePage(),
"/LoginPage": (BuildContext context) => LoginPage(),
"/ReceiptPage": (BuildContext context) => ReceiptPage(),
"/AboutPage": (BuildContext context) => AboutPage(),
"/SettingsPage": (BuildContext context) => SettingsPage(),
},
home: SplashScreen(),

View File

@ -1,138 +0,0 @@
import 'package:flutter/material.dart';
import 'package:local_spend/common/platform/platform_scaffold.dart';
import 'package:local_spend/common/widgets/basic_drawer.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
class AboutPage extends StatefulWidget {
@override
// _HomePageState createState() => _HomePageState();
State<StatefulWidget> createState() {
return new _HomePageState();
}
}
class _HomePageState extends State<AboutPage> {
@override
void initState() {
super.initState();
_saveCurrentRoute("/AboutPage");
}
@override
void dispose() {
super.dispose();
}
_saveCurrentRoute(String lastRoute) async {
SharedPreferences preferences = await SharedPreferences.getInstance();
await preferences.setString('LastScreenRoute', lastRoute);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
if (Navigator.canPop(context)) {
Navigator.of(context).pushNamedAndRemoveUntil(
'/HomePage', (Route<dynamic> route) => true);
} else {
Navigator.of(context).pushReplacementNamed('/HomePage');
}
},
child: PlatformScaffold(
appBar: AppBar(
title: Text(
"About Page",
style: TextStyle(
fontSize: 20,
color: Colors.black,
),
),
leading: BackButton(),
centerTitle: true,
iconTheme: IconThemeData(color: Colors.black),
),
body: Container(
padding: EdgeInsets.all(32.0),
child: ListView(
children: <Widget>[
InkWell(
child: const Center(child: Text
('Pear Trading',
style: TextStyle(
fontSize: 20,
color: Colors.blue,
),
),
),
onTap: () => launch('https://app.peartrade.org/#/login?returnUrl=%2Fdashboard')
),
Padding(
padding: EdgeInsets.fromLTRB(0,20,0,0),
child: Text(
"Pear Trading is a commerce company designed to register and monitor money circulating in the local economy.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0,20,0,0),
child: Text(
"Email: Test@admin.com",
// TODO: Make this an @email link
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
color: Colors.blue,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0,20,0,0),
child: Text(
"Phone: +44(0)1524 64544",
// TODO: Make this a @phone link
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
color: Colors.blue,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0,40,0,0),
child: Text(
"Developed by Shadowcat Industries",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0,20,0,0),
child: InkWell(
child: const Center(child: Text
('Shadowcat',
style: TextStyle(
fontSize: 20,
color: Colors.blue,
),
),
),
onTap: () => launch('https://shadow.cat/')
),
),
],
),
),
),
);
}
}

View File

@ -1,5 +1,4 @@
import 'dart:async';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_spend/common/apifunctions/request_login_api.dart';

View File

@ -5,15 +5,12 @@ import 'package:flutter/services.dart';
import 'package:local_spend/common/apifunctions/submit_receipt_api.dart';
import 'package:local_spend/common/functions/show_dialog_single_button.dart';
import 'package:local_spend/common/platform/platform_scaffold.dart';
import 'package:local_spend/common/widgets/basic_drawer.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:intl/intl.dart';
import 'package:local_spend/pages/settings.dart';
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
import 'package:local_spend/common/apifunctions/find_organisations.dart';
import 'package:local_spend/common/widgets/popupListView.dart';
import 'package:local_spend/common/widgets/labeled_checkbox.dart';
const URL = "https://flutter.io/";
const demonstration = false;
@ -29,8 +26,8 @@ class ReceiptPageState extends State<ReceiptPage> {
final TextEditingController _timeController = TextEditingController();
final TextEditingController _amountController = TextEditingController();
final TextEditingController _essentialController = TextEditingController();
final TextEditingController _recurringController = TextEditingController(text: "None");
final TextEditingController _typeController = TextEditingController();
final TextEditingController _recurringController = TextEditingController();
final TextEditingController _categoryController = TextEditingController();
final TextEditingController _orgController = TextEditingController();
final OrganizationController _organizationController = OrganizationController();
@ -56,6 +53,8 @@ class ReceiptPageState extends State<ReceiptPage> {
_saveCurrentRoute("/ReceiptPageState");
focusNode = FocusNode();
_recurringController.text = "None";
}
@override
@ -72,18 +71,19 @@ class ReceiptPageState extends State<ReceiptPage> {
// this file is getting really messy sorry everyone
void submitReceipt(String amount, String time, Organisation organisation) async {
void submitReceipt(String amount, String time, Organisation organisation, String recurring) async {
SystemChannels.textInput.invokeMethod('TextInput.hide');
if (amount == "" || time == "" || organisation == null) {
await showDialog(
if (organisation == null) {
_findOrganizationsDialog(context);
/* await showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Invalid data"),
title: new Text("Missing organisation"),
content: new Text(
"We couldn't process your request because one or more required fields are missing."),
"Please press 'Find' to select your desired organization."),
actions: <Widget>[
new FlatButton(
child: new Text("OK"),
@ -94,53 +94,77 @@ class ReceiptPageState extends State<ReceiptPage> {
],
);
},
);
);*/
}
else {
if (demonstration) {
if (amount == "" || time == "") {
await showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Success"),
content: new Text("Receipt successfully submitted."),
title: new Text("Missing required data"),
content: new Text(
"We couldn't process your request because one or more required fields are missing."),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("OK"),
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pushReplacementNamed('/HomePage');
},
),
],
);
},
).then((_) {});
);
}
else {
Receipt receipt = new Receipt();
if (demonstration) {
await showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Success"),
content: new Text("Receipt successfully submitted."),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("OK"),
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pushReplacementNamed("/HomePage");
},
),
],
);
},
).then((_) {});
}
// setting up 'receipt'
receipt.amount = amount;
receipt.time = formatDate(time);
// debugPrint(organisation.name + ", " + organisation.streetName + ", " + organisation.town + ", " + organisation.postcode);
receipt.organisationName = organisation.name;
receipt.street = organisation.streetName;
receipt.town = organisation.town;
receipt.postcode = organisation.postcode;
else {
Receipt receipt = new Receipt();
// receipt.essential = convertBoolToString(toConvert)
// setting up 'receipt'
receipt.amount = amount;
receipt.time = formatDate(time);
// debugPrint(organisation.name + ", " + organisation.streetName + ", " + organisation.town + ", " + organisation.postcode);
receipt.organisationName = organisation.name;
receipt.street = organisation.streetName;
receipt.town = organisation.town;
receipt.postcode = organisation.postcode;
receipt.recurring = recurring;
// TODO: Categories
// receipt.essential = convertBoolToString(toConvert)
// receipt.category = category;
// receipt.etc = etc;
// TODO: Categories
submitReceiptAPI(context, receipt);
Navigator.of(context).pushReplacementNamed('/HomePage');
// receipt.category = category;
// receipt.etc = etc;
submitReceiptAPI(context, receipt);
Navigator.of(context).pushReplacementNamed("/HomePage");
}
}
}
}
@ -226,6 +250,29 @@ class ReceiptPageState extends State<ReceiptPage> {
//can't return value as it is <future> and thus would block
}
_findOrganizationsDialog(context) {
if (_orgController.text != "") {
var organisations = findOrganisations(
_orgController.text); // returns Future<List<Organisation>>
var choice = organisations.then((data) =>
listOrganisations(data, context));
choice.then((value) => _orgController.text = value.name);
choice.then((value) => _organizationController.organisation = value);
} else {
// no data entered
showDialogSingleButton(
context,
"No data",
"We were unable to service your request because no data was entered.",
"OK"
);
}
}
@override
Widget build(BuildContext context) {
return WillPopScope(
@ -336,26 +383,7 @@ class ReceiptPageState extends State<ReceiptPage> {
padding: EdgeInsets.fromLTRB(5,0,0,4), // sorry about hardcoded constraints
child: FlatButton(
onPressed: () {
if (_orgController.text != "") {
var organisations = findOrganisations(
_orgController.text); // returns Future<List<Organisation>>
var choice = organisations.then((data) =>
listOrganisations(data, context));
choice.then((value) => _orgController.text = value.name);
choice.then((value) => _organizationController.organisation = value);
} else {
// no data entered
showDialogSingleButton(
context,
"No data",
"We were unable to service your request because no data was entered.",
"OK"
);
}
_findOrganizationsDialog(context);
},
child: Text("Find",
style: TextStyle(color: Colors.blue, fontSize: 18.0)
@ -386,7 +414,7 @@ class ReceiptPageState extends State<ReceiptPage> {
),
onSubmitted: (_) {
submitReceipt(_amountController.text,
_timeController.text, _organizationController.organisation);
_timeController.text, _organizationController.organisation, _recurringController.text);
// TODO: make sure organisation is valid
// TODO: Add 'find organisation' button which displays a dialog to, well, find the organisation's address or manual entry
},
@ -484,7 +512,32 @@ class ReceiptPageState extends State<ReceiptPage> {
height: 65.0,
child: RaisedButton(
onPressed: () {
submitReceipt(_amountController.text, _timeController.text, _organizationController.organisation);
try {
submitReceipt(
_amountController.text, _timeController.text,
_organizationController.organisation, _recurringController.text);
}
catch (_) {
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Invalid data"),
content: new Text(
"We couldn't process your request because some of the data entered is invalid."),
actions: <Widget>[
new FlatButton(
child: new Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
},
child: Text("GO",
style:

View File

@ -1,4 +1,3 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:local_spend/common/platform/platform_scaffold.dart';
@ -7,7 +6,6 @@ import 'package:local_spend/common/functions/logout.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:local_spend/common/functions/customAbout.dart' as custom;
import 'package:local_spend/common/functions/showDialogTwoButtons.dart';
import 'package:local_spend/common/functions/feedback.dart';
const URL = "https://flutter.io/";
const demonstration = false;