login navigate
parent
30db638877
commit
46302aed18
|
|
@ -1,19 +1,22 @@
|
|||
import '../core/services/ApiService.dart';
|
||||
|
||||
|
||||
import '../core/services/ApiService.dart';
|
||||
import '../core/services/authentication_service.dart';
|
||||
import '../core/logger.dart';
|
||||
import '../core/services/navigator_service.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
GetIt locator = GetIt.instance;
|
||||
GetIt locator = GetIt.I;
|
||||
|
||||
class LocatorInjector {
|
||||
static Logger _log = getLogger('LocatorInjector');
|
||||
|
||||
static Future<void> setupLocator() async {
|
||||
_log.d('Initializing Navigator Service');
|
||||
locator.registerLazySingleton(() => NavigatorService());
|
||||
_log.d('Initializing Api Service');
|
||||
locator.registerLazySingleton(() => ApiService());
|
||||
locator.registerLazySingleton<ApiService>(() => ApiService());
|
||||
_log.d('Initializing Navigator Service');
|
||||
locator.registerLazySingleton<NavigatorService>(() => NavigatorService());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
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,23 +1,20 @@
|
|||
class User {
|
||||
final String id;
|
||||
final String token;
|
||||
final String fullName;
|
||||
final String email;
|
||||
final String userRole;
|
||||
|
||||
User({this.id, this.fullName, this.email, this.userRole});
|
||||
User({this.token, this.fullName, this.email});
|
||||
|
||||
User.fromData(Map<String, dynamic> data)
|
||||
: id = data['id'],
|
||||
: token = data['api_token'],
|
||||
fullName = data['fullName'],
|
||||
email = data['email'],
|
||||
userRole = data['userRole'];
|
||||
email = data['email'];
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'api_token': token,
|
||||
'fullName': fullName,
|
||||
'email': email,
|
||||
'userRole': userRole,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,47 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/session.dart';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
/// The service responsible for networking requests
|
||||
class ApiService extends BaseService {
|
||||
static const endpoint = 'https://jsonplaceholder.typicode.com';
|
||||
static const endpoint = 'https://kassa-test.aman.com.kz/ru/api/v2';
|
||||
|
||||
var client = new http.Client();
|
||||
|
||||
Future<User> getUserProfile(int userId) async {
|
||||
// Get user profile for id
|
||||
var response = await client.get('$endpoint/users/$userId');
|
||||
|
||||
// Convert and return
|
||||
return User.fromData(json.decode(response.body));
|
||||
|
||||
Future<Session> isActive(String token) async {
|
||||
// var map = new Map<String, dynamic>();
|
||||
// map['api_token'] = token;
|
||||
// var response = await client.post(
|
||||
// '$endpoint/test_auth',
|
||||
// headers: {
|
||||
// HttpHeaders.contentTypeHeader: "multipart/form-data",
|
||||
// HttpHeaders.cacheControlHeader: "no-cache"
|
||||
// },
|
||||
// body: map);
|
||||
// print(response.body);
|
||||
// return Session.fromData(token,json.decode(response.body));
|
||||
Map<String, String> requestBody = <String,String>{
|
||||
'api_token':token
|
||||
};
|
||||
Map<String, String> headers= <String,String>{
|
||||
HttpHeaders.contentTypeHeader: "multipart/form-data",
|
||||
HttpHeaders.cacheControlHeader: "no-cache"
|
||||
};
|
||||
|
||||
var uri = Uri.parse('$endpoint/test_auth');
|
||||
var request = http.MultipartRequest('POST', uri)
|
||||
..headers.addAll(headers) //if u have headers, basic auth, token bearer... Else remove line
|
||||
..fields.addAll(requestBody);
|
||||
var response = await request.send();
|
||||
final respStr = await response.stream.bytesToString();
|
||||
print(respStr);
|
||||
return Session.fromData(token,json.decode(respStr));
|
||||
}
|
||||
|
||||
// Future<List<Post>> getPostsForUser(int userId) async {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
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/user.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
|
|
@ -14,17 +15,29 @@ class AuthenticationService extends BaseService {
|
|||
User _currentUser;
|
||||
User get currentUser => _currentUser;
|
||||
|
||||
Future loginWithEmail({
|
||||
@required String email,
|
||||
@required String password,
|
||||
}) async {
|
||||
try {
|
||||
User result = await _api.getUserProfile(123);
|
||||
_currentUser = result;
|
||||
return result != null;
|
||||
} catch (e) {
|
||||
return e.message;
|
||||
Session _session;
|
||||
Session get currentSession => _session;
|
||||
|
||||
// Future loginWithEmail({
|
||||
// @required String email,
|
||||
// @required String password,
|
||||
// }) async {
|
||||
// try {
|
||||
// User result = await _api.getUserProfile(123);
|
||||
// _currentUser = result;
|
||||
// return result != null;
|
||||
// } catch (e) {
|
||||
// return e.message;
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<bool> isUserLoggedIn(token) async {
|
||||
Session session = await _api.isActive(token);
|
||||
if("OK" == session.message){
|
||||
_session = session;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Future<bool> isUserLoggedIn() async {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,19 @@ import 'package:flutter/material.dart';
|
|||
class NavigatorService extends BaseService {
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
Future<dynamic> push(String routeName, {dynamic arguments}) {
|
||||
log.i('routeName: $routeName');
|
||||
return navigatorKey.currentState
|
||||
.pushNamed(routeName, arguments: arguments);
|
||||
}
|
||||
|
||||
Future<dynamic> replace(String routeName) {
|
||||
log.i('routeName: $routeName');
|
||||
return navigatorKey.currentState
|
||||
.pushNamedAndRemoveUntil(routeName, (Route<dynamic> route) => false);
|
||||
}
|
||||
|
||||
|
||||
Future<T> navigateToPage<T>(MaterialPageRoute<T> pageRoute) async {
|
||||
log.i('navigateToPage: pageRoute: ${pageRoute.settings.name}');
|
||||
if (navigatorKey.currentState == null) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
||||
|
||||
//general
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
//service & tools
|
||||
import 'core/locator.dart';
|
||||
import 'core/providers.dart';
|
||||
import 'core/router.dart';
|
||||
import 'core/services/navigator_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'views/home/home_view.dart';
|
||||
//pages
|
||||
import 'views/start_up/start_up_view.dart';
|
||||
|
||||
|
||||
//main start
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
//initialize locator
|
||||
await LocatorInjector.setupLocator();
|
||||
runApp(MainApplication());
|
||||
}
|
||||
|
|
@ -20,7 +25,7 @@ class MainApplication extends StatelessWidget {
|
|||
providers: ProviderInjector.providers.toList(),
|
||||
child: MaterialApp(
|
||||
navigatorKey: locator<NavigatorService>().navigatorKey,
|
||||
home: HomeView(),
|
||||
home: StartUpView(), // first page
|
||||
onGenerateRoute: generateRoute,
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
const Color shadowColor = Color.fromRGBO(80, 137, 196, 0.47);
|
||||
const Color cardShadowColor = Color.fromRGBO(228, 229, 231, 0.25);
|
||||
const Color blueColor = Color.fromRGBO(96, 205, 255, 1);
|
||||
const Color blueColorLigth = Color.fromRGBO(96, 205, 255, 0.536);
|
||||
const Color redColor = Color.fromRGBO(255, 98, 96, 1);
|
||||
const Color greenColor = Color.fromRGBO(59, 222, 134, 1);
|
||||
const Color whiteColor = Color.fromRGBO(255, 255, 255, 1);
|
||||
const Color textColor = Color.fromRGBO(107, 120, 151, 1);
|
||||
const Color textColorLight = Color.fromRGBO(162, 171, 191, 1);
|
||||
const Color dayColor = Color.fromRGBO(52, 72, 94, 0.536);
|
||||
const Color dayColorLight = Color.fromRGBO(255, 228, 231, 1);
|
||||
const Color backgroundColor = Color.fromRGBO(249, 250, 254, 1);
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// Box Decorations
|
||||
|
||||
BoxDecoration fieldDecortaion = BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5), color: Colors.white);
|
||||
|
||||
BoxDecoration disabledFieldDecortaion = BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5), color: Colors.grey[100]);
|
||||
|
||||
// Field Variables
|
||||
|
||||
const double fieldHeight = 55;
|
||||
const double smallFieldHeight = 40;
|
||||
const double inputFieldBottomMargin = 30;
|
||||
const double inputFieldSmallBottomMargin = 0;
|
||||
const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15);
|
||||
const EdgeInsets largeFieldPadding =
|
||||
const EdgeInsets.symmetric(horizontal: 15, vertical: 15);
|
||||
|
||||
// Text Variables
|
||||
const TextStyle buttonTitleTextStyle =
|
||||
const TextStyle(fontWeight: FontWeight.w400, color: whiteColor, fontSize: 15);
|
||||
|
||||
const TextStyle stepTitleTextStyle =
|
||||
const TextStyle(fontWeight: FontWeight.w700, color: textColor, fontSize: 15);
|
||||
const TextStyle stepSubTitleTextStyle = const TextStyle(fontWeight: FontWeight.w400, color: textColor, fontSize: 12);
|
||||
|
||||
// Box Shadow
|
||||
const BoxShadow mainShadowBox = BoxShadow(blurRadius: 16, color: shadowColor, offset: Offset(0, 5));
|
||||
const BoxShadow cardShadowBox = BoxShadow(blurRadius: 23, color: cardShadowColor, offset: Offset(0, 2));
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
const Widget horizontalSpaceTiny = SizedBox(width: 5.0);
|
||||
const Widget horizontalSpaceSmall = SizedBox(width: 10.0);
|
||||
const Widget horizontalSpaceMedium = SizedBox(width: 25.0);
|
||||
|
||||
const Widget verticalSpaceTiny = SizedBox(height: 5.0);
|
||||
const Widget verticalSpaceSmall = SizedBox(height: 10.0);
|
||||
const Widget verticalSpaceMedium = SizedBox(height: 25.0);
|
||||
const Widget verticalSpaceLarge = SizedBox(height: 50.0);
|
||||
const Widget verticalSpaceMassive = SizedBox(height: 120.0);
|
||||
|
||||
Widget spacedDivider = Column(
|
||||
children: const <Widget>[
|
||||
verticalSpaceMedium,
|
||||
const Divider(color: Colors.blueGrey, height: 5.0),
|
||||
verticalSpaceMedium,
|
||||
],
|
||||
);
|
||||
|
||||
Widget verticalSpace(double height) => SizedBox(height: height);
|
||||
|
||||
double screenWidth(BuildContext context) => MediaQuery.of(context).size.width;
|
||||
double screenHeight(BuildContext context) => MediaQuery.of(context).size.height;
|
||||
|
||||
double screenHeightFraction(BuildContext context,
|
||||
{int dividedBy = 1, double offsetBy = 0}) =>
|
||||
(screenHeight(context) - offsetBy) / dividedBy;
|
||||
|
||||
double screenWidthFraction(BuildContext context,
|
||||
{int dividedBy = 1, double offsetBy = 0}) =>
|
||||
(screenWidth(context) - offsetBy) / dividedBy;
|
||||
|
||||
double halfScreenWidth(BuildContext context) =>
|
||||
screenWidthFraction(context, dividedBy: 2);
|
||||
|
||||
double thirdScreenWidth(BuildContext context) =>
|
||||
screenWidthFraction(context, dividedBy: 3);
|
||||
|
|
@ -10,32 +10,13 @@ class HomeView extends StatelessWidget {
|
|||
return ViewModelBuilder<HomeViewModel>.reactive(
|
||||
viewModelBuilder: () => HomeViewModel(),
|
||||
onModelReady: (viewModel) {
|
||||
//viewModel.busy = true;
|
||||
viewModel.busy = true;
|
||||
},
|
||||
builder: (context, viewModel, child) {
|
||||
return buildWaitingLogo(context, viewModel, child);
|
||||
return Scaffold(
|
||||
body: Center(child: Text('HomeView')),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget buildWaitingLogo(
|
||||
BuildContext context, HomeViewModel viewModel, Widget child) =>
|
||||
new Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: 300,
|
||||
height: 100,
|
||||
child: Image.asset('assets/images/icon_large.png'),
|
||||
),
|
||||
CircularProgressIndicator(
|
||||
strokeWidth: 3,
|
||||
valueColor: AlwaysStoppedAnimation(
|
||||
Colors.yellow[300],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import 'package:aman_kassa_flutter/core/base/base_view_model.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class HomeViewModel extends BaseViewModel {
|
||||
final NavigatorService _navigationService = locator<NavigatorService>();
|
||||
|
|
@ -19,7 +18,5 @@ class HomeViewModel extends BaseViewModel {
|
|||
|
||||
void increment() => this.counter += 1;
|
||||
|
||||
void goToLogin() {
|
||||
_navigationService.navigateToPage(MaterialPageRoute(builder: (context) => LoginView()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,19 @@
|
|||
library login_view;
|
||||
|
||||
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/input_field.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/fields/text_link.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import 'login_view_model.dart';
|
||||
|
||||
class LoginView extends StatelessWidget {
|
||||
final emailController = TextEditingController();
|
||||
final passwordController = TextEditingController();
|
||||
|
||||
final FocusNode passwordNode = new FocusNode();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//LoginViewModel viewModel = LoginViewModel();
|
||||
|
|
@ -15,8 +24,59 @@ class LoginView extends StatelessWidget {
|
|||
},
|
||||
builder: (context, viewModel, child) {
|
||||
return Scaffold(
|
||||
body: Center(child: Text('LoginMobile')),
|
||||
//backgroundColor: Colors.white,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child: Image.asset('assets/images/logo.png'),
|
||||
//child: FlutterLogo(size: 120,),
|
||||
),
|
||||
InputField(
|
||||
placeholder: 'Электронная почта',
|
||||
controller: emailController,
|
||||
textInputType: TextInputType.emailAddress,
|
||||
nextFocusNode: passwordNode,
|
||||
),
|
||||
verticalSpaceSmall,
|
||||
InputField(
|
||||
placeholder: 'Пароль',
|
||||
password: true,
|
||||
controller: passwordController,
|
||||
fieldFocusNode: passwordNode,
|
||||
),
|
||||
verticalSpaceMedium,
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
BusyButton(
|
||||
title: 'Войти',
|
||||
busy: viewModel.busy,
|
||||
onPressed: () {
|
||||
viewModel.login(
|
||||
email: emailController.text.trim(),
|
||||
password: passwordController.text,
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
verticalSpaceLarge,
|
||||
TextLink(
|
||||
'Регистрация',
|
||||
onPressed: () {
|
||||
//viewModel.navigateToSignUp();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@ import 'package:aman_kassa_flutter/core/base/base_view_model.dart';
|
|||
class LoginViewModel extends BaseViewModel {
|
||||
LoginViewModel();
|
||||
|
||||
void login({String email, String password}) {}
|
||||
|
||||
// Add ViewModel specific code here
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
library home_view;
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'start_up_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
|
||||
class StartUpView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<StartUpViewModel>.reactive(
|
||||
viewModelBuilder: () => StartUpViewModel(authenticationService: Provider.of(context), navigationService: Provider.of(context)),
|
||||
onModelReady: (viewModel) {
|
||||
viewModel.handleStartUpLogic();
|
||||
},
|
||||
builder: (context, viewModel, child) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: 500,
|
||||
height: 200,
|
||||
child: Image.asset('assets/images/icon_large.png'),
|
||||
),
|
||||
CircularProgressIndicator(
|
||||
strokeWidth: 3,
|
||||
valueColor: AlwaysStoppedAnimation(
|
||||
Colors.yellow[300],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// A button that shows a busy indicator in place of title
|
||||
class BusyButton extends StatefulWidget {
|
||||
final bool busy;
|
||||
final String title;
|
||||
final Function onPressed;
|
||||
final bool enabled;
|
||||
const BusyButton(
|
||||
{@required this.title,
|
||||
this.busy = false,
|
||||
@required this.onPressed,
|
||||
this.enabled = true});
|
||||
|
||||
@override
|
||||
_BusyButtonState createState() => _BusyButtonState();
|
||||
}
|
||||
|
||||
class _BusyButtonState extends State<BusyButton> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: widget.onPressed,
|
||||
child: InkWell(
|
||||
child: AnimatedContainer(
|
||||
height: widget.busy ? 40 : null,
|
||||
width: widget.busy ? 40 : null,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: widget.busy ? 10 : 25,
|
||||
vertical: widget.busy ? 10 : 15),
|
||||
decoration: BoxDecoration(
|
||||
color: widget.enabled ? blueColor : blueColorLigth,
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
boxShadow: [mainShadowBox]
|
||||
),
|
||||
child: !widget.busy
|
||||
? Text(
|
||||
widget.title,
|
||||
style: buttonTitleTextStyle,
|
||||
)
|
||||
: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||
|
||||
import 'note_text.dart';
|
||||
|
||||
class InputField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final TextInputType textInputType;
|
||||
final bool password;
|
||||
final bool isReadOnly;
|
||||
final String placeholder;
|
||||
final String validationMessage;
|
||||
final Function enterPressed;
|
||||
final bool smallVersion;
|
||||
final FocusNode fieldFocusNode;
|
||||
final FocusNode nextFocusNode;
|
||||
final TextInputAction textInputAction;
|
||||
final bool multiline;
|
||||
final String additionalNote;
|
||||
final Function(String) onChanged;
|
||||
final TextInputFormatter formatter;
|
||||
final String initialValue;
|
||||
final String labelText;
|
||||
|
||||
InputField(
|
||||
{
|
||||
this.controller,
|
||||
@required this.placeholder,
|
||||
this.enterPressed,
|
||||
this.fieldFocusNode,
|
||||
this.nextFocusNode,
|
||||
this.additionalNote,
|
||||
this.onChanged,
|
||||
this.formatter,
|
||||
this.initialValue,
|
||||
this.validationMessage,
|
||||
this.textInputAction = TextInputAction.next,
|
||||
this.textInputType = TextInputType.text,
|
||||
this.password = false,
|
||||
this.isReadOnly = false,
|
||||
this.multiline = false,
|
||||
this.smallVersion = false, this.labelText});
|
||||
|
||||
@override
|
||||
_InputFieldState createState() => _InputFieldState();
|
||||
}
|
||||
|
||||
class _InputFieldState extends State<InputField> {
|
||||
bool isPassword;
|
||||
double fieldHeight = 55;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
isPassword = widget.password;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (widget.labelText != null) NoteText(widget.labelText),
|
||||
Container(
|
||||
//height: widget.smallVersion ? 40 : fieldHeight,
|
||||
constraints: BoxConstraints(minHeight: widget.smallVersion ? 40 : fieldHeight),
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: fieldPadding,
|
||||
decoration:
|
||||
widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
style: TextStyle( color: textColor ),
|
||||
controller: widget.controller,
|
||||
keyboardType: widget.textInputType,
|
||||
focusNode: widget.fieldFocusNode,
|
||||
textInputAction: widget.textInputAction,
|
||||
maxLines: widget.multiline ? null : 1,
|
||||
onChanged: widget.onChanged,
|
||||
initialValue: widget.initialValue,
|
||||
inputFormatters:
|
||||
widget.formatter != null ? [widget.formatter] : null,
|
||||
onEditingComplete: () {
|
||||
if (widget.enterPressed != null) {
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
widget.enterPressed();
|
||||
}
|
||||
},
|
||||
onFieldSubmitted: (value) {
|
||||
if (widget.nextFocusNode != null) {
|
||||
widget.nextFocusNode.requestFocus();
|
||||
}
|
||||
},
|
||||
obscureText: isPassword,
|
||||
readOnly: widget.isReadOnly,
|
||||
decoration: InputDecoration.collapsed(
|
||||
hintText: widget.placeholder,
|
||||
hintStyle:
|
||||
TextStyle(fontSize: widget.smallVersion ? 12 : 15, color: textColorLight)),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => setState(() {
|
||||
isPassword = !isPassword;
|
||||
}),
|
||||
child: widget.password
|
||||
? Container(
|
||||
width: fieldHeight,
|
||||
height: fieldHeight,
|
||||
alignment: Alignment.center,
|
||||
child: Icon(isPassword
|
||||
? Icons.visibility
|
||||
: Icons.visibility_off, color: textColor))
|
||||
: Container(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (widget.validationMessage != null)
|
||||
NoteText(
|
||||
widget.validationMessage,
|
||||
color: Colors.red,
|
||||
),
|
||||
if (widget.additionalNote != null) verticalSpace(5),
|
||||
if (widget.additionalNote != null) NoteText(widget.additionalNote),
|
||||
verticalSpaceSmall
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NoteText extends StatelessWidget {
|
||||
final String text;
|
||||
final TextAlign textAlign;
|
||||
final Color color;
|
||||
final double fontSize;
|
||||
const NoteText(this.text, {this.textAlign, this.color, this.fontSize});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(
|
||||
text,
|
||||
textAlign: textAlign,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize ?? 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: color ?? dayColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TextLink extends StatelessWidget {
|
||||
final String text;
|
||||
final Function onPressed;
|
||||
const TextLink(this.text, {this.onPressed});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onPressed,
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14, color: textColor),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue