redux main state/main_state.dart
parent
71fb01ee93
commit
1d18e70208
|
|
@ -0,0 +1,33 @@
|
||||||
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
|
||||||
|
const String Category_tableName = 'goods_category';
|
||||||
|
const String Category_columnId = 'id';
|
||||||
|
const String Category_columnParentIn = 'parent_id';
|
||||||
|
const String Category_columnName = 'name';
|
||||||
|
|
||||||
|
class Category {
|
||||||
|
int id;
|
||||||
|
int parentIn;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
var map = <String, dynamic>{
|
||||||
|
Category_columnParentIn: parentIn,
|
||||||
|
Category_columnName: name,
|
||||||
|
};
|
||||||
|
if (id != null) {
|
||||||
|
map[Category_columnId] = id;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
Category();
|
||||||
|
|
||||||
|
Category.fromMap(Map<String, dynamic> map) {
|
||||||
|
id = map[Category_columnId];
|
||||||
|
parentIn = map[Category_columnParentIn];
|
||||||
|
name = map[Category_columnName];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
|
||||||
|
const String Goog_tableName = 'goods';
|
||||||
|
const String Goog_columnId = 'id';
|
||||||
|
const String Goog_columnArticul = 'articul';
|
||||||
|
const String Goog_columnName = 'name';
|
||||||
|
const String Goog_columnPrice = 'price';
|
||||||
|
const String Goog_columnCategoryId = 'category_id';
|
||||||
|
const String Goog_columnEan = 'ean';
|
||||||
|
|
||||||
|
class Good {
|
||||||
|
int id;
|
||||||
|
int articul;
|
||||||
|
String name;
|
||||||
|
double price;
|
||||||
|
int categoryId;
|
||||||
|
String ean;
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
var map = <String, dynamic>{
|
||||||
|
Goog_columnArticul: articul,
|
||||||
|
Goog_columnName: name,
|
||||||
|
Goog_columnPrice: price,
|
||||||
|
Goog_columnCategoryId: categoryId,
|
||||||
|
Goog_columnEan: ean,
|
||||||
|
};
|
||||||
|
if (id != null) {
|
||||||
|
map[Goog_columnId] = id;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
Good();
|
||||||
|
|
||||||
|
Good.fromMap(Map<String, dynamic> map) {
|
||||||
|
id = map[Goog_columnId];
|
||||||
|
articul = map[Goog_columnArticul];
|
||||||
|
name = map[Goog_columnName];
|
||||||
|
price = map[Goog_columnPrice]?.toDouble();
|
||||||
|
categoryId = map[Goog_columnCategoryId];
|
||||||
|
ean = map[Goog_columnEan];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
|
||||||
|
const String Service_tableName = 'services';
|
||||||
|
const String Service_columnId = 'id';
|
||||||
|
const String Service_columnArticul = 'articul';
|
||||||
|
const String Service_columnName = 'name';
|
||||||
|
const String Service_columnPrice = 'price';
|
||||||
|
const String Service_columnCategoryId = 'category_id';
|
||||||
|
const String Service_columnEan = 'ean';
|
||||||
|
|
||||||
|
class Service {
|
||||||
|
int id;
|
||||||
|
int articul;
|
||||||
|
String name;
|
||||||
|
double price;
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
var map = <String, dynamic>{
|
||||||
|
Service_columnArticul: articul,
|
||||||
|
Service_columnName: name,
|
||||||
|
Service_columnPrice: price,
|
||||||
|
};
|
||||||
|
if (id != null) {
|
||||||
|
map[Service_columnId] = id;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
Service();
|
||||||
|
|
||||||
|
Service.fromMap(Map<String, dynamic> map) {
|
||||||
|
id = map[Service_columnId];
|
||||||
|
articul = map[Service_columnArticul];
|
||||||
|
name = map[Service_columnName];
|
||||||
|
price = map[Service_columnPrice]?.toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
|
||||||
|
import '../core/services/DbService.dart';
|
||||||
|
|
||||||
import '../core/services/ApiService.dart';
|
import '../core/services/ApiService.dart';
|
||||||
import '../core/services/dialog_service.dart';
|
import '../core/services/dialog_service.dart';
|
||||||
import '../core/logger.dart';
|
import '../core/logger.dart';
|
||||||
|
|
@ -17,8 +21,16 @@ class LocatorInjector {
|
||||||
locator.registerLazySingleton<ApiService>(() => ApiService());
|
locator.registerLazySingleton<ApiService>(() => ApiService());
|
||||||
_log.d('Initializing Navigator Service');
|
_log.d('Initializing Navigator Service');
|
||||||
locator.registerLazySingleton<NavigatorService>(() => NavigatorService());
|
locator.registerLazySingleton<NavigatorService>(() => NavigatorService());
|
||||||
_log.d('Initializing Dialog Service');
|
_log.d('Initializing Dialog Service');
|
||||||
locator.registerLazySingleton<DialogService>(() => DialogService());
|
locator.registerLazySingleton<DialogService>(() => DialogService());
|
||||||
|
_log.d('Initializing DbService Service');
|
||||||
|
locator.registerLazySingleton<DbService>(() => DbService.instance);
|
||||||
|
|
||||||
|
|
||||||
|
// depencies
|
||||||
|
|
||||||
|
|
||||||
|
_log.d('Initializing DataService Service');
|
||||||
|
locator.registerLazySingleton<DataService>(() => DataService());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class Choice {
|
||||||
|
const Choice({this.title, this.icon, this.command});
|
||||||
|
final String command;
|
||||||
|
final String title;
|
||||||
|
final IconData icon;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
class DictDao {
|
||||||
|
final int id;
|
||||||
|
final String name;
|
||||||
|
DictDao({ this.id, this.name});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
class Message {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
Message({this.message});
|
||||||
|
|
||||||
|
|
||||||
|
static Message fromJson(Map<String, dynamic> data) => Message(message : data['message']);
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
class ProductDao {
|
class ProductDao {
|
||||||
final String name;
|
final String name;
|
||||||
final double price;
|
final num price;
|
||||||
int count;
|
num count;
|
||||||
|
|
||||||
|
|
||||||
ProductDao( {this.name, this.price, this.count});
|
ProductDao( {this.name, this.price, this.count});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
class Response<T> {
|
||||||
|
final T body;
|
||||||
|
final int status;
|
||||||
|
final bool operation;
|
||||||
|
|
||||||
|
Response({this.body, this.operation, this.status});
|
||||||
|
|
||||||
|
factory Response.fromJson(Map<String, dynamic> data, Function parser) {
|
||||||
|
return Response(
|
||||||
|
body: parser(data['body']),
|
||||||
|
status: data['status'],
|
||||||
|
operation: data['operation']);
|
||||||
|
}
|
||||||
|
factory Response.fromJsonDynamic(Map<String, dynamic> data) {
|
||||||
|
return Response(
|
||||||
|
body: data['body'],
|
||||||
|
status: data['status'],
|
||||||
|
operation: data['operation']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
class Session {
|
|
||||||
String token;
|
|
||||||
int appCompanyId;
|
|
||||||
int kassaId;
|
|
||||||
int userId;
|
|
||||||
String message;
|
|
||||||
Session();
|
|
||||||
|
|
||||||
|
|
||||||
Session.fromData(String token ,Map<String, dynamic> data)
|
|
||||||
: token = token,
|
|
||||||
appCompanyId = data['app_company_id'],
|
|
||||||
userId = data['user_id'],
|
|
||||||
message = data['message'],
|
|
||||||
kassaId = data['kassa_id'];
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
||||||
import 'package:provider/single_child_widget.dart';
|
import 'package:provider/single_child_widget.dart';
|
||||||
|
|
||||||
import '../core/locator.dart';
|
import '../core/locator.dart';
|
||||||
|
|
@ -15,16 +17,21 @@ class ProviderInjector {
|
||||||
];
|
];
|
||||||
|
|
||||||
static List<SingleChildWidget> _independentServices = [
|
static List<SingleChildWidget> _independentServices = [
|
||||||
Provider.value(value: locator<NavigatorService>()),
|
// Provider.value(value: locator<NavigatorService>()),
|
||||||
Provider.value(value: locator<ApiService>()),
|
// Provider.value(value: locator<ApiService>()),
|
||||||
|
// Provider.value(value: locator<DbService>()),
|
||||||
];
|
];
|
||||||
|
|
||||||
static List<SingleChildWidget> _dependentServices = [
|
static List<SingleChildWidget> _dependentServices = [
|
||||||
ProxyProvider<ApiService, AuthenticationService>(
|
// ProxyProvider<ApiService, AuthenticationService>(
|
||||||
update: (context, api, authenticationService) =>
|
// update: (context, api, authenticationService) =>
|
||||||
AuthenticationService(api: api),
|
// AuthenticationService(api: api),
|
||||||
)
|
// ),
|
||||||
|
// ProxyProvider2< ApiService ,DbService, DataService>(
|
||||||
|
// update: (context,api , db, authenticationService) =>
|
||||||
|
// DataService(api: api, db: db),
|
||||||
|
// )
|
||||||
];
|
];
|
||||||
|
|
||||||
static List<SingleChildWidget> _consumableServices = [];
|
static List<SingleChildWidget> _consumableServices = [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@ import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/session.dart';
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Message.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Response.dart';
|
||||||
import '../models/authResponse.dart';
|
import '../models/authResponse.dart';
|
||||||
|
|
||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
/// The service responsible for networking requests
|
/// The service responsible for networking requests
|
||||||
|
|
@ -21,20 +22,25 @@ class ApiService extends BaseService {
|
||||||
};
|
};
|
||||||
var response = await requestFormData('/authenticate', requestBody);
|
var response = await requestFormData('/authenticate', requestBody);
|
||||||
final respStr = await response.stream.bytesToString();
|
final respStr = await response.stream.bytesToString();
|
||||||
print(respStr);
|
AuthResponse aman = AuthResponse.fromJson(json.decode(respStr));
|
||||||
AuthResponse aman = AuthResponse.fromJson(json.decode(respStr));
|
|
||||||
return aman.body;
|
return aman.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Session> isActive(String token) async {
|
Future<Response<Message>> isActive(String token) async {
|
||||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
var response = await requestFormData('/test_auth', requestBody);
|
var response = await requestFormData('/test_auth', requestBody);
|
||||||
final respStr = await response.stream.bytesToString();
|
final respStr = await response.stream.bytesToString();
|
||||||
return Session.fromData(token, json.decode(respStr)['body']);
|
return Response.fromJson(json.decode(respStr), Message.fromJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<http.StreamedResponse> requestFormData(
|
Future<Response<Message>> logout(String token) async {
|
||||||
String point, Map<String, String> requestBody) async {
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/logout', requestBody);
|
||||||
|
final respStr = await response.stream.bytesToString();
|
||||||
|
return Response.fromJson(json.decode(respStr), Message.fromJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<http.StreamedResponse> requestFormData(String point, Map<String, String> requestBody) async {
|
||||||
Map<String, String> headers = <String, String>{
|
Map<String, String> headers = <String, String>{
|
||||||
HttpHeaders.contentTypeHeader: "multipart/form-data",
|
HttpHeaders.contentTypeHeader: "multipart/form-data",
|
||||||
HttpHeaders.cacheControlHeader: "no-cache"
|
HttpHeaders.cacheControlHeader: "no-cache"
|
||||||
|
|
@ -48,4 +54,26 @@ class ApiService extends BaseService {
|
||||||
return await request.send();
|
return await request.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> getGoodsFromServer(String token) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/goods', requestBody);
|
||||||
|
final respStr = await response.stream.bytesToString();
|
||||||
|
print(respStr);
|
||||||
|
return Response.fromJsonDynamic(json.decode(respStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> getCategoryFromServer(String token) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/goods_category', requestBody);
|
||||||
|
final respStr = await response.stream.bytesToString();
|
||||||
|
print(respStr);
|
||||||
|
return Response.fromJsonDynamic(json.decode(respStr));
|
||||||
|
}
|
||||||
|
Future<Response<dynamic>> getServiceFromServer(String token) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/services', requestBody);
|
||||||
|
final respStr = await response.stream.bytesToString();
|
||||||
|
print(respStr);
|
||||||
|
return Response.fromJsonDynamic(json.decode(respStr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Response.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
||||||
|
|
||||||
|
import 'ApiService.dart';
|
||||||
|
|
||||||
|
class DataService extends BaseService {
|
||||||
|
final ApiService _api = locator<ApiService>();
|
||||||
|
final DbService _db = locator<DbService>();
|
||||||
|
|
||||||
|
Future<List<Category>> getCategoriesByParentId ( {int parentId} ) async {
|
||||||
|
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(Category_tableName, '$Category_columnParentIn = ?', [parentId ?? 0 ]);
|
||||||
|
return list.map((e) => Category.fromMap(e)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Good>> getGoodsByCategoryId ( {int categoryId} ) async {
|
||||||
|
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(Goog_tableName, '$Goog_columnCategoryId = ?', [categoryId ?? 0]);
|
||||||
|
return list.map((e) => Good.fromMap(e)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> getDataFromServer(String token) async {
|
||||||
|
try {
|
||||||
|
|
||||||
|
Response<dynamic> goods = await _api.getGoodsFromServer(token);
|
||||||
|
Response<dynamic> categories = await _api.getCategoryFromServer(token);
|
||||||
|
Response<dynamic> services = await _api.getServiceFromServer(token);
|
||||||
|
await _db.deleteAll(Goog_tableName);
|
||||||
|
await _db.deleteAll(Category_tableName);
|
||||||
|
await _db.deleteAll(Service_tableName);
|
||||||
|
log.i('All tables cleaned');
|
||||||
|
for (var key in goods.body.keys) {
|
||||||
|
print(goods.body[key]);
|
||||||
|
Good row = Good.fromMap(goods.body[key]);
|
||||||
|
_db.insert(Goog_tableName,row.toMap());
|
||||||
|
}
|
||||||
|
log.i('Inserted ${goods.body.length} to table $Goog_tableName');
|
||||||
|
|
||||||
|
for (var el in categories.body) {
|
||||||
|
print(el);
|
||||||
|
Category row = Category.fromMap(el);
|
||||||
|
_db.insert(Category_tableName,row.toMap());
|
||||||
|
}
|
||||||
|
log.i('Inserted ${categories.body.length} to table $Category_tableName');
|
||||||
|
|
||||||
|
for (var key in services.body.keys) {
|
||||||
|
print(services.body[key]);
|
||||||
|
Service row = Service.fromMap(services.body[key]);
|
||||||
|
_db.insert(Service_tableName,row.toMap());
|
||||||
|
}
|
||||||
|
log.i('Inserted ${services.body.length} to table $Service_tableName');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
||||||
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
import 'package:path/path.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
|
class DbService extends BaseService {
|
||||||
|
static final _databaseName = "AmanFlutterDb.db";
|
||||||
|
static final _databaseVersion = 5;
|
||||||
|
|
||||||
|
// make this a singleton class
|
||||||
|
DbService._privateConstructor();
|
||||||
|
|
||||||
|
static final DbService instance = DbService._privateConstructor();
|
||||||
|
|
||||||
|
// only have a single app-wide reference to the database
|
||||||
|
static Database _database;
|
||||||
|
|
||||||
|
Future<Database> get database async {
|
||||||
|
if (_database != null) return _database;
|
||||||
|
// lazily instantiate the db the first time it is accessed
|
||||||
|
_database = await _initDatabase();
|
||||||
|
return _database;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this opens the database (and creates it if it doesn't exist)
|
||||||
|
_initDatabase() async {
|
||||||
|
Directory documentsDirectory = await getApplicationDocumentsDirectory();
|
||||||
|
String path = join(documentsDirectory.path, _databaseName);
|
||||||
|
print(path);
|
||||||
|
return await openDatabase(path,
|
||||||
|
version: _databaseVersion,
|
||||||
|
onUpgrade: _onUpdate,
|
||||||
|
onCreate: _onCreate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Future _onUpdate(Database db, int oldVersion, int newVersion) async {
|
||||||
|
print('update from $oldVersion to $newVersion');
|
||||||
|
//Goods table
|
||||||
|
await db.execute('''
|
||||||
|
DROP TABLE IF EXISTS $Goog_tableName;
|
||||||
|
DROP TABLE IF EXISTS $Category_tableName;
|
||||||
|
DROP TABLE IF EXISTS $Service_tableName;
|
||||||
|
''');
|
||||||
|
_onCreate(db, newVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _onCreate(Database db, int version) async {
|
||||||
|
print('create tables');
|
||||||
|
//Goods table
|
||||||
|
await db.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS $Goog_tableName (
|
||||||
|
$Goog_columnId integer primary key unique,
|
||||||
|
$Goog_columnArticul integer not null,
|
||||||
|
$Goog_columnName text not null,
|
||||||
|
$Goog_columnPrice real not null,
|
||||||
|
$Goog_columnCategoryId integer not null,
|
||||||
|
$Goog_columnEan text);
|
||||||
|
''');
|
||||||
|
await db.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS $Category_tableName (
|
||||||
|
$Category_columnId integer primary key unique,
|
||||||
|
$Category_columnName text not null,
|
||||||
|
$Category_columnParentIn integer);
|
||||||
|
''');
|
||||||
|
await db.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS $Service_tableName (
|
||||||
|
$Service_columnId integer primary key unique,
|
||||||
|
$Service_columnArticul integer not null,
|
||||||
|
$Service_columnName text not null,
|
||||||
|
$Service_columnPrice real not null);
|
||||||
|
''');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inserts a row in the database where each key in the Map is a column name
|
||||||
|
// and the value is the column value. The return value is the id of the
|
||||||
|
// inserted row.
|
||||||
|
Future<int> insert(String table, Map<String, dynamic> row) async {
|
||||||
|
Database db = await instance.database;
|
||||||
|
return await db.insert(table, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All of the rows are returned as a list of maps, where each map is
|
||||||
|
// a key-value list of columns.
|
||||||
|
Future<List<Map<String, dynamic>>> queryAllRows(String table) async {
|
||||||
|
Database db = await instance.database;
|
||||||
|
return await db.query(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Map<String, dynamic>>> queryRowsWithWhere(String table, String where, List<dynamic> args ) async {
|
||||||
|
Database db = await instance.database;
|
||||||
|
return await db.query(table, where: where, whereArgs: args );
|
||||||
|
}
|
||||||
|
|
||||||
|
// All of the methods (insert, query, update, delete) can also be done using
|
||||||
|
// raw SQL commands. This method uses a raw query to give the row count.
|
||||||
|
Future<int> queryRowCount(String table) async {
|
||||||
|
Database db = await instance.database;
|
||||||
|
return Sqflite.firstIntValue(
|
||||||
|
await db.rawQuery('SELECT COUNT(*) FROM $table'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are assuming here that the id column in the map is set. The other
|
||||||
|
// column values will be used to update the row.
|
||||||
|
Future<int> update(String table, Map<String, dynamic> row) async {
|
||||||
|
Database db = await instance.database;
|
||||||
|
int id = row['id'];
|
||||||
|
return await db.update(table, row, where: 'id = ?', whereArgs: [id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deletes the row specified by the id. The number of affected rows is
|
||||||
|
// returned. This should be 1 as long as the row exists.
|
||||||
|
Future<int> delete(String table, int id) async {
|
||||||
|
Database db = await instance.database;
|
||||||
|
return await db.delete(table, where: 'id = ?', whereArgs: [id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> deleteAll(String table) async {
|
||||||
|
Database db = await instance.database;
|
||||||
|
return await db.delete(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future close() async => instance.close();
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/session.dart';
|
import 'package:aman_kassa_flutter/core/models/Message.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Response.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/user.dart';
|
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/authResponse.dart';
|
import 'package:aman_kassa_flutter/core/models/authResponse.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
@ -14,9 +15,6 @@ class AuthenticationService extends BaseService {
|
||||||
User _currentUser;
|
User _currentUser;
|
||||||
User get currentUser => _currentUser;
|
User get currentUser => _currentUser;
|
||||||
|
|
||||||
Session _session;
|
|
||||||
Session get currentSession => _session;
|
|
||||||
|
|
||||||
Future<AuthBody> loginWithEmail({
|
Future<AuthBody> loginWithEmail({
|
||||||
@required String email,
|
@required String email,
|
||||||
@required String password,
|
@required String password,
|
||||||
|
|
@ -34,9 +32,18 @@ class AuthenticationService extends BaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isUserLoggedIn(String token) async {
|
Future<bool> isUserLoggedIn(String token) async {
|
||||||
Session session = await _api.isActive(token);
|
Response<Message> session = await _api.isActive(token);
|
||||||
if ("OK" == session.message) {
|
if ("OK" == session.body.message) {
|
||||||
_session = session;
|
//_session = session;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> logout(String token) async {
|
||||||
|
Response<Message> session = await _api.logout(token);
|
||||||
|
if ("logout" == session.body.message) {
|
||||||
|
//_session = session;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
//general
|
//general
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
//service & tools
|
//service & tools
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'core/locator.dart';
|
import 'core/locator.dart';
|
||||||
import 'core/providers.dart';
|
import 'core/providers.dart';
|
||||||
import 'core/router.dart';
|
import 'core/router.dart';
|
||||||
|
|
@ -19,34 +23,37 @@ void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
//initialize locator
|
//initialize locator
|
||||||
await LocatorInjector.setupLocator();
|
await LocatorInjector.setupLocator();
|
||||||
|
|
||||||
|
await Redux.init();
|
||||||
runApp(MainApplication());
|
runApp(MainApplication());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MainApplication extends StatelessWidget {
|
class MainApplication extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiProvider(
|
return StoreProvider<AppState>(
|
||||||
providers: ProviderInjector.providers.toList(),
|
store: Redux.store,
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
primaryColor: primaryColor,
|
primaryColor: primaryColor,
|
||||||
accentColor: yellowColor,
|
accentColor: yellowColor,
|
||||||
scaffoldBackgroundColor: Colors.white,
|
scaffoldBackgroundColor: Colors.white,
|
||||||
textTheme: GoogleFonts.latoTextTheme(
|
textTheme: GoogleFonts.latoTextTheme(
|
||||||
Theme.of(context).textTheme,
|
Theme.of(context).textTheme,
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
builder: (context, child) => Navigator(
|
||||||
|
key: locator<DialogService>().dialogNavigationKey,
|
||||||
|
onGenerateRoute: (settings) => MaterialPageRoute(
|
||||||
|
builder: (context) => DialogManager(child: child)),
|
||||||
|
),
|
||||||
|
navigatorKey: locator<NavigatorService>().navigatorKey,
|
||||||
|
home: StartUpView(), // first page
|
||||||
|
onGenerateRoute: generateRoute,
|
||||||
),
|
),
|
||||||
debugShowCheckedModeBanner: false,
|
);
|
||||||
builder: (context, child) => Navigator(
|
|
||||||
key: locator<DialogService>().dialogNavigationKey,
|
|
||||||
onGenerateRoute: (settings) => MaterialPageRoute(
|
|
||||||
builder: (context) => DialogManager(child: child)),
|
|
||||||
),
|
|
||||||
navigatorKey: locator<NavigatorService>().navigatorKey,
|
|
||||||
home: StartUpView(), // first page
|
|
||||||
onGenerateRoute: generateRoute,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/DictDao.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
|
||||||
|
import '../store.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class SetMainStateAction {
|
||||||
|
final MainState mainState;
|
||||||
|
|
||||||
|
SetMainStateAction(this.mainState);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ApiService _api = locator<ApiService>();
|
||||||
|
final DataService _dataService = locator<DataService>();
|
||||||
|
final NavigatorService _navigation = locator<NavigatorService>();
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> backBottomElement(Store<AppState> store) async {
|
||||||
|
List<DictDao> prevCategories = store.state.mainState.prevCategories;
|
||||||
|
DictDao last = prevCategories.removeLast();
|
||||||
|
if(last!=null) {
|
||||||
|
store.dispatch(SetMainStateAction(MainState(prevCategories: prevCategories)));
|
||||||
|
store.dispatch(selectBottomElement(last.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> selectBottomElement(int parentId) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetMainStateAction(MainState(bottomSheetLoading: true)));
|
||||||
|
try {
|
||||||
|
List<DictDao> prevCategories = store.state.mainState.prevCategories;
|
||||||
|
if(parentId == 0) {
|
||||||
|
prevCategories = [];
|
||||||
|
}
|
||||||
|
store.state.mainState.bottomSheetElements.forEach((element) {
|
||||||
|
if(element is Category && element.id == parentId){
|
||||||
|
prevCategories.add(DictDao(id: element.parentIn, name: element.name));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
List<Category> categories = await _dataService.getCategoriesByParentId(parentId: parentId);
|
||||||
|
List<Good> goods = await _dataService.getGoodsByCategoryId(categoryId: parentId);
|
||||||
|
List _bottomSheetElements = [];
|
||||||
|
_bottomSheetElements.addAll(categories);
|
||||||
|
_bottomSheetElements.addAll(goods);
|
||||||
|
store.dispatch(
|
||||||
|
SetMainStateAction(
|
||||||
|
MainState(
|
||||||
|
bottomSheetLoading: false,
|
||||||
|
bottomSheetElements: _bottomSheetElements,
|
||||||
|
prevCategories: prevCategories
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
store.dispatch(SetMainStateAction(MainState(bottomSheetLoading: false)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Message.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/authResponse.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Response.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
import '../store.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class SetUserStateAction {
|
||||||
|
final UserState userState;
|
||||||
|
SetUserStateAction(this.userState);
|
||||||
|
}
|
||||||
|
final ApiService _api = locator<ApiService>();
|
||||||
|
final NavigatorService _navigation = locator<NavigatorService>();
|
||||||
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
|
||||||
|
Future<void> checkUserAction(Store<AppState> store) async {
|
||||||
|
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||||
|
try {
|
||||||
|
Response<Message> session = await _api.isActive('test');
|
||||||
|
bool isAuthenticated = "OK" == session.body.message;
|
||||||
|
store.dispatch(
|
||||||
|
SetUserStateAction(
|
||||||
|
UserState(
|
||||||
|
isLoading: false,
|
||||||
|
isAuthenticated: isAuthenticated,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if(!isAuthenticated){
|
||||||
|
_navigation.replace(LoginViewRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
store.dispatch(SetUserStateAction(UserState(isLoading: false)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ThunkAction<AppState> authenticate(String email, String password) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||||
|
try {
|
||||||
|
AuthBody result = await _api.authenticate(email, password);
|
||||||
|
store.dispatch(SetUserStateAction(UserState(
|
||||||
|
isLoading: false,
|
||||||
|
loginFormMessage: LoginFormMessage(email: result.email?.join(","), password: result.password?.join(","), message: result.message),
|
||||||
|
user: result.user
|
||||||
|
)));
|
||||||
|
if(result.user == null && result.message!=null){
|
||||||
|
_dialogService.showDialog(title: 'Warning', buttonTitle: 'Ok', description: result.message);
|
||||||
|
}
|
||||||
|
if(result.user!=null) {
|
||||||
|
_navigation.replace(HomeViewRoute);
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
store.dispatch(SetUserStateAction(UserState(isLoading: false)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
||||||
|
|
||||||
|
mainReducer(MainState prevState, SetMainStateAction action) {
|
||||||
|
final payload = action.mainState;
|
||||||
|
return prevState.copyWith(
|
||||||
|
bottomSheetElements: payload.bottomSheetElements,
|
||||||
|
bottomSheetLoading: payload.bottomSheetLoading,
|
||||||
|
prevCategories: payload.prevCategories,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
|
|
||||||
|
|
||||||
|
userReducer(UserState prevState, SetUserStateAction action) {
|
||||||
|
final payload = action.userState;
|
||||||
|
return prevState.copyWith(
|
||||||
|
isError: payload.isError,
|
||||||
|
isLoading: payload.isLoading,
|
||||||
|
user: payload.user,
|
||||||
|
isAuthenticated: payload.isAuthenticated,
|
||||||
|
loginFormMessage: payload.loginFormMessage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/models/DictDao.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class MainState {
|
||||||
|
final List bottomSheetElements;
|
||||||
|
final bool bottomSheetLoading;
|
||||||
|
final List<DictDao> prevCategories;
|
||||||
|
|
||||||
|
MainState({this.bottomSheetElements, this.bottomSheetLoading, this.prevCategories});
|
||||||
|
|
||||||
|
factory MainState.initial() => MainState(
|
||||||
|
bottomSheetElements: [],
|
||||||
|
bottomSheetLoading: false,
|
||||||
|
prevCategories: [],
|
||||||
|
);
|
||||||
|
|
||||||
|
MainState copyWith({
|
||||||
|
@required bottomSheetElements,
|
||||||
|
@required bottomSheetLoading,
|
||||||
|
@required prevCategories,
|
||||||
|
}) {
|
||||||
|
return MainState(
|
||||||
|
bottomSheetElements: bottomSheetElements ?? this.bottomSheetElements,
|
||||||
|
bottomSheetLoading: bottomSheetLoading ?? this.bottomSheetLoading,
|
||||||
|
prevCategories: prevCategories ?? this.prevCategories,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class UserState {
|
||||||
|
final bool isError;
|
||||||
|
final bool isLoading;
|
||||||
|
final bool isAuthenticated;
|
||||||
|
final LoginFormMessage loginFormMessage;
|
||||||
|
final User user;
|
||||||
|
|
||||||
|
UserState({
|
||||||
|
this.isError,
|
||||||
|
this.isLoading,
|
||||||
|
this.isAuthenticated,
|
||||||
|
this.user,
|
||||||
|
this.loginFormMessage
|
||||||
|
});
|
||||||
|
|
||||||
|
factory UserState.initial() => UserState(
|
||||||
|
isLoading: false,
|
||||||
|
isError: false,
|
||||||
|
isAuthenticated: false,
|
||||||
|
loginFormMessage: LoginFormMessage(),
|
||||||
|
);
|
||||||
|
|
||||||
|
UserState copyWith({
|
||||||
|
@required bool isError,
|
||||||
|
@required bool isLoading,
|
||||||
|
@required User user,
|
||||||
|
@required bool isAuthenticated,
|
||||||
|
@required LoginFormMessage loginFormMessage,
|
||||||
|
}) {
|
||||||
|
return UserState(
|
||||||
|
isError: isError ?? this.isError,
|
||||||
|
isLoading: isLoading ?? this.isLoading,
|
||||||
|
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
||||||
|
user: user ?? this.user,
|
||||||
|
loginFormMessage: loginFormMessage ?? this.loginFormMessage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoginFormMessage {
|
||||||
|
final String email;
|
||||||
|
final String password;
|
||||||
|
final String message;
|
||||||
|
LoginFormMessage({this.email, this.password, this.message});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/reducers/main_reducer.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/reducers/user_reducer.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
|
||||||
|
|
||||||
|
//reducer context
|
||||||
|
AppState appReducer(AppState state, dynamic action) {
|
||||||
|
|
||||||
|
if (action is SetUserStateAction) { /** UserAction **/
|
||||||
|
final nextUserState = userReducer(state.userState, action);
|
||||||
|
return state.copyWith(userState: nextUserState);
|
||||||
|
} else if(action is SetMainStateAction) { /** MainAction **/
|
||||||
|
final nextMainState = mainReducer(state.mainState, action);
|
||||||
|
return state.copyWith(mainState: nextMainState);
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Main State
|
||||||
|
@immutable
|
||||||
|
class AppState {
|
||||||
|
final UserState userState;
|
||||||
|
final MainState mainState;
|
||||||
|
AppState({
|
||||||
|
@required this.userState,
|
||||||
|
@required this.mainState,
|
||||||
|
});
|
||||||
|
|
||||||
|
//stable work
|
||||||
|
AppState copyWith({
|
||||||
|
UserState userState,
|
||||||
|
MainState mainState,
|
||||||
|
}) {
|
||||||
|
return AppState(
|
||||||
|
userState: userState ?? this.userState,
|
||||||
|
mainState: mainState ?? this.mainState,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Redux {
|
||||||
|
static Store<AppState> _store;
|
||||||
|
|
||||||
|
static Store<AppState> get store {
|
||||||
|
if (_store == null) {
|
||||||
|
throw Exception("store is not initialized");
|
||||||
|
} else {
|
||||||
|
return _store;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//initial context
|
||||||
|
static Future<void> init() async {
|
||||||
|
final userStateInitial = UserState.initial();
|
||||||
|
final mainStateInitial = MainState.initial();
|
||||||
|
|
||||||
|
_store = Store<AppState>(
|
||||||
|
appReducer,
|
||||||
|
middleware: [thunkMiddleware],
|
||||||
|
initialState: AppState(userState: userStateInitial, mainState: mainStateInitial),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,8 +20,8 @@ const EdgeInsets largeFieldPadding =
|
||||||
const EdgeInsets.symmetric(horizontal: 15, vertical: 15);
|
const EdgeInsets.symmetric(horizontal: 15, vertical: 15);
|
||||||
|
|
||||||
// Text Variables
|
// Text Variables
|
||||||
|
const TextStyle productTextStyle = const TextStyle(fontWeight: FontWeight.w400, color: Colors.black, fontSize: 15);
|
||||||
const TextStyle buttonTitleTextStyle = const TextStyle(fontWeight: FontWeight.w400, color: whiteColor, fontSize: 15);
|
const TextStyle buttonTitleTextStyle = const TextStyle(fontWeight: FontWeight.w400, color: whiteColor, fontSize: 15);
|
||||||
|
|
||||||
const TextStyle buttonBigTitleTextStyle = const TextStyle(fontWeight: FontWeight.w400, color: whiteColor, fontSize: 22, );
|
const TextStyle buttonBigTitleTextStyle = const TextStyle(fontWeight: FontWeight.w400, color: whiteColor, fontSize: 22, );
|
||||||
|
|
||||||
const TextStyle stepTitleTextStyle =
|
const TextStyle stepTitleTextStyle =
|
||||||
|
|
|
||||||
|
|
@ -1,124 +1,135 @@
|
||||||
library home_view;
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Choice.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:stacked/stacked.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/models/ProductDao.dart';
|
|
||||||
import 'package:aman_kassa_flutter/widgets/components/ProductListItem.dart';
|
|
||||||
import 'home_view_model.dart';
|
|
||||||
import '../../widgets/components/calculator/calculator-buttons.dart';
|
|
||||||
import '../../widgets/components/calculator/number-display.dart';
|
|
||||||
|
|
||||||
part './tabs/KassaTab.dart';
|
import './tabs/KassaTab.dart';
|
||||||
part './tabs/CalculatorTab.dart';
|
import './tabs/AdditionalTab.dart';
|
||||||
part './tabs/AdditionalTab.dart';
|
import './tabs/CalculatorTab.dart';
|
||||||
|
|
||||||
class Choice {
|
|
||||||
const Choice({this.title, this.icon});
|
|
||||||
|
|
||||||
final String title;
|
|
||||||
final IconData icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
const List<Choice> choices = const <Choice>[
|
const List<Choice> choices = const <Choice>[
|
||||||
const Choice(title: 'Обновить номенклатуру', icon: Icons.directions_car),
|
const Choice(title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'),
|
||||||
const Choice(title: 'Помощь', icon: Icons.directions_car),
|
const Choice(title: 'Помощь', icon: Icons.help, command: 'help'),
|
||||||
const Choice(title: 'О Программе', icon: Icons.directions_car),
|
const Choice(title: 'О Программе', icon: Icons.info_outline, command: 'info'),
|
||||||
const Choice(title: 'Язык', icon: Icons.directions_car),
|
const Choice(title: 'Язык', icon: Icons.language, command: 'language'),
|
||||||
const Choice(title: 'Выйти', icon: Icons.directions_bike)
|
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
||||||
];
|
];
|
||||||
|
|
||||||
class HomeView extends StatelessWidget {
|
class HomeView extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_HomeViewState createState() => _HomeViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HomeViewState extends State<HomeView> {
|
||||||
|
PageController pageController;
|
||||||
|
int selectedTabIndex;
|
||||||
|
DataService _dataService = locator<DataService>();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
// TODO: implement initState
|
||||||
|
super.initState();
|
||||||
|
selectedTabIndex = 0;
|
||||||
|
pageController = new PageController(initialPage: selectedTabIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSelectChoice(Choice choice) async {
|
||||||
|
if(choice.command == 'exit') {
|
||||||
|
|
||||||
|
} else if (choice.command == 'update') {
|
||||||
|
bool result = await _dataService.getDataFromServer(Redux.store.state.userState.user.token);
|
||||||
|
print('result: $result');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ViewModelBuilder<HomeViewModel>.reactive(
|
return Scaffold(
|
||||||
viewModelBuilder: () => HomeViewModel(
|
appBar: AppBar(
|
||||||
authenticationService: Provider.of(context),
|
title: Center(
|
||||||
navigationService: Provider.of(context)),
|
child: Container(
|
||||||
onModelReady: (viewModel) {
|
width: 100,
|
||||||
viewModel.initialize();
|
child: Image(
|
||||||
viewModel.pageController =
|
image: AssetImage('assets/images/logo.png'),
|
||||||
new PageController(initialPage: viewModel.tabIndex);
|
fit: BoxFit.fitHeight,
|
||||||
},
|
),
|
||||||
builder: (context, viewModel, child) {
|
)),
|
||||||
return Scaffold(
|
actions: <Widget>[
|
||||||
appBar: AppBar(
|
PopupMenuButton<Choice>(
|
||||||
title: Center(
|
icon: Icon(
|
||||||
child: Container(
|
Icons.more_vert,
|
||||||
width: 100,
|
color: menuColor,
|
||||||
child: Image(
|
|
||||||
image: AssetImage('assets/images/logo.png'),
|
|
||||||
fit: BoxFit.fitHeight,
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
actions: <Widget>[
|
|
||||||
PopupMenuButton<Choice>(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.more_vert,
|
|
||||||
color: menuColor,
|
|
||||||
),
|
|
||||||
onSelected: (s) {},
|
|
||||||
itemBuilder: (BuildContext context) {
|
|
||||||
return choices.map((Choice choice) {
|
|
||||||
return PopupMenuItem<Choice>(
|
|
||||||
value: choice,
|
|
||||||
child: Text(choice.title),
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
backgroundColor: fillColor,
|
|
||||||
),
|
),
|
||||||
body: PageView(
|
onSelected: _onSelectChoice,
|
||||||
onPageChanged: (index) {
|
itemBuilder: (BuildContext context) {
|
||||||
viewModel.tabIndex = index;
|
return choices.map((Choice choice) {
|
||||||
},
|
return PopupMenuItem<Choice>(
|
||||||
controller: viewModel.pageController,
|
value: choice,
|
||||||
children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
KassaTab(viewModel, 0),
|
Icon(choice.icon, color: primaryColor,),
|
||||||
CalculatorTab(viewModel, 1),
|
Text(choice.title)
|
||||||
AdditionalTab(viewModel, 2)
|
], ),
|
||||||
],
|
|
||||||
),
|
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
|
||||||
currentIndex: viewModel.tabIndex,
|
|
||||||
backgroundColor: menuColor,
|
|
||||||
type: BottomNavigationBarType.shifting,
|
|
||||||
items: [
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
backgroundColor: menuColor,
|
|
||||||
icon: Icon(MdiIcons.cashRegister, color: Colors.white),
|
|
||||||
title: new Text(
|
|
||||||
'Касса',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
)),
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Icon(MdiIcons.calculator, color: Colors.white),
|
|
||||||
title: new Text(
|
|
||||||
'Калькулятор',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
)),
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Icon(MdiIcons.tune, color: Colors.white),
|
|
||||||
title: new Text(
|
|
||||||
'Опции',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
onTap: (index) {
|
|
||||||
viewModel.pageController.animateToPage(
|
|
||||||
index,
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeIn,
|
|
||||||
);
|
);
|
||||||
},
|
}).toList();
|
||||||
),
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
backgroundColor: fillColor,
|
||||||
|
),
|
||||||
|
body: PageView(
|
||||||
|
onPageChanged: (index) {
|
||||||
|
setState(() {
|
||||||
|
selectedTabIndex = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
controller: pageController,
|
||||||
|
children: <Widget>[
|
||||||
|
KassaTab(0),
|
||||||
|
CalculatorTab(1),
|
||||||
|
AdditionalTab(2),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
|
currentIndex: selectedTabIndex,
|
||||||
|
backgroundColor: menuColor,
|
||||||
|
type: BottomNavigationBarType.shifting,
|
||||||
|
items: [
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
backgroundColor: menuColor,
|
||||||
|
icon: Icon(MdiIcons.cashRegister, color: Colors.white),
|
||||||
|
title: new Text(
|
||||||
|
'Касса',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
)),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(MdiIcons.calculator, color: Colors.white),
|
||||||
|
title: new Text(
|
||||||
|
'Калькулятор',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
)),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(MdiIcons.tune, color: Colors.white),
|
||||||
|
title: new Text(
|
||||||
|
'Опции',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
onTap: (index) {
|
||||||
|
pageController.animateToPage(
|
||||||
|
index,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeIn,
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
import 'package:aman_kassa_flutter/core/base/base_view_model.dart';
|
import 'package:aman_kassa_flutter/core/base/base_view_model.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
||||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Choice.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/user.dart';
|
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/authentication_service.dart';
|
import 'package:aman_kassa_flutter/core/services/authentication_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||||
|
|
||||||
|
|
@ -10,12 +14,15 @@ import 'package:flutter/material.dart';
|
||||||
class HomeViewModel extends BaseViewModel {
|
class HomeViewModel extends BaseViewModel {
|
||||||
NavigatorService _navigationService;
|
NavigatorService _navigationService;
|
||||||
AuthenticationService _authenticationService;
|
AuthenticationService _authenticationService;
|
||||||
|
DataService _dataService;
|
||||||
final DialogService _dialogService = locator<DialogService>();
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
|
||||||
HomeViewModel({
|
HomeViewModel({
|
||||||
@required AuthenticationService authenticationService,
|
@required AuthenticationService authenticationService,
|
||||||
@required NavigatorService navigationService,
|
@required NavigatorService navigationService,
|
||||||
|
@required DataService dataService,
|
||||||
}) : _authenticationService = authenticationService,
|
}) : _authenticationService = authenticationService,
|
||||||
|
_dataService = dataService,
|
||||||
_navigationService = navigationService;
|
_navigationService = navigationService;
|
||||||
|
|
||||||
User _currentUser;
|
User _currentUser;
|
||||||
|
|
@ -28,13 +35,48 @@ class HomeViewModel extends BaseViewModel {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onSelected(Choice choice) async {
|
||||||
|
log.i(choice.command);
|
||||||
|
if(choice.command == 'exit') {
|
||||||
|
bool result = await _authenticationService.logout(_currentUser.token);
|
||||||
|
if (result) {
|
||||||
|
_navigationService.replace(LoginViewRoute);
|
||||||
|
}
|
||||||
|
} else if (choice.command == 'update') {
|
||||||
|
log.i(_authenticationService.currentUser.token);
|
||||||
|
bool result = await _dataService.getDataFromServer(_authenticationService.currentUser.token);
|
||||||
|
log.i(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PageController get pageController => this._pageController;
|
PageController get pageController => this._pageController;
|
||||||
PageController _pageController;
|
PageController _pageController;
|
||||||
set pageController(PageController pageController) {
|
set pageController(PageController pageController) {
|
||||||
this._pageController = pageController;
|
this._pageController = pageController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Object> _bottomSheetElements = [];
|
||||||
|
List<Object> get bottomSheetElements => this._bottomSheetElements;
|
||||||
|
int _parentId;
|
||||||
|
void selectBottomElement(int parentId) async {
|
||||||
|
// log.i('parentId=$parentId');
|
||||||
|
// _parentId = parentId;
|
||||||
|
// _bottomSheetElements.clear();
|
||||||
|
// List<Category> categories = await _dataService.getCategoriesByParentId(parentId: parentId);
|
||||||
|
// List<Category> goods = await _dataService.getGoodsByCategoryId(categoryId: parentId);
|
||||||
|
// _bottomSheetElements.addAll(categories);
|
||||||
|
// _bottomSheetElements.addAll(goods);
|
||||||
|
// notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String _text;
|
||||||
|
get text => this._text;
|
||||||
|
set text(String text) => this._text = text;
|
||||||
|
|
||||||
void initialize() {
|
void initialize() {
|
||||||
|
|
||||||
_currentUser = _authenticationService.currentUser;
|
_currentUser = _authenticationService.currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,28 @@
|
||||||
part of home_view;
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/home/home_view_model.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
class AdditionalTab extends StatelessWidget {
|
class AdditionalTab extends StatelessWidget {
|
||||||
final HomeViewModel viewModel;
|
|
||||||
final int index;
|
final int index;
|
||||||
|
AdditionalTab(this.index);
|
||||||
AdditionalTab(this.viewModel, this.index);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return StoreConnector<AppState, UserState>(
|
||||||
child: Column(
|
converter: (store) => store.state.userState,
|
||||||
children: <Widget>[
|
builder: (context, vm) {
|
||||||
Text('AdditionalTab index:$index ${viewModel.currentUser.fullName} ',
|
return Container(
|
||||||
style: GoogleFonts.lato(color: Colors.black87))
|
child: Column(
|
||||||
],
|
children: <Widget>[
|
||||||
),
|
Text('AdditionalTab index:$index ${vm.user.fullName} ',
|
||||||
|
style: GoogleFonts.lato(color: Colors.black87))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
part of home_view;
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/home/home_view_model.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator-buttons.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/components/calculator/number-display.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CalculatorTab extends StatelessWidget {
|
class CalculatorTab extends StatelessWidget {
|
||||||
final HomeViewModel viewModel;
|
|
||||||
final int index;
|
final int index;
|
||||||
|
|
||||||
CalculatorTab(this.viewModel, this.index);
|
CalculatorTab(this.index);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,14 @@
|
||||||
part of home_view;
|
|
||||||
|
import 'package:aman_kassa_flutter/core/models/ProductDao.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/CatalogBottomSheet.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/ProductAddBottomSheet.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/components/ProductListItem.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
|
||||||
List<String> litems = [
|
List<String> litems = [
|
||||||
"1",
|
"1",
|
||||||
|
|
@ -13,33 +23,14 @@ List<String> litems = [
|
||||||
"2",
|
"2",
|
||||||
"3",
|
"3",
|
||||||
"4",
|
"4",
|
||||||
"1",
|
"1"
|
||||||
"2",
|
|
||||||
"3",
|
|
||||||
"4",
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
"3",
|
|
||||||
"4",
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
"3",
|
|
||||||
"4",
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
"3",
|
|
||||||
"4",
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
"3",
|
|
||||||
"4"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
class KassaTab extends StatelessWidget {
|
class KassaTab extends StatelessWidget {
|
||||||
final HomeViewModel viewModel;
|
|
||||||
final int index;
|
final int index;
|
||||||
|
|
||||||
KassaTab(this.viewModel, this.index);
|
KassaTab(this.index);
|
||||||
|
|
||||||
Widget buildItem(BuildContext ctxt, int index) {
|
Widget buildItem(BuildContext ctxt, int index) {
|
||||||
return ProductListItem(
|
return ProductListItem(
|
||||||
|
|
@ -49,87 +40,108 @@ class KassaTab extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Padding(
|
||||||
backgroundColor: fillColor,
|
padding: EdgeInsets.all(4),
|
||||||
body: Padding(
|
child: Column(
|
||||||
padding: EdgeInsets.all(4),
|
children: <Widget>[
|
||||||
child: Column(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Expanded(
|
||||||
children: <Widget>[
|
child: Padding(
|
||||||
Expanded(
|
padding: const EdgeInsets.all(4.0),
|
||||||
child: Padding(
|
child: RaisedButton(
|
||||||
padding: const EdgeInsets.all(4.0),
|
padding: EdgeInsets.all(8),
|
||||||
child: RaisedButton(
|
color: primaryColor,
|
||||||
padding: EdgeInsets.all(8),
|
child: Text(
|
||||||
color: primaryColor,
|
"Добавить",
|
||||||
child: Text(
|
style: buttonBigTitleTextStyle,
|
||||||
"Добавить",
|
|
||||||
style: buttonBigTitleTextStyle,
|
|
||||||
),
|
|
||||||
onPressed: () => null,
|
|
||||||
),
|
),
|
||||||
|
onPressed: () { showModalBottomSheetCatalog(context, 'add');},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(4.0),
|
|
||||||
child: RaisedButton(
|
|
||||||
padding: EdgeInsets.all(8),
|
|
||||||
color: greenColor,
|
|
||||||
child: Text(
|
|
||||||
"Каталог",
|
|
||||||
style: buttonBigTitleTextStyle,
|
|
||||||
),
|
|
||||||
onPressed: () => null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: ListView.builder(
|
|
||||||
itemCount: litems.length,
|
|
||||||
itemBuilder: (BuildContext ctxt, int index) =>
|
|
||||||
buildItem(ctxt, index)),
|
|
||||||
),
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(4.0),
|
||||||
|
child: RaisedButton(
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
color: greenColor,
|
||||||
|
child: Text(
|
||||||
|
"Каталог",
|
||||||
|
style: buttonBigTitleTextStyle,
|
||||||
|
),
|
||||||
|
onPressed: () { showModalBottomSheetCatalog(context, 'catalog');},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: litems.length,
|
||||||
|
itemBuilder: (BuildContext ctxt, int index) =>
|
||||||
|
buildItem(ctxt, index)),
|
||||||
),
|
),
|
||||||
Row(
|
),
|
||||||
children: <Widget>[
|
Row(
|
||||||
Expanded(
|
children: <Widget>[
|
||||||
child: Padding(
|
Expanded(
|
||||||
padding: const EdgeInsets.all(4.0),
|
child: Padding(
|
||||||
child: RaisedButton(
|
padding: const EdgeInsets.all(4.0),
|
||||||
padding: EdgeInsets.all(8),
|
child: RaisedButton(
|
||||||
color: redColor,
|
padding: EdgeInsets.all(8),
|
||||||
child: Text(
|
color: redColor,
|
||||||
"Возврат",
|
child: Text(
|
||||||
style: buttonBigTitleTextStyle,
|
"Возврат",
|
||||||
),
|
style: buttonBigTitleTextStyle,
|
||||||
onPressed: () => null,
|
|
||||||
),
|
),
|
||||||
|
onPressed: () => null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
),
|
||||||
child: Padding(
|
Expanded(
|
||||||
padding: const EdgeInsets.all(4.0),
|
child: Padding(
|
||||||
child: RaisedButton(
|
padding: const EdgeInsets.all(4.0),
|
||||||
padding: EdgeInsets.all(8),
|
child: RaisedButton(
|
||||||
color: greenColor,
|
padding: EdgeInsets.all(8),
|
||||||
child: Text(
|
color: greenColor,
|
||||||
"Оплата",
|
child: Text(
|
||||||
style: buttonBigTitleTextStyle,
|
"Оплата",
|
||||||
),
|
style: buttonBigTitleTextStyle,
|
||||||
onPressed: () => null,
|
|
||||||
),
|
),
|
||||||
|
onPressed: () => null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
)
|
],
|
||||||
],
|
)
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showModalBottomSheetCatalog(BuildContext context, String action) {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder: (context){
|
||||||
|
return DraggableScrollableSheet(
|
||||||
|
initialChildSize: 0.8,
|
||||||
|
maxChildSize: 0.95,
|
||||||
|
minChildSize: 0.5,
|
||||||
|
builder: (BuildContext context, ScrollController scrollController) {
|
||||||
|
if( action == 'add') {
|
||||||
|
return ProductAddBottomSheet();
|
||||||
|
} else {
|
||||||
|
return CatalogBottomSheet(scrollController: scrollController,);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
||||||
|
class CatalogBottomSheet extends StatelessWidget {
|
||||||
|
final ScrollController scrollController;
|
||||||
|
|
||||||
|
CatalogBottomSheet({this.scrollController});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return StoreConnector<AppState, MainState>(
|
||||||
|
converter: (store) => store.state.mainState,
|
||||||
|
onInit: (store) => Redux.store.dispatch(selectBottomElement(0)),
|
||||||
|
builder: (context, vm) {
|
||||||
|
return WillPopScope(
|
||||||
|
onWillPop: () {
|
||||||
|
if (vm.prevCategories.length > 0) {
|
||||||
|
Redux.store.dispatch(backBottomElement);
|
||||||
|
} else
|
||||||
|
Navigator.pop(context);
|
||||||
|
return new Future(() => false);
|
||||||
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(
|
||||||
|
vm.prevCategories.isNotEmpty
|
||||||
|
? vm.prevCategories?.last?.name
|
||||||
|
: '',
|
||||||
|
style: TextStyle(color: Colors.black45),
|
||||||
|
),
|
||||||
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
|
backgroundColor: whiteColor,
|
||||||
|
elevation: 3,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(vm.prevCategories.length > 0
|
||||||
|
? Icons.arrow_back
|
||||||
|
: Icons.close),
|
||||||
|
onPressed: () {
|
||||||
|
if (vm.prevCategories.length > 0) {
|
||||||
|
Redux.store.dispatch(backBottomElement);
|
||||||
|
} else
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
controller: scrollController,
|
||||||
|
itemCount: vm.bottomSheetElements.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
var el = vm.bottomSheetElements[index];
|
||||||
|
String name;
|
||||||
|
if (el is Category) {
|
||||||
|
Category category = el;
|
||||||
|
name = category.name;
|
||||||
|
} else if (el is Good) {
|
||||||
|
Good good = el;
|
||||||
|
name = good.name;
|
||||||
|
}
|
||||||
|
return Card(
|
||||||
|
child: ListTile(
|
||||||
|
leading: Icon(
|
||||||
|
el is Category ? Icons.layers : Icons.move_to_inbox,
|
||||||
|
size: 40,
|
||||||
|
),
|
||||||
|
title: Text(name),
|
||||||
|
onTap: () {
|
||||||
|
if (el is Category) {
|
||||||
|
Redux.store.dispatch(selectBottomElement(el.id));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trailing:
|
||||||
|
el is Category ? Icon(Icons.chevron_right) : null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
RaisedButton(
|
||||||
|
child: Text(
|
||||||
|
'Отмена',
|
||||||
|
style: buttonBigTitleTextStyle,
|
||||||
|
),
|
||||||
|
color: redColor,
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ProductAddBottomSheet extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: whiteColor
|
||||||
|
),
|
||||||
|
child: Text('ProductAddBottomSheet'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
library login_view;
|
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/input_field.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/input_field.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/text_link.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/text_link.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:stacked/stacked.dart';
|
|
||||||
import 'login_view_model.dart';
|
|
||||||
|
|
||||||
class LoginView extends StatelessWidget {
|
class LoginView extends StatelessWidget {
|
||||||
final emailController = TextEditingController(text: 'test@kkm-kassa.kz');
|
final emailController = TextEditingController(text: 'test@kkm-kassa.kz');
|
||||||
|
|
@ -18,30 +16,16 @@ class LoginView extends StatelessWidget {
|
||||||
final FocusNode passwordNode = new FocusNode();
|
final FocusNode passwordNode = new FocusNode();
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
|
_pressBtnEnter() async {
|
||||||
|
Redux.store.dispatch(authenticate(emailController.text, passwordController.text));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
login(LoginViewModel viewModel) async {
|
return StoreConnector<AppState, UserState>(
|
||||||
String message = await viewModel.login(
|
converter: (store) => store.state.userState,
|
||||||
email: emailController.text.trim(),
|
builder: (context, vm) {
|
||||||
password: passwordController.text);
|
print('build');
|
||||||
if (message != null) {
|
|
||||||
_scaffoldKey.currentState.showSnackBar(new SnackBar(
|
|
||||||
content: new Text(
|
|
||||||
message,
|
|
||||||
style: GoogleFonts.lato(),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//LoginViewModel viewModel = LoginViewModel();
|
|
||||||
return ViewModelBuilder<LoginViewModel>.reactive(
|
|
||||||
viewModelBuilder: () => LoginViewModel(
|
|
||||||
authenticationService: Provider.of(context),
|
|
||||||
navigationService: Provider.of(context)),
|
|
||||||
onModelReady: (viewModel) {
|
|
||||||
// Do something once your viewModel is initialized
|
|
||||||
},
|
|
||||||
builder: (context, viewModel, child) {
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
backgroundColor: fillColor,
|
backgroundColor: fillColor,
|
||||||
|
|
@ -62,17 +46,16 @@ class LoginView extends StatelessWidget {
|
||||||
controller: emailController,
|
controller: emailController,
|
||||||
textInputType: TextInputType.emailAddress,
|
textInputType: TextInputType.emailAddress,
|
||||||
nextFocusNode: passwordNode,
|
nextFocusNode: passwordNode,
|
||||||
additionalNote: viewModel.messageEmail,
|
additionalNote: vm.loginFormMessage.email,
|
||||||
),
|
),
|
||||||
verticalSpaceSmall,
|
verticalSpaceSmall,
|
||||||
InputField(
|
InputField(
|
||||||
placeholder: 'Пароль',
|
placeholder: 'Пароль',
|
||||||
password: true,
|
password: true,
|
||||||
controller: passwordController,
|
controller: passwordController,
|
||||||
fieldFocusNode: passwordNode,
|
fieldFocusNode: passwordNode,
|
||||||
additionalNote: viewModel.messagePassword,
|
additionalNote: vm.loginFormMessage.password,
|
||||||
enterPressed: () => login(viewModel),
|
enterPressed: _pressBtnEnter),
|
||||||
),
|
|
||||||
verticalSpaceMedium,
|
verticalSpaceMedium,
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
|
@ -80,8 +63,8 @@ class LoginView extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
BusyButton(
|
BusyButton(
|
||||||
title: 'Войти',
|
title: 'Войти',
|
||||||
busy: viewModel.busy,
|
busy: vm.isLoading,
|
||||||
onPressed: () => login(viewModel),
|
onPressed: _pressBtnEnter,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -95,4 +78,6 @@ class LoginView extends StatelessWidget {
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
import 'package:aman_kassa_flutter/core/base/base_view_model.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/services/authentication_service.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/models/authResponse.dart';
|
|
||||||
|
|
||||||
class LoginViewModel extends BaseViewModel {
|
|
||||||
|
|
||||||
//service
|
|
||||||
NavigatorService _navigationService;
|
|
||||||
AuthenticationService _authenticationService;
|
|
||||||
|
|
||||||
//private var
|
|
||||||
String _messageEmail;
|
|
||||||
String _messagePassword;
|
|
||||||
|
|
||||||
//public getter setter
|
|
||||||
get messageEmail => this._messageEmail;
|
|
||||||
set messageEmail(String message) {
|
|
||||||
this._messageEmail = message;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
get messagePassword => this._messagePassword;
|
|
||||||
set messagePassword(String message) {
|
|
||||||
this._messagePassword = message;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LoginViewModel({
|
|
||||||
@required AuthenticationService authenticationService,
|
|
||||||
@required NavigatorService navigationService,
|
|
||||||
}) :
|
|
||||||
_authenticationService = authenticationService ,
|
|
||||||
_navigationService = navigationService;
|
|
||||||
|
|
||||||
|
|
||||||
Future<String> login({String email, String password}) async {
|
|
||||||
String result;
|
|
||||||
busy = true;
|
|
||||||
try {
|
|
||||||
AuthBody response = await _authenticationService.loginWithEmail(email: email, password: password);
|
|
||||||
|
|
||||||
if(response!=null) {
|
|
||||||
if(response.user != null){
|
|
||||||
_navigationService.replace(HomeViewRoute);
|
|
||||||
} else {
|
|
||||||
// show error on validate
|
|
||||||
if(response.email?.isEmpty == false){
|
|
||||||
messageEmail = response.email.join(",");
|
|
||||||
} else {
|
|
||||||
messageEmail = null;
|
|
||||||
}
|
|
||||||
if(response.password?.isEmpty == false){
|
|
||||||
messagePassword = response.password.join(",");
|
|
||||||
} else {
|
|
||||||
messagePassword = null;
|
|
||||||
}
|
|
||||||
//return meesage on snackbar for user screen
|
|
||||||
if(response.message!=null) {
|
|
||||||
result = response.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
busy = false ;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add ViewModel specific code here
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +1,29 @@
|
||||||
library home_view;
|
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'start_up_view_model.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
|
||||||
|
|
||||||
class StartUpView extends StatelessWidget {
|
|
||||||
|
class StartUpView extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_StartUpViewState createState() => _StartUpViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StartUpViewState extends State<StartUpView> {
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
// TODO: implement initState
|
||||||
|
super.initState();
|
||||||
|
Redux.store.dispatch(checkUserAction);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ViewModelBuilder<StartUpViewModel>.reactive(
|
return StoreConnector<AppState, UserState>(
|
||||||
viewModelBuilder: () => StartUpViewModel(authenticationService: Provider.of(context), navigationService: Provider.of(context)),
|
converter: (store) => store.state.userState,
|
||||||
onModelReady: (viewModel) {
|
builder: (context, userState) {
|
||||||
viewModel.handleStartUpLogic();
|
|
||||||
},
|
|
||||||
builder: (context, viewModel, child) {
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -25,6 +34,8 @@ class StartUpView extends StatelessWidget {
|
||||||
height: 200,
|
height: 200,
|
||||||
child: Image.asset('assets/images/icon_large.png'),
|
child: Image.asset('assets/images/icon_large.png'),
|
||||||
),
|
),
|
||||||
|
Text('${userState.isLoading}'),
|
||||||
|
Text('${userState.isAuthenticated}'),
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
valueColor: AlwaysStoppedAnimation(
|
valueColor: AlwaysStoppedAnimation(
|
||||||
|
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
import 'package:aman_kassa_flutter/core/base/base_view_model.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/services/authentication_service.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class StartUpViewModel extends BaseViewModel {
|
|
||||||
NavigatorService _navigationService;
|
|
||||||
AuthenticationService _authenticationService;
|
|
||||||
|
|
||||||
StartUpViewModel({
|
|
||||||
@required AuthenticationService authenticationService,
|
|
||||||
@required NavigatorService navigationService,
|
|
||||||
}) :
|
|
||||||
_authenticationService = authenticationService ,
|
|
||||||
_navigationService = navigationService;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Future handleStartUpLogic() async {
|
|
||||||
// Register for push notifications
|
|
||||||
//await _pushNotificationService.initialise();
|
|
||||||
|
|
||||||
var hasLoggedInUser = await _authenticationService.isUserLoggedIn('test');
|
|
||||||
log.i('hasLoggedInUser $hasLoggedInUser');
|
|
||||||
if (hasLoggedInUser) {
|
|
||||||
//_navigationService.navigateTo(HomeViewRoute);
|
|
||||||
_navigationService.replace(HomeViewRoute);
|
|
||||||
} else {
|
|
||||||
_navigationService.replace(LoginViewRoute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +1,81 @@
|
||||||
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/ProductDao.dart';
|
import 'package:aman_kassa_flutter/core/models/ProductDao.dart';
|
||||||
|
|
||||||
class ProductListItem extends StatelessWidget {
|
class ProductListItem extends StatelessWidget {
|
||||||
|
|
||||||
ProductDao item;
|
ProductDao item;
|
||||||
|
|
||||||
ProductListItem({
|
ProductListItem({this.item});
|
||||||
this.item
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Padding(
|
||||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 4),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
|
||||||
child: Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
color: whiteColor,
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
|
||||||
child: Text(item.name)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
color: whiteColor,
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
|
||||||
child: Text('${item.price?.toString()} x ${item.count?.toString()}', textAlign: TextAlign.right)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Row(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: whiteColor,
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
||||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
child: Text(item.name, style: productTextStyle,)),
|
||||||
child: Text(item.name)
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(child: Text(item.name)),
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
||||||
|
child: Text(
|
||||||
|
'${item.price?.toString()} x ${item.count?.toString()}',
|
||||||
|
textAlign: TextAlign.right, style: productTextStyle)),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
|
Container(
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Container(),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Container(
|
||||||
|
//margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
buildClipRect(primaryColor,Icons.remove, () {}),
|
||||||
|
buildClipRect(primaryColor,Icons.add, () {}),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
),
|
||||||
|
),
|
||||||
|
buildClipRect(redColor,Icons.close, () {}),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Divider()
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClipRect buildClipRect(Color color, IconData icon, VoidCallback onPress) {
|
||||||
|
return ClipRect(
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.all(5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color
|
||||||
|
),
|
||||||
|
height: 35,
|
||||||
|
width: 35,
|
||||||
|
child: IconButton(
|
||||||
|
icon: Icon(icon, color: whiteColor, size: 20),
|
||||||
|
onPressed: onPress,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ class CalculatorButton extends StatelessWidget {
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Color.fromRGBO(0, 0, 0, 0.1),
|
color: const Color.fromRGBO(0, 0, 0, 0.1),
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -24,7 +24,7 @@ class CalculatorButton extends StatelessWidget {
|
||||||
text,
|
text,
|
||||||
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
|
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.all(15),
|
padding: const EdgeInsets.all(15),
|
||||||
highlightColor: Colors.blueGrey[100],
|
highlightColor: Colors.blueGrey[100],
|
||||||
splashColor: Colors.blueAccent[100],
|
splashColor: Colors.blueAccent[100],
|
||||||
)));
|
)));
|
||||||
|
|
|
||||||
51
pubspec.lock
51
pubspec.lock
|
|
@ -83,6 +83,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
flutter_redux:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_redux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
@ -173,7 +180,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.4"
|
version: "1.6.4"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
|
|
@ -242,6 +249,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
|
redux:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: redux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.0"
|
||||||
|
redux_thunk:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: redux_thunk
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.0"
|
||||||
responsive_builder:
|
responsive_builder:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -254,6 +275,13 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.99"
|
version: "0.0.99"
|
||||||
|
sliding_up_panel:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: sliding_up_panel
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -261,6 +289,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.0"
|
version: "1.7.0"
|
||||||
|
sqflite:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: sqflite
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0+2"
|
||||||
|
sqflite_common:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqflite_common
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -289,6 +331,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.5"
|
||||||
|
synchronized:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: synchronized
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
cupertino_icons: ^0.1.2
|
cupertino_icons: ^0.1.2
|
||||||
|
redux: ^4.0.0
|
||||||
|
flutter_redux: ^0.6.0
|
||||||
|
redux_thunk: ^0.3.0
|
||||||
stacked : ^1.5.2
|
stacked : ^1.5.2
|
||||||
provider_architecture: ^1.0.3
|
provider_architecture: ^1.0.3
|
||||||
responsive_builder: ^0.1.4
|
responsive_builder: ^0.1.4
|
||||||
|
|
@ -14,9 +17,12 @@ dependencies:
|
||||||
logger: ^0.9.1
|
logger: ^0.9.1
|
||||||
get_it: ^3.0.3
|
get_it: ^3.0.3
|
||||||
equatable: ^1.1.1
|
equatable: ^1.1.1
|
||||||
http: ^0.12.1
|
http: ^0.12.1
|
||||||
|
sqflite: ^1.3.0
|
||||||
|
path_provider: ^1.6.9
|
||||||
google_fonts: ^1.1.0
|
google_fonts: ^1.1.0
|
||||||
flutter_boom_menu: ^1.0.2
|
flutter_boom_menu: ^1.0.2
|
||||||
|
sliding_up_panel: ^1.0.2
|
||||||
material_design_icons_flutter: ^4.0.5345
|
material_design_icons_flutter: ^4.0.5345
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue