diff --git a/lib/data/file_storage.dart b/lib/data/file_storage.dart index cf32be9b0..0f05a15fe 100644 --- a/lib/data/file_storage.dart +++ b/lib/data/file_storage.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import '../data/models/models.dart'; +import 'package:invoiceninja/data/models/models.dart'; //import 'package:built_redux_sample/models/serializers.dart'; /// Loads and saves a List of Products using a text file stored on the device. diff --git a/lib/data/repositories/product_repository.dart b/lib/data/repositories/product_repository.dart index 58b10c8d5..02b6d6f9f 100644 --- a/lib/data/repositories/product_repository.dart +++ b/lib/data/repositories/product_repository.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'dart:core'; import 'package:meta/meta.dart'; -import '../../data/models/entities.dart'; -import '../../data/repositories/repositories.dart'; -import '../../data/file_storage.dart'; -import '../../data/web_client.dart'; +import 'package:invoiceninja/data/models/entities.dart'; +import 'package:invoiceninja/data/repositories/repositories.dart'; +import 'package:invoiceninja/data/file_storage.dart'; +import 'package:invoiceninja/data/web_client.dart'; /// A class that glues together our local file storage and web client. It has a /// clear responsibility: Load Products and Persist products. diff --git a/lib/data/repositories/repositories.dart b/lib/data/repositories/repositories.dart index 4c740b492..ebdfb9061 100644 --- a/lib/data/repositories/repositories.dart +++ b/lib/data/repositories/repositories.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'dart:core'; -import '../../data/models/entities.dart'; +import 'package:invoiceninja/data/models/entities.dart'; /// A class that Loads and Persists products. The data layer of the app. /// diff --git a/lib/data/web_client.dart b/lib/data/web_client.dart index 6f538695e..415dc3508 100644 --- a/lib/data/web_client.dart +++ b/lib/data/web_client.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; -import '../data/models/models.dart'; +import 'package:invoiceninja/data/models/models.dart'; /// A class that is meant to represent a Web Service you would call to fetch /// and persist Products to and from the cloud. diff --git a/lib/keys.dart b/lib/keys.dart index 9f29f08ac..0d3ad5951 100644 --- a/lib/keys.dart +++ b/lib/keys.dart @@ -6,6 +6,7 @@ class NinjaKeys { static Key snackbarAction(String id) => Key('__snackbar_action_${id}__'); static final dashboard = const Key('__dashboard__'); + static final loginScreen = const Key('__login_screen__'); static final clientList = const Key('__client_list__'); static final productHome = const Key('__product_home__'); diff --git a/lib/main.dart b/lib/main.dart index 15e4c3b79..629e20433 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,9 +2,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux/redux.dart'; import 'redux/app/app_state.dart'; -import 'ui/dashboard.dart'; -import 'ui/client/client_list.dart'; -import 'ui/product/product_home.dart'; +import 'package:invoiceninja/ui/dashboard_screen.dart'; +import 'package:invoiceninja/ui/client/client_list.dart'; +import 'package:invoiceninja/ui/product/product_screen.dart'; +import 'package:invoiceninja/ui/app/login_screen.dart'; import 'routes.dart'; import 'redux/product/product_actions.dart'; import 'redux/product/product_middleware.dart'; @@ -39,6 +40,13 @@ class InvoiceNinjaApp extends StatelessWidget { theme: new ThemeData.dark(), title: 'Invoice Ninja', routes: { + NinjaRoutes.login: (context) { + return StoreBuilder( + builder: (context, store) { + return LoginScreen(); + }, + ); + }, NinjaRoutes.dashboard: (context) { return StoreBuilder( builder: (context, store) { diff --git a/lib/redux/app/app_reducer.dart b/lib/redux/app/app_reducer.dart index eda1d035c..2bc8a74a8 100644 --- a/lib/redux/app/app_reducer.dart +++ b/lib/redux/app/app_reducer.dart @@ -1,6 +1,6 @@ -import '../../redux/app/app_state.dart'; -import '../../redux/app/loading_reducer.dart'; -import '../../redux/product/product_reducer.dart'; +import 'package:invoiceninja/redux/app/app_state.dart'; +import 'package:invoiceninja/redux/app/loading_reducer.dart'; +import 'package:invoiceninja/redux/product/product_reducer.dart'; // We create the State reducer by combining many smaller reducers into one! AppState appReducer(AppState state, action) { diff --git a/lib/redux/app/app_state.dart b/lib/redux/app/app_state.dart index ef4ca651b..fc10e43cd 100644 --- a/lib/redux/app/app_state.dart +++ b/lib/redux/app/app_state.dart @@ -1,5 +1,5 @@ import 'package:meta/meta.dart'; -import '../../data/models/models.dart'; +import 'package:invoiceninja/data/models/models.dart'; @immutable class AppState { diff --git a/lib/redux/app/loading_reducer.dart b/lib/redux/app/loading_reducer.dart index 0dd84694e..e7ca0543f 100644 --- a/lib/redux/app/loading_reducer.dart +++ b/lib/redux/app/loading_reducer.dart @@ -1,5 +1,5 @@ import 'package:redux/redux.dart'; -import '../../redux/product/product_actions.dart'; +import 'package:invoiceninja/redux/product/product_actions.dart'; final loadingReducer = combineReducers([ TypedReducer(_setLoaded), diff --git a/lib/redux/product/product_actions.dart b/lib/redux/product/product_actions.dart index e736de8a0..26420ca10 100644 --- a/lib/redux/product/product_actions.dart +++ b/lib/redux/product/product_actions.dart @@ -1,4 +1,4 @@ -import '../../data/models/models.dart'; +import 'package:invoiceninja/data/models/models.dart'; class LoadProductsAction {} diff --git a/lib/redux/product/product_middleware.dart b/lib/redux/product/product_middleware.dart index 65937150c..b1d918f86 100644 --- a/lib/redux/product/product_middleware.dart +++ b/lib/redux/product/product_middleware.dart @@ -1,11 +1,11 @@ import 'package:path_provider/path_provider.dart'; import 'package:redux/redux.dart'; -import '../../redux/product/product_actions.dart'; -import '../../redux/app/app_state.dart'; -import '../../data/repositories/repositories.dart'; -import '../../data/repositories/product_repository.dart'; -import '../../data/file_storage.dart'; -import '../../redux/product/product_selectors.dart'; +import 'package:invoiceninja/redux/product/product_actions.dart'; +import 'package:invoiceninja/redux/app/app_state.dart'; +import 'package:invoiceninja/data/repositories/repositories.dart'; +import 'package:invoiceninja/data/repositories/product_repository.dart'; +import 'package:invoiceninja/data/file_storage.dart'; +import 'package:invoiceninja/redux/product/product_selectors.dart'; List> createStoreProductsMiddleware([ ProductsRepository repository = const ProductsRepositoryFlutter( diff --git a/lib/redux/product/product_reducer.dart b/lib/redux/product/product_reducer.dart index 337e4fa68..02c4c4c10 100644 --- a/lib/redux/product/product_reducer.dart +++ b/lib/redux/product/product_reducer.dart @@ -1,7 +1,7 @@ import 'package:redux/redux.dart'; -import '../../redux/product/product_actions.dart'; -import '../../data/models/models.dart'; -import '../../redux/product/product_selectors.dart'; +import 'package:invoiceninja/redux/product/product_actions.dart'; +import 'package:invoiceninja/data/models/models.dart'; +import 'package:invoiceninja/redux/product/product_selectors.dart'; final productsReducer = combineReducers>([ /* diff --git a/lib/redux/product/product_selectors.dart b/lib/redux/product/product_selectors.dart index 3d5fe1476..3c892430a 100644 --- a/lib/redux/product/product_selectors.dart +++ b/lib/redux/product/product_selectors.dart @@ -1,6 +1,6 @@ -import '../../data/models/models.dart'; -import '../../redux/app/app_state.dart'; -import '../../utils/optional.dart'; +import 'package:invoiceninja/data/models/models.dart'; +import 'package:invoiceninja/redux/app/app_state.dart'; +import 'package:invoiceninja/utils/optional.dart'; bool isLoadingSelector(AppState state) => state.isLoading; diff --git a/lib/routes.dart b/lib/routes.dart index 83101ebbe..463676c27 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,5 +1,6 @@ class NinjaRoutes { - static final dashboard = "/"; + static final login = "/"; + static final dashboard = "/dashboard"; static final clientList = "/clientList"; static final productList = "/productList"; } \ No newline at end of file diff --git a/lib/ui/app/app_loading.dart b/lib/ui/app/app_loading.dart index cb0045e38..777354a7e 100644 --- a/lib/ui/app/app_loading.dart +++ b/lib/ui/app/app_loading.dart @@ -2,8 +2,8 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux/redux.dart'; -import '../../redux/app/app_state.dart'; -import '../../redux/product/product_selectors.dart'; +import 'package:invoiceninja/redux/app/app_state.dart'; +import 'package:invoiceninja/redux/product/product_selectors.dart'; class AppLoading extends StatelessWidget { final Function(BuildContext context, bool isLoading) builder; diff --git a/lib/ui/app/login_screen.dart b/lib/ui/app/login_screen.dart new file mode 100644 index 000000000..8397ae56c --- /dev/null +++ b/lib/ui/app/login_screen.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; + +class LoginScreen extends StatefulWidget { + static String tag = 'login-page'; + @override + _LoginScreenState createState() => new _LoginScreenState(); +} + +class _LoginScreenState extends State { + @override + Widget build(BuildContext context) { + final email = TextFormField( + keyboardType: TextInputType.emailAddress, + autofocus: false, + validator: (value) { + if (value.isEmpty) { + return 'This field is required'; + } + }, + decoration: InputDecoration( + labelText: 'Email', + contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + ), + ); + + final password = TextFormField( + autofocus: false, + obscureText: true, + decoration: InputDecoration( + labelText: 'Password', + contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + ), + ); + + final loginButton = Padding( + padding: EdgeInsets.symmetric(vertical: 16.0), + child: Material( + //borderRadius: BorderRadius.circular(30.0), + shadowColor: Colors.lightBlueAccent.shade100, + elevation: 5.0, + child: MaterialButton( + minWidth: 200.0, + height: 42.0, + onPressed: () { + //Navigator.of(context).pushNamed(HomeScreen.tag); + }, + color: Colors.lightBlueAccent, + child: Text('Log In', style: TextStyle(color: Colors.white)), + ), + ), + ); + + /* + final forgotLabel = FlatButton( + child: Text( + 'Forgot password?', + style: TextStyle(color: Colors.black54), + ), + onPressed: () {}, + ); + */ + + return Scaffold( + //backgroundColor: Colors.white, + body: Center( + child: ListView( + shrinkWrap: true, + padding: EdgeInsets.only(left: 24.0, right: 24.0), + children: [ + SizedBox(height: 48.0), + email, + SizedBox(height: 8.0), + password, + SizedBox(height: 24.0), + loginButton, + //forgotLabel + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/ui/client/client_list.dart b/lib/ui/client/client_list.dart index d34338330..fc82ecdd9 100644 --- a/lib/ui/client/client_list.dart +++ b/lib/ui/client/client_list.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../../keys.dart'; -import '../../ui/app/sidebar.dart'; +import 'package:invoiceninja/keys.dart'; +import 'package:invoiceninja/ui/app/sidebar.dart'; class ClientList extends StatelessWidget { ClientList() : super(key: NinjaKeys.clientList); diff --git a/lib/ui/dashboard.dart b/lib/ui/dashboard_screen.dart similarity index 85% rename from lib/ui/dashboard.dart rename to lib/ui/dashboard_screen.dart index 86b406469..1bb802452 100644 --- a/lib/ui/dashboard.dart +++ b/lib/ui/dashboard_screen.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../keys.dart'; -import '../ui/app/sidebar.dart'; +import 'package:invoiceninja/keys.dart'; +import 'package:invoiceninja/ui/app/sidebar.dart'; class Dashboard extends StatelessWidget { Dashboard() : super(key: NinjaKeys.dashboard); diff --git a/lib/ui/product/product_details.dart b/lib/ui/product/product_details.dart index 9e0cd9932..8911b4800 100644 --- a/lib/ui/product/product_details.dart +++ b/lib/ui/product/product_details.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -//import '../../containers/edit_product.dart'; -import '../../data/models/models.dart'; +//import 'package:invoiceninja/containers/edit_product.dart'; +import 'package:invoiceninja/data/models/models.dart'; class DetailsScreen extends StatelessWidget { final ProductEntity product; diff --git a/lib/ui/product/product_details_vm.dart b/lib/ui/product/product_details_vm.dart index d7552eb06..a2cbe8ac9 100644 --- a/lib/ui/product/product_details_vm.dart +++ b/lib/ui/product/product_details_vm.dart @@ -6,11 +6,11 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux/redux.dart'; -import '../../redux/product/product_actions.dart'; -import '../../data/models/models.dart'; -import '../../ui/product/product_details.dart'; -import '../../redux/product/product_selectors.dart'; -import '../../redux/app/app_state.dart'; +import 'package:invoiceninja/redux/product/product_actions.dart'; +import 'package:invoiceninja/data/models/models.dart'; +import 'package:invoiceninja/ui/product/product_details.dart'; +import 'package:invoiceninja/redux/product/product_selectors.dart'; +import 'package:invoiceninja/redux/app/app_state.dart'; class ProductDetails extends StatelessWidget { final int id; diff --git a/lib/ui/product/product_item.dart b/lib/ui/product/product_item.dart index f335e50a7..36603e57c 100644 --- a/lib/ui/product/product_item.dart +++ b/lib/ui/product/product_item.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../data/models/models.dart'; -import '../../keys.dart'; +import 'package:invoiceninja/data/models/models.dart'; +import 'package:invoiceninja/keys.dart'; class ProductItem extends StatelessWidget { final DismissDirectionCallback onDismissed; diff --git a/lib/ui/product/product_list.dart b/lib/ui/product/product_list.dart index 6ac76b95e..a8f29cd16 100644 --- a/lib/ui/product/product_list.dart +++ b/lib/ui/product/product_list.dart @@ -1,11 +1,11 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import '../../ui/app/app_loading.dart'; -import '../../ui/product/product_details_vm.dart'; -import '../../data/models/models.dart'; -import '../../ui/app/loading_indicator.dart'; -import '../../ui/product/product_item.dart'; -import '../../keys.dart'; +import 'package:invoiceninja/ui/app/app_loading.dart'; +import 'package:invoiceninja/ui/product/product_details_vm.dart'; +import 'package:invoiceninja/data/models/models.dart'; +import 'package:invoiceninja/ui/app/loading_indicator.dart'; +import 'package:invoiceninja/ui/product/product_item.dart'; +import 'package:invoiceninja/keys.dart'; class ProductList extends StatelessWidget { final List products; diff --git a/lib/ui/product/product_list_vm.dart b/lib/ui/product/product_list_vm.dart index 50eb3f7a5..69086fc6a 100644 --- a/lib/ui/product/product_list_vm.dart +++ b/lib/ui/product/product_list_vm.dart @@ -2,11 +2,11 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux/redux.dart'; -import '../../redux/product/product_actions.dart'; -import '../../data/models/models.dart'; -import '../../ui/product/product_list.dart'; -import '../../redux/product/product_selectors.dart'; -import '../../redux/app/app_state.dart'; +import 'package:invoiceninja/redux/product/product_actions.dart'; +import 'package:invoiceninja/data/models/models.dart'; +import 'package:invoiceninja/ui/product/product_list.dart'; +import 'package:invoiceninja/redux/product/product_selectors.dart'; +import 'package:invoiceninja/redux/app/app_state.dart'; class FilteredProducts extends StatelessWidget { FilteredProducts({Key key}) : super(key: key); diff --git a/lib/ui/product/product_home.dart b/lib/ui/product/product_screen.dart similarity index 85% rename from lib/ui/product/product_home.dart rename to lib/ui/product/product_screen.dart index 7e7489af4..490f6a4a9 100644 --- a/lib/ui/product/product_home.dart +++ b/lib/ui/product/product_screen.dart @@ -3,9 +3,9 @@ // in the LICENSE file. import 'package:flutter/material.dart'; -import '../../data/models/models.dart'; -import '../../keys.dart'; -import '../../ui/product/product_list_vm.dart'; +import 'package:invoiceninja/data/models/models.dart'; +import 'package:invoiceninja/keys.dart'; +import 'package:invoiceninja/ui/product/product_list_vm.dart'; class ProductHome extends StatelessWidget { ProductHome() : super(key: NinjaKeys.productHome);