cleanup, 'recurring' now is submitted too
also getting ready to add categories
This commit is contained in:
parent
3ff1f7053d
commit
4ec386019d
9 changed files with 109 additions and 275 deletions
|
@ -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 {
|
||||
|
|
|
@ -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 = "";
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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(),
|
||||
|
|
|
@ -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/')
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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';
|
||||
|
|
|
@ -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,16 +71,39 @@ 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) {
|
||||
if (organisation == null) {
|
||||
_findOrganizationsDialog(context);
|
||||
/* await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
// return object of type Dialog
|
||||
return AlertDialog(
|
||||
title: new Text("Missing organisation"),
|
||||
content: new Text(
|
||||
"Please press 'Find' to select your desired organization."),
|
||||
actions: <Widget>[
|
||||
new FlatButton(
|
||||
child: new Text("OK"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);*/
|
||||
}
|
||||
else {
|
||||
if (amount == "" || time == "") {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
// return object of type Dialog
|
||||
return AlertDialog(
|
||||
title: new Text("Invalid data"),
|
||||
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>[
|
||||
|
@ -111,7 +133,7 @@ class ReceiptPageState extends State<ReceiptPage> {
|
|||
child: new Text("OK"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushReplacementNamed('/HomePage');
|
||||
Navigator.of(context).pushReplacementNamed("/HomePage");
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -131,6 +153,7 @@ class ReceiptPageState extends State<ReceiptPage> {
|
|||
receipt.street = organisation.streetName;
|
||||
receipt.town = organisation.town;
|
||||
receipt.postcode = organisation.postcode;
|
||||
receipt.recurring = recurring;
|
||||
|
||||
// receipt.essential = convertBoolToString(toConvert)
|
||||
|
||||
|
@ -140,7 +163,8 @@ class ReceiptPageState extends State<ReceiptPage> {
|
|||
// receipt.etc = etc;
|
||||
|
||||
submitReceiptAPI(context, receipt);
|
||||
Navigator.of(context).pushReplacementNamed('/HomePage');
|
||||
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:
|
||||
|
|
|
@ -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;
|
||||
|
|
Reference in a new issue