From 0c5d43c04b0d7b6e97e2f30a87777a017484df06 Mon Sep 17 00:00:00 2001 From: devmirza121 Date: Thu, 20 Jan 2022 15:39:25 +0300 Subject: [PATCH] New Structure Implemented --- lib/api/api_client.dart | 155 +++++++++++++++ lib/api/tangheem_user_api_client.dart | 34 ++++ lib/app_state/app_state.dart | 26 +++ lib/classes/colors.dart | 31 +++ lib/classes/consts.dart | 20 ++ lib/classes/utils.dart | 70 +++++++ lib/config/app_provider.dart | 15 +- lib/config/background_loader.dart | 34 ---- lib/config/dependencies.dart | 38 ---- lib/config/localization.dart | 18 -- lib/exceptions/api_exception.dart | 29 +++ lib/extensions/int_extensions.dart | 7 + lib/extensions/string_extensions.dart | 114 +++++++++++ lib/extensions/widget_extensions.dart | 11 ++ lib/main.dart | 9 +- lib/models/content_info_model.dart | 65 +++++++ lib/models/member_model.dart | 62 ++++++ lib/models/surah_model.dart | 74 +++++++ lib/pages/dashboard/dashboard_page.dart | 26 +-- lib/pages/user/complete_profile_page.dart | 31 ++- lib/pages/user/forget_password_page.dart | 13 +- lib/pages/user/login_verification_page.dart | 16 +- lib/pages/user/login_verify_account_page.dart | 13 +- lib/pages/user/register_page.dart | 24 ++- lib/pages/user/register_selection_page.dart | 13 +- lib/pages/user/splash_page.dart | 31 +-- lib/provider/counter.dart | 20 -- lib/repo/account_repository.dart | 51 ----- lib/services/backend_service.dart | 127 ------------ lib/services/firebase_service.dart | 180 ------------------ lib/services/http_service.dart | 36 ---- lib/services/media_service.dart | 26 --- lib/services/network_service.dart | 25 --- lib/services/secure_storage.dart | 33 ---- lib/services/shared_preferences.dart | 119 ------------ lib/utils/utils.dart | 105 +++++----- lib/widgets/app_bar.dart | 8 +- lib/widgets/button/show_image_button.dart | 11 +- lib/widgets/dialog/message_dialog.dart | 13 +- lib/widgets/dialog/otp_dialog.dart | 18 +- lib/widgets/show_fill_button.dart | 13 +- lib/widgets/txt.dart | 170 ----------------- lib/widgets/txt_field.dart | 12 +- pubspec.lock | 10 +- 44 files changed, 866 insertions(+), 1090 deletions(-) create mode 100644 lib/api/api_client.dart create mode 100644 lib/api/tangheem_user_api_client.dart create mode 100644 lib/app_state/app_state.dart create mode 100644 lib/classes/colors.dart create mode 100644 lib/classes/consts.dart create mode 100644 lib/classes/utils.dart delete mode 100644 lib/config/background_loader.dart delete mode 100644 lib/config/dependencies.dart delete mode 100644 lib/config/localization.dart create mode 100644 lib/exceptions/api_exception.dart create mode 100644 lib/extensions/int_extensions.dart create mode 100644 lib/extensions/string_extensions.dart create mode 100644 lib/extensions/widget_extensions.dart create mode 100644 lib/models/content_info_model.dart create mode 100644 lib/models/member_model.dart create mode 100644 lib/models/surah_model.dart delete mode 100644 lib/provider/counter.dart delete mode 100644 lib/repo/account_repository.dart delete mode 100644 lib/services/backend_service.dart delete mode 100644 lib/services/firebase_service.dart delete mode 100644 lib/services/http_service.dart delete mode 100644 lib/services/media_service.dart delete mode 100644 lib/services/network_service.dart delete mode 100644 lib/services/secure_storage.dart delete mode 100644 lib/services/shared_preferences.dart delete mode 100644 lib/widgets/txt.dart diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart new file mode 100644 index 0000000..4908e53 --- /dev/null +++ b/lib/api/api_client.dart @@ -0,0 +1,155 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:http/http.dart'; +import 'package:http/io_client.dart'; +import 'package:car_customer_app/exceptions/api_exception.dart'; + +typedef FactoryConstructor = U Function(dynamic); + +class APIError { + int errorCode; + String errorMessage; + + APIError(this.errorCode, this.errorMessage); + + Map toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage}; + + @override + String toString() { + return jsonEncode(this); + } +} + +APIException _throwAPIException(Response response) { + switch (response.statusCode) { + case 400: + APIError? apiError; + if (response.body != null && response.body.isNotEmpty) { + var jsonError = jsonDecode(response.body); + apiError = APIError(jsonError['errorCode'], jsonError['errorMessage']); + } + return APIException(APIException.BAD_REQUEST, error: apiError); + case 401: + return APIException(APIException.UNAUTHORIZED); + case 403: + return APIException(APIException.FORBIDDEN); + case 404: + return APIException(APIException.NOT_FOUND); + case 500: + return APIException(APIException.INTERNAL_SERVER_ERROR); + case 444: + var downloadUrl = response.headers["location"]; + return APIException(APIException.UPGRADE_REQUIRED, arguments: downloadUrl); + default: + return APIException(APIException.OTHER); + } +} + +class ApiClient { + static final ApiClient _instance = ApiClient._internal(); + + ApiClient._internal(); + + factory ApiClient() => _instance; + + Future postJsonForObject(FactoryConstructor factoryConstructor, String url, T jsonObject, + {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + var _headers = {'Accept': 'application/json'}; + if (headers != null && headers.isNotEmpty) { + _headers.addAll(headers); + } + if (!kReleaseMode) { + print("Url:$url"); + print("body:$jsonObject"); + } + var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes); + try { + var jsonData = jsonDecode(response.body); + return factoryConstructor(jsonData); + } catch (ex) { + throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); + } + } + + Future postJsonForResponse(String url, T jsonObject, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + String? requestBody; + if (jsonObject != null) { + requestBody = jsonEncode(jsonObject); + if (headers == null) { + headers = {'Content-Type': 'application/json'}; + } else { + headers['Content-Type'] = 'application/json'; + } + } + + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes); + } + + Future _postForResponse(String url, requestBody, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + try { + var _headers = {}; + if (token != null) { + _headers['Authorization'] = 'Bearer $token'; + } + + if (headers != null && headers.isNotEmpty) { + _headers.addAll(headers); + } + + if (queryParameters != null) { + var queryString = new Uri(queryParameters: queryParameters).query; + url = url + '?' + queryString; + } + var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(seconds: 15)); + + if (response.statusCode >= 200 && response.statusCode < 300) { + return response; + } else { + throw _throwAPIException(response); + } + } on SocketException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } on HttpException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } on TimeoutException catch (e) { + throw APIException(APIException.TIMEOUT, arguments: e); + } on ClientException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } + } + + bool _certificateCheck(X509Certificate cert, String host, int port) => true; + + Future _withClient(Future Function(Client) fn) async { + var httpClient = HttpClient()..badCertificateCallback = _certificateCheck; + var client = IOClient(httpClient); + try { + return await fn(client); + } finally { + client.close(); + } + } + + Future _post(url, {Map? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding)); +} diff --git a/lib/api/tangheem_user_api_client.dart b/lib/api/tangheem_user_api_client.dart new file mode 100644 index 0000000..802e26a --- /dev/null +++ b/lib/api/tangheem_user_api_client.dart @@ -0,0 +1,34 @@ +import 'dart:async'; + +import 'package:car_customer_app/classes/consts.dart'; +import 'package:car_customer_app/models/content_info_model.dart'; +import 'package:car_customer_app/models/member_model.dart'; +import 'package:car_customer_app/models/surah_model.dart'; + +import 'api_client.dart'; + +class TangheemUserApiClient { + static final TangheemUserApiClient _instance = TangheemUserApiClient._internal(); + + TangheemUserApiClient._internal(); + + factory TangheemUserApiClient() => _instance; + + Future getSurahs() async { + String url = "${ApiConsts.tangheemUsers}AlSuar_Get"; + var postParams = {}; + return await ApiClient().postJsonForObject((json) => SurahModel.fromJson(json), url, postParams); + } + + Future getMembers() async { + String url = "${ApiConsts.tangheemUsers}Committee_Get"; + var postParams = {}; + return await ApiClient().postJsonForObject((json) => MemberModel.fromJson(json), url, postParams); + } + + Future getContentInfo(int contentId) async { + String url = "${ApiConsts.tangheemUsers}ContentInfo_Get"; + var postParams = {"contentTypeId": contentId}; + return await ApiClient().postJsonForObject((json) => ContentInfoModel.fromJson(json), url, postParams); + } +} diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart new file mode 100644 index 0000000..61ec706 --- /dev/null +++ b/lib/app_state/app_state.dart @@ -0,0 +1,26 @@ +import 'package:car_customer_app/models/content_info_model.dart'; +import 'package:car_customer_app/models/surah_model.dart'; + +class AppState { + static final AppState _instance = AppState._internal(); + + AppState._internal(); + + factory AppState() => _instance; + + SurahModel? _surahModel; + + SurahModel? get getSurahModel => _surahModel; + + void setSurahModel(SurahModel _surahModel) { + this._surahModel = _surahModel; + } + + ContentInfoDataModel? _copyRight; + + ContentInfoDataModel? get getContentInfoModel => _copyRight; + + void setContentInfoModel(ContentInfoDataModel _copyRight) { + this._copyRight = _copyRight; + } +} diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart new file mode 100644 index 0000000..276dc8e --- /dev/null +++ b/lib/classes/colors.dart @@ -0,0 +1,31 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class MyColors { + static const Color primaryColor = Colors.white; + static const Color accentColor = Colors.blue; + static const Color darkIconColor = Color(0xff28323A); + static const Color darkTextColor = Color(0xff2B353E); + static const Color normalTextColor = Color(0xff5A5A5A); + static const Color lightTextColor = Color(0xffBFBFBF); + static const Color gradiantStartColor = Color(0xff33c0a5); + static const Color gradiantEndColor = Color(0xff259db7 ); + static const Color textMixColor = Color(0xff2BB8A6); + static const Color backgroundColor = Color(0xffF8F8F8); + static const Color grey57Color = Color(0xff575757); + static const Color grey77Color = Color(0xff777777); + static const Color grey70Color = Color(0xff707070); + static const Color greyACColor = Color(0xffACACAC); + static const Color grey98Color = Color(0xff989898); + static const Color lightGreyEFColor = Color(0xffEFEFEF); + static const Color lightGreyEDColor = Color(0xffEDEDED); + static const Color lightGreyEAColor = Color(0xffEAEAEA); + static const Color darkWhiteColor = Color(0xffE0E0E0); + static const Color redColor = Color(0xffD02127); + static const Color yellowColor = Color(0xffF4E31C); + static const Color backgroundBlackColor = Color(0xff202529); + static const Color black = Color(0xff000000); + static const Color white = Color(0xffffffff); + static const Color green = Color(0xffffffff); + static const Color borderColor = Color(0xffE8E8E8); +} diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart new file mode 100644 index 0000000..0c71f0c --- /dev/null +++ b/lib/classes/consts.dart @@ -0,0 +1,20 @@ +class ApiConsts { + //static String baseUrl = "http://10.200.204.20:2801/"; // Local server + static String baseUrl = "http://20.203.25.82"; // production server + static String baseUrlServices = baseUrl + "/services/"; // production server + // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server + static String authentication = baseUrlServices + "api/Authentication/"; + static String tangheemUsers = baseUrlServices + "api/TangheemUsers/"; + static String adminConfiguration = baseUrlServices + "api/AdminConfiguration/"; + static String user = baseUrlServices + "api/User/"; +} + +class GlobalConsts { + static String isRememberMe = "remember_me"; + static String email = "email"; + static String password = "password"; + static String bookmark = "bookmark"; + static String fontZoomSize = "font_zoom_size"; + static String welcomeVideoUrl = "welcomeVideoUrl"; + static String doNotShowWelcomeVideo = "doNotShowWelcomeVideo"; +} diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart new file mode 100644 index 0000000..5ae025e --- /dev/null +++ b/lib/classes/utils.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; + +// import 'package:fluttertoast/fluttertoast.dart'; +import 'package:car_customer_app/exceptions/api_exception.dart'; + +class Utils { + static bool _isLoadingVisible = false; + + static bool get isLoading => _isLoadingVisible; + + static void showToast(String message) { + // Fluttertoast.showToast( + // msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0); + } + + static dynamic getNotNullValue(List list, int index) { + try { + return list[index]; + } catch (ex) { + return null; + } + } + + static int stringToHex(String colorCode) { + try { + return int.parse(colorCode.replaceAll("#", "0xff")); + } catch (ex) { + return (0xff000000); + } + } + + static void showLoading(BuildContext context) { + WidgetsBinding.instance?.addPostFrameCallback((_) { + _isLoadingVisible = true; + // showDialog( + // context: context, + // barrierColor: ColorConsts.primaryBlack.withOpacity(0.5), + // builder: (BuildContext context) => LoadingDialog(), + // ).then((value) { + // _isLoadingVisible = false; + // }); + }); + } + + static void hideLoading(BuildContext context) { + if (_isLoadingVisible) { + _isLoadingVisible = false; + Navigator.of(context).pop(); + } + _isLoadingVisible = false; + } + + static void handleException(dynamic exception, Function(String)? onErrorMessage) { + String errorMessage; + if (exception is APIException) { + if (exception.message == APIException.UNAUTHORIZED) { + return; + } else { + errorMessage = exception.error?.errorMessage ?? exception.message; + } + } else { + errorMessage = APIException.UNKNOWN; + } + if (onErrorMessage != null) { + onErrorMessage(errorMessage); + } else { + showToast(errorMessage); + } + } +} diff --git a/lib/config/app_provider.dart b/lib/config/app_provider.dart index 37067c5..d81c90f 100644 --- a/lib/config/app_provider.dart +++ b/lib/config/app_provider.dart @@ -1,4 +1,4 @@ -import 'package:car_customer_app/provider/counter.dart'; +// import 'package:car_customer_app/provider/counter.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -9,11 +9,12 @@ class AppProvider extends StatelessWidget { @override Widget build(BuildContext context) { - return MultiProvider( - providers: [ - ChangeNotifierProvider(create: (_) => Counter()), - ], - child: child, - ); + return child; + // return MultiProvider( + // providers: [ + // ChangeNotifierProvider(create: (_) => Counter()), + // ], + // child: child, + // ); } } diff --git a/lib/config/background_loader.dart b/lib/config/background_loader.dart deleted file mode 100644 index 34d4a61..0000000 --- a/lib/config/background_loader.dart +++ /dev/null @@ -1,34 +0,0 @@ -//class which loads components "in the background", i.e. ui does not depend on it - -import 'package:car_customer_app/services/shared_preferences.dart'; -import 'package:injector/injector.dart'; -//import 'package:revocheckapp/services/firebase_service.dart'; - - -class BackgroundLoader { - Future loadBackgroundData() async { - //init notification setting - try { - /* - final isPromotionNotificationEnabled = await Injector.appInstance - .getDependency() - .promotionNotificationsEnabled; - if (isPromotionNotificationEnabled == null) { - await Injector.appInstance - .getDependency() - .setPromotionNotificationEnabled(true); - Injector.appInstance - .getDependency() - .subscribeForPromotions(); - } */ - } catch (_) { - //something wend wrong, set it to true - await Injector.appInstance - .getDependency() - .setPromotionNotificationEnabled(true); - /*Injector.appInstance - .getDependency() - .subscribeForPromotions();*/ - } - } -} diff --git a/lib/config/dependencies.dart b/lib/config/dependencies.dart deleted file mode 100644 index 802ac58..0000000 --- a/lib/config/dependencies.dart +++ /dev/null @@ -1,38 +0,0 @@ -// import 'package:firebase_crashlytics/firebase_crashlytics.dart'; -// import 'package:flutter/material.dart'; - -import 'package:car_customer_app/repo/account_repository.dart'; -import 'package:injector/injector.dart'; - -import 'background_loader.dart'; - - -class AppDependencies { - static void addDependencies() { - Injector injector = Injector.appInstance; - - //add dependencies as needed - injector.registerSingleton(() => AcRepository()); - - // injector.registerSingleton((injector) => AcRepository()); - - _addCrashlytics(); - _loadBackgroundTasksNonBlocking(); - } - - static void _addCrashlytics() { - // Set `enableInDevMode` to true to see reports while in debug mode - // This is only to be used for confirming that reports are being - // submitted as expected. It is not intended to be used for everyday - // development. - //Crashlytics.instance.enableInDevMode = true; - - // Pass all uncaught errors from the framework to Crashlytics. - // FlutterError.onError = Crashlytics.instance.recordFlutterError; - } - - static void _loadBackgroundTasksNonBlocking() { - final backgroundLoader = BackgroundLoader(); - backgroundLoader.loadBackgroundData(); - } -} diff --git a/lib/config/localization.dart b/lib/config/localization.dart deleted file mode 100644 index 5d7acdf..0000000 --- a/lib/config/localization.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_localizations/flutter_localizations.dart'; - -class AppLocalizations { - static const Iterable> localizationsDelegates = - [ - // ... app-specific localization delegate[s] here - // S.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate - ]; - - static const List supportedLocales = [ - const Locale("en", "US") - ]; -} diff --git a/lib/exceptions/api_exception.dart b/lib/exceptions/api_exception.dart new file mode 100644 index 0000000..9729795 --- /dev/null +++ b/lib/exceptions/api_exception.dart @@ -0,0 +1,29 @@ +import 'dart:convert'; + +import 'package:car_customer_app/api/api_client.dart'; + +class APIException implements Exception { + static const String BAD_REQUEST = 'api_common_bad_request'; + static const String UNAUTHORIZED = 'api_common_unauthorized'; + static const String FORBIDDEN = 'api_common_forbidden'; + static const String NOT_FOUND = 'api_common_not_found'; + static const String INTERNAL_SERVER_ERROR = 'api_common_internal_server_error'; + static const String UPGRADE_REQUIRED = 'api_common_upgrade_required'; + static const String BAD_RESPONSE_FORMAT = 'api_common_bad_response_format'; + static const String OTHER = 'api_common_http_error'; + static const String TIMEOUT = 'api_common_http_timeout'; + static const String UNKNOWN = 'unexpected_error'; + + final String message; + final APIError? error; + final arguments; + + const APIException(this.message, {this.arguments, this.error}); + + Map toJson() => {'message': message, 'error': error, 'arguments': '$arguments'}; + + @override + String toString() { + return jsonEncode(this); + } +} diff --git a/lib/extensions/int_extensions.dart b/lib/extensions/int_extensions.dart new file mode 100644 index 0000000..9b90b2f --- /dev/null +++ b/lib/extensions/int_extensions.dart @@ -0,0 +1,7 @@ +import 'package:flutter/cupertino.dart'; + +extension IntExtensions on int { + Widget get height => SizedBox(height: toDouble()); + + Widget get width => SizedBox(width: toDouble()); +} diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart new file mode 100644 index 0000000..9b8fc19 --- /dev/null +++ b/lib/extensions/string_extensions.dart @@ -0,0 +1,114 @@ +import 'package:flutter/cupertino.dart'; +import 'package:intl/intl.dart'; +import 'package:car_customer_app/classes/colors.dart'; + +extension EmailValidator on String { + Widget get toWidget => Text(this); + + Widget toText({Color? color, bool isBold = false,double? fontSize}) => Text( + this, + style: TextStyle(fontSize: fontSize??10, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), + ); + + Widget toText10({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(fontSize: 10, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), + ); + + Widget toText11({Color? color, bool isUnderLine = false, bool isBold = false}) => Text( + this, + style: TextStyle( + fontSize: 11, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.33, + decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => Text( + this, + textAlign: isCenter ? TextAlign.center : null, + maxLines: (maxLine > 0) ? maxLine : null, + style: TextStyle( + fontSize: 12, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.72, + decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget toText13({Color? color, bool isUnderLine = false}) => Text( + this, + style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget toText14({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 14, letterSpacing: -0.48, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText16({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 16, letterSpacing: -0.64, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText17({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 17, letterSpacing: -0.68, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText22({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText24({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText32({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + bool isValidEmail() { + return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); + } + + String toFormattedDate() { + String date = this.split("T")[0]; + String time = this.split("T")[1]; + var dates = date.split("-"); + return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a').format(DateFormat('hh:mm:ss').parse(time))}"; + } + + getMonth(int month) { + switch (month) { + case 1: + return "January"; + case 2: + return "February"; + case 3: + return "March"; + case 4: + return "April"; + case 5: + return "May"; + case 6: + return "June"; + case 7: + return "July"; + case 8: + return "August"; + case 9: + return "September"; + case 10: + return "October"; + case 11: + return "November"; + case 12: + return "December"; + } + } +} diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart new file mode 100644 index 0000000..787894d --- /dev/null +++ b/lib/extensions/widget_extensions.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +extension WidgetExtensions on Widget { + Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); + + Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this); + + Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => + Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); +} diff --git a/lib/main.dart b/lib/main.dart index 3cc464e..fd4f325 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,11 @@ import 'package:car_customer_app/config/app_provider.dart'; -import 'package:car_customer_app/config/dependencies.dart'; + import 'package:car_customer_app/theme/app_theme.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:sizer/sizer.dart'; -import 'config/localization.dart'; + import 'config/routes.dart'; Future main() async { @@ -24,10 +24,7 @@ Future main() async { } class MyApp extends StatelessWidget { - // This widget is the root of your application. - MyApp() { - AppDependencies.addDependencies(); - } + @override Widget build(BuildContext context) { diff --git a/lib/models/content_info_model.dart b/lib/models/content_info_model.dart new file mode 100644 index 0000000..4eec746 --- /dev/null +++ b/lib/models/content_info_model.dart @@ -0,0 +1,65 @@ +class ContentInfoModel { + int? totalItemsCount; + int? statusCode; + String? message; + List? data; + + ContentInfoModel({this.totalItemsCount, this.statusCode, this.message, this.data}); + + ContentInfoModel.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = []; + json['data'].forEach((v) { + data?.add(new ContentInfoDataModel.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = this.totalItemsCount; + data['statusCode'] = this.statusCode; + data['message'] = this.message; + if (this.data != null) { + data['data'] = this.data?.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ContentInfoDataModel { + int? contentInfoId; + int? contentTypeId; + String? content; + String? contentTypeNameEn; + String? contentTypeNameAr; + String? fileName; + String? exposeFilePath; + + ContentInfoDataModel({this.contentInfoId, this.contentTypeId, this.content, this.contentTypeNameEn, this.contentTypeNameAr, this.fileName, this.exposeFilePath}); + + ContentInfoDataModel.fromJson(Map json) { + contentInfoId = json['contentInfoId']; + contentTypeId = json['contentTypeId']; + content = json['content']; + contentTypeNameEn = json['contentTypeNameEn']; + contentTypeNameAr = json['contentTypeNameAr']; + fileName = json['fileName']; + exposeFilePath = json['exposeFilePath']; + } + + Map toJson() { + final Map data = new Map(); + data['contentInfoId'] = this.contentInfoId; + data['contentTypeId'] = this.contentTypeId; + data['content'] = this.content; + data['contentTypeNameEn'] = this.contentTypeNameEn; + data['contentTypeNameAr'] = this.contentTypeNameAr; + data['fileName'] = this.fileName; + data['exposeFilePath'] = this.exposeFilePath; + return data; + } +} diff --git a/lib/models/member_model.dart b/lib/models/member_model.dart new file mode 100644 index 0000000..d968827 --- /dev/null +++ b/lib/models/member_model.dart @@ -0,0 +1,62 @@ +class MemberModel { + int? totalItemsCount; + int? statusCode; + String? message; + List? data; + + MemberModel({this.totalItemsCount, this.statusCode, this.message, this.data}); + + MemberModel.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = []; + json['data'].forEach((v) { + data?.add(new MemberDataModel.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = this.totalItemsCount; + data['statusCode'] = this.statusCode; + data['message'] = this.message; + if (this.data != null) { + data['data'] = this.data?.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class MemberDataModel { + int? committeeId; + String? firstName; + String? lastName; + String? description; + String? picture; + int? orderNo; + + MemberDataModel({this.committeeId, this.firstName, this.lastName, this.description, this.picture, this.orderNo}); + + MemberDataModel.fromJson(Map json) { + committeeId = json['committeeId']; + firstName = json['firstName']; + lastName = json['lastName']; + description = json['description']; + picture = json['picture']; + orderNo = json['orderNo']; + } + + Map toJson() { + final Map data = new Map(); + data['committeeId'] = this.committeeId; + data['firstName'] = this.firstName; + data['lastName'] = this.lastName; + data['description'] = this.description; + data['picture'] = this.picture; + data['orderNo'] = this.orderNo; + return data; + } +} diff --git a/lib/models/surah_model.dart b/lib/models/surah_model.dart new file mode 100644 index 0000000..acc171a --- /dev/null +++ b/lib/models/surah_model.dart @@ -0,0 +1,74 @@ +class SurahModel { + int? totalItemsCount; + int? statusCode; + String? message; + List? data; + + SurahModel({this.totalItemsCount, this.statusCode, this.message, this.data}); + + SurahModel.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = []; + json['data'].forEach((v) { + data?.add(SurahModelData.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = totalItemsCount; + data['statusCode'] = statusCode; + data['message'] = message; + if (this.data != null) { + data['data'] = this.data?.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class SurahModelData { + int? id; + int? surahID; + String? nameAR; + String? nameEN; + int? numberOfAyahs; + String? englishNameTranslation; + int? revelationID; + String? revelationType; + int? startPageNo; + int? endPageNo; + + SurahModelData({this.id, this.surahID, this.nameAR, this.nameEN, this.numberOfAyahs, this.englishNameTranslation, this.revelationID, this.revelationType, this.startPageNo, this.endPageNo}); + + SurahModelData.fromJson(Map json) { + id = json['id']; + surahID = json['surahID']; + nameAR = json['nameAR']; + nameEN = json['nameEN']; + numberOfAyahs = json['numberOfAyahs']; + englishNameTranslation = json['englishNameTranslation']; + revelationID = json['revelation_ID']; + revelationType = json['revelationType']; + startPageNo = json['startPageNo']; + endPageNo = json['endPageNo']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['surahID'] = this.surahID; + data['nameAR'] = this.nameAR; + data['nameEN'] = this.nameEN; + data['numberOfAyahs'] = this.numberOfAyahs; + data['englishNameTranslation'] = this.englishNameTranslation; + data['revelation_ID'] = this.revelationID; + data['revelationType'] = this.revelationType; + data['startPageNo'] = this.startPageNo; + data['endPageNo'] = this.endPageNo; + return data; + } +} diff --git a/lib/pages/dashboard/dashboard_page.dart b/lib/pages/dashboard/dashboard_page.dart index 02a31b5..27621ae 100644 --- a/lib/pages/dashboard/dashboard_page.dart +++ b/lib/pages/dashboard/dashboard_page.dart @@ -2,7 +2,9 @@ import 'package:car_customer_app/theme/colors.dart'; import 'package:car_customer_app/utils/navigator.dart'; import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:flutter/material.dart'; class DashboardPage extends StatelessWidget { @@ -15,10 +17,7 @@ class DashboardPage extends StatelessWidget { drawer: showDrawer(context), body: Container( child: Center( - child: Txt( - "Dashboard/Main Page", - txtType: TxtType.heading3, - ), + child: "Dashboard/Main Page".toText24(), ), ), ); @@ -50,13 +49,8 @@ class DashboardPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Txt( - "User Name", - txtType: TxtType.heading3, - ), - Txt( - "User role or title", - ), + "User Name".toText24(), + "User role or title".toText12(), ], ), ), @@ -69,19 +63,19 @@ class DashboardPage extends StatelessWidget { ), ListTile( leading: Icon(Icons.notifications), - title: Txt("Notifications"), + title: "Notifications".toText12(), ), ListTile( leading: Icon(Icons.settings), - title: Txt("General"), + title: "General".toText12(), ), ListTile( leading: Icon(Icons.person), - title: Txt("Account"), + title: "Account".toText12(), ), ListTile( leading: Icon(Icons.logout), - title: Txt("Sign Out"), + title: "Sign Out".toText12(), onTap: () { pop(context); pop(context); diff --git a/lib/pages/user/complete_profile_page.dart b/lib/pages/user/complete_profile_page.dart index f76f266..1bd71cd 100644 --- a/lib/pages/user/complete_profile_page.dart +++ b/lib/pages/user/complete_profile_page.dart @@ -1,7 +1,9 @@ import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:flutter/material.dart'; @@ -18,40 +20,35 @@ class CompleteProfilePage extends StatelessWidget { padding: EdgeInsets.all(40), child: Column( children: [ - Txt( - "Complete Profile", - txtType: TxtType.heading3, - ), - mHeight(12), + "Complete Profile".toText24(), + 12.height, + TxtField( hint: "First Name", ), - mHeight(12), + 12.height, TxtField( hint: "Surname", ), - mHeight(12), + 12.height, TxtField( hint: "Email", ), - mHeight(12), + 12.height, TxtField( hint: "Create Password", ), - mHeight(12), + 12.height, TxtField( hint: "Confirm Password", ), - mHeight(12), + 12.height, TxtField( hint: "Phone Number", ), - mHeight(50), - Txt( - "By creating an account you agree to our Terms of Service and Privacy Policy", - textAlign: TextAlign.center, - ), - mHeight(16), + 50.height, + "By creating an account you agree to our Terms of Service and Privacy Policy".toText12(), + 16.height, ShowFillButton( title: "Continue", width: double.infinity, diff --git a/lib/pages/user/forget_password_page.dart b/lib/pages/user/forget_password_page.dart index 01db9aa..3d0e045 100644 --- a/lib/pages/user/forget_password_page.dart +++ b/lib/pages/user/forget_password_page.dart @@ -3,7 +3,9 @@ import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/dialog/dialogs.dart'; import 'package:car_customer_app/widgets/dialog/message_dialog.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:flutter/material.dart'; @@ -18,18 +20,15 @@ class ForgetPasswordPage extends StatelessWidget { padding: EdgeInsets.all(40), child: Column( children: [ - Txt( - "Retrieve Password", - txtType: TxtType.heading3, - ), - mHeight(12), + "Retrieve Password".toText24(), + 12.height, TxtField( hint: "Phone Number", ), TxtField( hint: "Email", ), - mHeight(40), + 40.height, ShowFillButton( title: "Continue", width: double.infinity, diff --git a/lib/pages/user/login_verification_page.dart b/lib/pages/user/login_verification_page.dart index 54b469a..3a0166b 100644 --- a/lib/pages/user/login_verification_page.dart +++ b/lib/pages/user/login_verification_page.dart @@ -6,7 +6,9 @@ import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/button/show_image_button.dart'; import 'package:car_customer_app/widgets/dialog/dialogs.dart'; import 'package:car_customer_app/widgets/dialog/message_dialog.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:flutter/material.dart'; @@ -21,10 +23,8 @@ class LoginVerificationPage extends StatelessWidget { padding: EdgeInsets.all(40), child: Column( children: [ - Txt( - "Verify Account", - txtType: TxtType.heading3, - ), + "Verify Account".toText24(), + mFlex(2), Row( children: [ @@ -46,7 +46,7 @@ class LoginVerificationPage extends StatelessWidget { icon: icons + "ic_fingerprint.png", ), ), - mWidth(20), + 20.width, Expanded( child: ShowImageButton( onClick: () { @@ -58,7 +58,7 @@ class LoginVerificationPage extends StatelessWidget { ), ], ), - mHeight(40), + 40.height, Row( children: [ Expanded( @@ -70,7 +70,7 @@ class LoginVerificationPage extends StatelessWidget { icon: icons + "ic_sms.png", ), ), - mWidth(20), + 20.width, Expanded( child: ShowImageButton( onClick: () { diff --git a/lib/pages/user/login_verify_account_page.dart b/lib/pages/user/login_verify_account_page.dart index 301623e..f8cdfc8 100644 --- a/lib/pages/user/login_verify_account_page.dart +++ b/lib/pages/user/login_verify_account_page.dart @@ -7,7 +7,9 @@ import 'package:car_customer_app/widgets/button/show_image_button.dart'; import 'package:car_customer_app/widgets/dialog/dialogs.dart'; import 'package:car_customer_app/widgets/dialog/message_dialog.dart'; import 'package:car_customer_app/widgets/dialog/otp_dialog.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:flutter/material.dart'; @@ -22,10 +24,7 @@ class LoginVerifyAccountPage extends StatelessWidget { padding: EdgeInsets.all(40), child: Column( children: [ - Txt( - "Verify Account", - txtType: TxtType.heading3, - ), + "Verify Account".toText24(), mFlex(1), TxtField( hint: "Enter Phone number to verify", @@ -40,7 +39,7 @@ class LoginVerifyAccountPage extends StatelessWidget { onClick: () { pop(context); delay(300).then( - (value) => showMDialog( + (value) => showMDialog( context, child: MessageDialog( title: "Phone Number Verified", @@ -57,7 +56,7 @@ class LoginVerifyAccountPage extends StatelessWidget { icon: icons + "ic_sms.png", ), ), - mWidth(20), + 20.width, Expanded( child: ShowImageButton( onClick: () { diff --git a/lib/pages/user/register_page.dart b/lib/pages/user/register_page.dart index 8247bdf..cb93d7d 100644 --- a/lib/pages/user/register_page.dart +++ b/lib/pages/user/register_page.dart @@ -1,7 +1,9 @@ import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:flutter/material.dart'; @@ -16,27 +18,23 @@ class RegisterPage extends StatelessWidget { padding: EdgeInsets.all(40), child: Column( children: [ - Txt( - "Enter Phone Number", - txtType: TxtType.heading3, - ), - mHeight(12), + "Enter Phone Number".toText24(), + + 12.height, TxtField( hint: "Enter Phone number to Register", ), TxtField( hint: "Enter Phone number to Register", ), - mHeight(40), - Txt( - "Or Enter Email", - txtType: TxtType.heading3, - ), - mHeight(12), + 40.height, + "Or Enter Email".toText24(), + 12.height, + TxtField( hint: "Enter Email to Register", ), - mHeight(50), + 50.height, ShowFillButton( title: "Continue", width: double.infinity, diff --git a/lib/pages/user/register_selection_page.dart b/lib/pages/user/register_selection_page.dart index 30d85c3..f49015a 100644 --- a/lib/pages/user/register_selection_page.dart +++ b/lib/pages/user/register_selection_page.dart @@ -3,7 +3,9 @@ import 'package:car_customer_app/utils/navigator.dart'; import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:flutter/material.dart'; class RegisterSelectionPage extends StatelessWidget { @@ -17,10 +19,7 @@ class RegisterSelectionPage extends StatelessWidget { padding: EdgeInsets.all(40), child: Column( children: [ - Txt( - "Welcome Message", - txtType: TxtType.heading3, - ), + "Welcome Message".toText24(), mFlex(1), ShowFillButton( title: "Log In", @@ -29,7 +28,7 @@ class RegisterSelectionPage extends StatelessWidget { navigateWithName(context, AppRoutes.loginVerifyAccount); }, ), - mHeight(20), + 20.height, ShowFillButton( title: "Sign Up", width: double.infinity, @@ -37,7 +36,7 @@ class RegisterSelectionPage extends StatelessWidget { navigateWithName(context, AppRoutes.register); }, ), - mHeight(20), + 20.height, ShowFillButton( title: "Forget Password", width: double.infinity, diff --git a/lib/pages/user/splash_page.dart b/lib/pages/user/splash_page.dart index 4b937da..df80890 100644 --- a/lib/pages/user/splash_page.dart +++ b/lib/pages/user/splash_page.dart @@ -1,9 +1,10 @@ import 'dart:async'; import 'package:car_customer_app/config/routes.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:car_customer_app/utils/navigator.dart'; import 'package:car_customer_app/utils/utils.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:flutter/material.dart'; class SplashPage extends StatelessWidget { @@ -16,29 +17,15 @@ class SplashPage extends StatelessWidget { child: Column( children: [ mFlex(5), - Txt( - "Logo", - fontSize: 45, - bold: true, - ), + "Logo".toText(fontSize: 45, isBold: true), mFlex(3), - Txt( - "First Time Log In", - txtType: TxtType.heading1, - isFlatButton: true, - onTap: () { - navigateWithName(context, AppRoutes.registerSelection); - }, - ), + "First Time Log In".toText(fontSize: 18, isBold: true).onPress(() { + navigateWithName(context, AppRoutes.registerSelection); + }), mFlex(1), - Txt( - "Already Signed Up and Logged In", - txtType: TxtType.heading1, - isFlatButton: true, - onTap: () { - navigateWithName(context, AppRoutes.loginVerification); - }, - ), + "Already Signed Up and Logged In".toText(fontSize: 18, isBold: true).onPress(() { + navigateWithName(context, AppRoutes.loginVerification); + }), mFlex(5), ], ), diff --git a/lib/provider/counter.dart b/lib/provider/counter.dart deleted file mode 100644 index 0272327..0000000 --- a/lib/provider/counter.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -class Counter with ChangeNotifier, DiagnosticableTreeMixin { - int _count = 0; - - int get count => _count; - - void increment() { - _count++; - notifyListeners(); - } - - /// Makes `Counter` readable inside the devtools by listing all of its properties - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(IntProperty('count', count)); - } -} \ No newline at end of file diff --git a/lib/repo/account_repository.dart b/lib/repo/account_repository.dart deleted file mode 100644 index 0140f65..0000000 --- a/lib/repo/account_repository.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:car_customer_app/models/account.dart'; -import 'package:car_customer_app/models/response_models.dart'; -import 'package:car_customer_app/services/backend_service.dart'; -import 'package:injector/injector.dart'; - - - -abstract class IAcRepository { - Future getAccountList(); - - Future updateAccount(String dataAsJson); -} - -class AcRepository implements IAcRepository { - static const String ACCOUNT_API_CONTROLLER_MOBILE = - "AccountApiControllerMobile/"; - - static const String ACCOUNT_LIST = ACCOUNT_API_CONTROLLER_MOBILE + "list"; - static const String UPDATE_LIST = - ACCOUNT_API_CONTROLLER_MOBILE + "saveaccountselected"; - - @override - Future getAccountList() async { - BackendResponse response = await Injector.appInstance - .getDependency() - .getAuthenticatedAPI(ACCOUNT_LIST); - - if (response != null && response.isOk) { - return Account.fromJson(response.result); - } else { - throw Exception(); - } - } - - @override - Future updateAccount(String dataAsJson) async { - BackendResponse response = await Injector.appInstance - .getDependency() - .postAuthenticatedAPI(UPDATE_LIST, dataAsJson); - - if (response != null && response.isOk) { - //if parsing failed, throw exception - return response; - } else { - throw Exception(); - } - } -} diff --git a/lib/services/backend_service.dart b/lib/services/backend_service.dart deleted file mode 100644 index c25c80c..0000000 --- a/lib/services/backend_service.dart +++ /dev/null @@ -1,127 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'package:car_customer_app/models/response_models.dart'; -import 'package:car_customer_app/services/secure_storage.dart'; -import 'package:http/http.dart'; -import 'package:injector/injector.dart'; - -import 'http_service.dart'; -import 'network_service.dart'; - -abstract class IBackendApiService { - Future getUnauthenticatedAPI(String route); - - Future getAuthenticatedAPI(String route); - - Future postUnauthenticatedAPI( - String route, String dataAsJson); - - Future postAuthenticatedAPI(String route, String dataAsJson); - - Future deleteAuthenticatedAPI(String route, String id); -} - -class BackendApiService implements IBackendApiService { - static String _homeUrl = "https://check.revotec.eu/check2/"; - static String _serverApiBaseUrl = _homeUrl + "mapi/v1/"; - - static String get homeUrl => _homeUrl; - - final ISecureStorage _secureStorage = - Injector.appInstance.getDependency(); - final IHttpService _httpService = - Injector.appInstance.getDependency(); - - ///internal helper functions which executes the given api call - ///and wraps the response - Future _callApi(Future callback) async { - Response response; - try { - //execute future - response = await callback; - //check response code, and if not ok return isOk = false - //200 for Get - //201 for Post - - // print("res121: " + - // response.statusCode.toString() + - // " Body:" + - // response.body.toString()); - //if delete request sent so server is returning 204 in case of success. - if (response.statusCode == 204) - return BackendResponse(id: 1, isOk: true, result: null); - - if (response.statusCode != 200 && response.statusCode != 201) - return BackendResponse(id: -1, isOk: false, result: null); - //if response code is good then parse message and return parsed response - return BackendResponse.fromJson(json.decode(response.body)); - //return BackendResponse.fromJson(dioResponse.body); - } catch (e) { - return BackendResponse(id: -1, isOk: false, result: null); - // try { - // return BackendResponse.fromJson(json.decode(response.body)); - // } catch (e) { - // return BackendResponse(id:-1, isOk:false,result: null); - // } - } - } - - @override - Future getAuthenticatedAPI(String route) async { - await checkConnection(); - final token = await _secureStorage.readBearerToken(); - return _callApi(_httpService.get(_serverApiBaseUrl + route, headers: { - 'Content-Type': 'application/json', - 'Accept': '*/*', - HttpHeaders.authorizationHeader: "Bearer $token" - })); - } - - @override - Future getUnauthenticatedAPI(String route) async { - await checkConnection(); - return _callApi(_httpService.get(_serverApiBaseUrl + route, - headers: {'Content-Type': 'application/json', 'Accept': '*/*'})); - } - - @override - Future postAuthenticatedAPI( - String route, String dataAsJson) async { - await checkConnection(); - final token = await _secureStorage.readBearerToken(); - // print("res121: " + _serverApiBaseUrl + route); - return _callApi(_httpService - .post(_serverApiBaseUrl + route, body: dataAsJson, headers: { - 'Content-Type': 'application/json', - 'Accept': '*/*', - HttpHeaders.authorizationHeader: "Bearer $token" - })); - } - - @override - Future postUnauthenticatedAPI( - String route, String dataAsJson) async { - await checkConnection(); - return _callApi(_httpService.post(_serverApiBaseUrl + route, - body: dataAsJson, headers: {'Content-Type': 'application/json'})); - } - - Future checkConnection() async { - if (!(await Injector.appInstance - .getDependency() - .isHostAvailable(_homeUrl))) throw NetworkException(); - } - - @override - Future deleteAuthenticatedAPI( - String route, String id) async { - await checkConnection(); - final token = await _secureStorage.readBearerToken(); - return _callApi( - _httpService.delete(_serverApiBaseUrl + route + "/" + id, headers: { - 'Content-Type': 'application/json', - 'Accept': '*/*', - HttpHeaders.authorizationHeader: "Bearer $token" - })); - } -} diff --git a/lib/services/firebase_service.dart b/lib/services/firebase_service.dart deleted file mode 100644 index ad76959..0000000 --- a/lib/services/firebase_service.dart +++ /dev/null @@ -1,180 +0,0 @@ -/* -import 'dart:io' show Platform; -import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; - -abstract class IFirebaseService { - Future get token; - - Future backgroundMessageHandler(Map message); - - Future messageHandler(Map message); - - Future onLaunch(Map message); - - Future onResume(Map message); - - void subscribeForPromotions(); - - void unsubscribeFromPromotions(); -} - -//https://medium.com/@SebastianEngel/easy-push-notifications-with-flutter-and-firebase-cloud-messaging-d96084f5954f -class FirebaseService implements IFirebaseService { - FirebaseMessaging _firebaseMessaging; - - FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin; - - FirebaseService() {. - _firebaseMessaging = FirebaseMessaging(); - - //https://github.com/FirebaseExtended/flutterfire/issues/1695 - _firebaseMessaging.configure( - onMessage: messageHandler, - onBackgroundMessage: - Platform.isAndroid ? myBackgroundMessageHandler : null, - onLaunch: onLaunch, - onResume: onResume, - ); - - //monitor firebase token changes - //https://firebase.google.com/docs/cloud-messaging/android/client#sample-register - ///The registration token may change when: - // - //The app deletes Instance ID - //The app is restored on a new device - //The user uninstalls/reinstall the app - //The user clears app data. - /// - - //for the first release we don't care about token refreshes - /*Stream fcmStream = _firebaseMessaging.onTokenRefresh; - fcmStream.listen((token) { - - });*/ - - //ios specific settings - //taken from https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_messaging/example/lib/main.dart - _firebaseMessaging.requestNotificationPermissions( - const IosNotificationSettings( - sound: true, badge: true, alert: true, provisional: true)); - _firebaseMessaging.onIosSettingsRegistered - .listen((IosNotificationSettings settings) { - print("Settings registered: $settings"); - }); - - var initializationSettingsAndroid = - AndroidInitializationSettings('app_icon'); - var initializationSettingsIOS = - IOSInitializationSettings(onDidReceiveLocalNotification: onDidReceiveLocalNotification); - var initializationSettings = InitializationSettings( - initializationSettingsAndroid, initializationSettingsIOS); - flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - flutterLocalNotificationsPlugin.initialize(initializationSettings, - onSelectNotification: selectNotification); - } - - Future onDidReceiveLocalNotification(int id, String title, String body, String payload) async{ - var androidPlatformChannelSpecifics = AndroidNotificationDetails( - 'new_message_channel_id', - 'Neue Nachricht', - 'Channel für neue Nachrichten', - importance: Importance.Max, - priority: Priority.High, - ticker: 'ticker'); - var iOSPlatformChannelSpecifics = IOSNotificationDetails(); - var platformChannelSpecifics = NotificationDetails( - androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); - await flutterLocalNotificationsPlugin.show( - 0, - title, - body, - platformChannelSpecifics); - } - - @override - Future backgroundMessageHandler(Map message) async { - await myBackgroundMessageHandler(message); - } - - @override - Future messageHandler(Map message) async { - print("onMessage: $message"); - -// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project - - var androidPlatformChannelSpecifics = AndroidNotificationDetails( - 'new_message_channel_id', - 'Neue Nachricht', - 'Channel für neue Nachrichten', - importance: Importance.Max, - priority: Priority.High, - ticker: 'ticker'); - var iOSPlatformChannelSpecifics = IOSNotificationDetails(); - var platformChannelSpecifics = NotificationDetails( - androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); - - if(Platform.isAndroid) { - await flutterLocalNotificationsPlugin.show( - 0, - message["notification"]["title"], - message["notification"]["body"], - platformChannelSpecifics); - }else if(Platform.isIOS){ - await flutterLocalNotificationsPlugin.show( - 0, - message["aps"]["alert"]["title"], - message["aps"]["alert"]["body"], - platformChannelSpecifics); - } - } - - Future selectNotification(String payload) async { - if (payload != null) { - debugPrint('notification payload: ' + payload); - } - } - - @override - Future onLaunch(Map message) async { - print("onLaunch: $message"); - } - - @override - Future onResume(Map message) async { - print("onResume: $message"); - } - - @override - Future get token => _firebaseMessaging.getToken(); - - @override - void subscribeForPromotions() { - _firebaseMessaging.subscribeToTopic("promotions"); - } - - @override - void unsubscribeFromPromotions() { - _firebaseMessaging.unsubscribeFromTopic("promotions"); - } -} - -Future myBackgroundMessageHandler(Map message) { - debugPrint("BACKGROUND MESSAGE RECEIVED"); - print("BACKGROUND MESSAGE RECEIVED"); - return Future.value(() => true); - - /*if (message.containsKey('data')) { - // Handle data message - final dynamic data = message['data']; - } - - if (message.containsKey('notification')) { - // Handle notification message - final dynamic notification = message['notification']; - }*/ - - // Or do other work. -} -*/ \ No newline at end of file diff --git a/lib/services/http_service.dart b/lib/services/http_service.dart deleted file mode 100644 index ff99ed0..0000000 --- a/lib/services/http_service.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'dart:async'; - - -import 'package:http/http.dart' as http; -import 'package:http/http.dart'; -import 'package:path/path.dart'; -import 'package:injector/injector.dart'; - -abstract class IHttpService { - Future post(url, - {Map headers, body, Encoding encoding}); - - Future get(url, {Map headers}); - - Future delete(url, {Map headers}); -} - -class HttpService implements IHttpService { - @override - Future delete(url, {Map? headers}) { - return http.delete(url, headers: headers); - } - - @override - Future get(url, {Map? headers}) { - return http.get(url, headers: headers); - } - - @override - Future post(url, - {Map? headers, body, Encoding? encoding}) { - return http.post(url, headers: headers, body: body, encoding: encoding); - } -} diff --git a/lib/services/media_service.dart b/lib/services/media_service.dart deleted file mode 100644 index 0762d7f..0000000 --- a/lib/services/media_service.dart +++ /dev/null @@ -1,26 +0,0 @@ -// import 'dart:io'; -// -// import 'package:image_picker/image_picker.dart'; -// -// abstract class IMediaService { -// Future takePicture(); -// -// Future openImageFromGallery(); -// } -// -// class MediaService implements IMediaService { -// @override -// Future openImageFromGallery() async { -// final pickedFile = -// await ImagePicker().getImage(source: ImageSource.gallery); -// if (pickedFile == null) return null; -// return File(pickedFile.path); -// } -// -// @override -// Future takePicture() async { -// final pickedFile = await ImagePicker().getImage(source: ImageSource.camera); -// if (pickedFile == null) return null; -// return File(pickedFile.path); -// } -// } diff --git a/lib/services/network_service.dart b/lib/services/network_service.dart deleted file mode 100644 index 50a861d..0000000 --- a/lib/services/network_service.dart +++ /dev/null @@ -1,25 +0,0 @@ - -import 'dart:io'; - -abstract class INetworkService { - Future isHostAvailable(String endpoint); -} - -class NetworkService implements INetworkService{ - @override - Future isHostAvailable(String endpoint) async { - try { - final result = await InternetAddress.lookup(endpoint.substring(endpoint.indexOf('//')+2).substring(0,endpoint.substring(endpoint.indexOf('//')+2).indexOf('/'))); - if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) { - return true; - } else{ - return false; - } - } on SocketException catch (_) { - return false; - } - } -} - -class NetworkException implements Exception { -} diff --git a/lib/services/secure_storage.dart b/lib/services/secure_storage.dart deleted file mode 100644 index 7622f7f..0000000 --- a/lib/services/secure_storage.dart +++ /dev/null @@ -1,33 +0,0 @@ -abstract class ISecureStorage { - Future readBearerToken(); - - Future clearUserCredentials(); -} - -class SecureStorage implements ISecureStorage { - ///return bearer token if present, or null if not - @override - Future readBearerToken() async { - try { - return ""; - } catch (_) { - //an error occured returning null - return ""; - } - } - - ///returns true if write was successful, false otherwise - @override - Future writeBearerToken(String token) async { - try { - await ""; - return true; - } catch (_) { - //an error occured returning false - return false; - } - } - - @override - Future clearUserCredentials() async {} -} diff --git a/lib/services/shared_preferences.dart b/lib/services/shared_preferences.dart deleted file mode 100644 index 367bcbf..0000000 --- a/lib/services/shared_preferences.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'dart:convert'; - -import 'package:car_customer_app/models/config_model.dart'; - -import 'package:shared_preferences/shared_preferences.dart' -as SharedPrefsPlugin; - -/// -/// Taken from AlarmGuide Project -/// - -abstract class ISharedPreferences { - Future get authState; - - Future setAuthState(int authState); - - Future get configState; - - Future setConfigState(int confState); - - Future get config; - - Future setConfig(ConfigModel config); - - Future get promotionNotificationsEnabled; - - Future setPromotionNotificationEnabled(bool newSetting); - - Future get helpAlreadyShown; - - Future setHelpAlreadyShown(); - - Future get useS3; - - Future setUseS3(int value); -} - -class SharedPreferences implements ISharedPreferences { - static const String _AUTH_STATE_KEY = "auth_key"; - static const String _CONFIG_KEY = "config"; - static const String _CONFIG_STATE_KEY = "config_key"; - static const String _PROMOTION_NOTIFICATION_KEY = "promotion"; - static const String _HELP_ALREADY_SHOWN = "help_shown"; - static const String _USE_S3 = "s3"; - - @override - Future get authState async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getInt(_AUTH_STATE_KEY); - } - - @override - Future setAuthState(int authState) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setInt(_AUTH_STATE_KEY, authState); - } - - @override - Future get config async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - final configAsJson = sharedPrefs.getString(_CONFIG_KEY); - return ConfigModel.fromJson(jsonDecode(configAsJson!)); - } - - @override - Future setConfig(ConfigModel config) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setString(_CONFIG_KEY, jsonEncode(config)); - setConfigState(1); - } - - @override - Future get promotionNotificationsEnabled async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getBool(_PROMOTION_NOTIFICATION_KEY); - } - - @override - Future setPromotionNotificationEnabled(bool newSetting) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setBool(_PROMOTION_NOTIFICATION_KEY, newSetting); - } - - @override - Future get helpAlreadyShown async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getBool(_HELP_ALREADY_SHOWN); - } - - @override - Future setHelpAlreadyShown() async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setBool(_HELP_ALREADY_SHOWN, true); - } - - @override - Future get configState async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getInt(_CONFIG_STATE_KEY); - } - - @override - Future setConfigState(int confState) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setInt(_CONFIG_STATE_KEY, confState); - } - - @override - Future setUseS3(int value) async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - sharedPrefs.setInt(_USE_S3, value); - } - - @override - Future get useS3 async { - final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance(); - return sharedPrefs.getInt(_USE_S3); - } -} diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 34f66ea..fdf7639 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -5,7 +5,6 @@ import 'dart:ui'; import 'package:car_customer_app/config/constants.dart'; import 'package:car_customer_app/theme/colors.dart'; -import 'package:car_customer_app/widgets/txt.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; @@ -44,12 +43,12 @@ Widget spacerHorizontal(double v) { ); } -Widget mHeight(double f) { - return Container( - width: f, - height: f, - ); -} +// Widget mHeight(double f) { +// return Container( +// width: f, +// height: f, +// ); +// } Widget mDivider(Color color, {double? h}) { return Container( @@ -89,12 +88,12 @@ InputDecoration txtField(String label) { ); } -Widget mWidth(double f) { - return Container( - width: f, - height: f, - ); -} +// Widget mWidth(double f) { +// return Container( +// width: f, +// height: f, +// ); +// } Widget mFlex(int f) { return Flexible( @@ -119,46 +118,46 @@ spacer() { height: 8, ); } - -Widget floatButton(String icon, {Color? color, required Function onClick, String? title}) { - return Padding( - padding: const EdgeInsets.only(top: 12, bottom: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - FloatingActionButton( - onPressed: () { - onClick(); - }, - heroTag: icon, - backgroundColor: accentColor, - elevation: 4, - child: Container( - child: SvgPicture.asset( - categorySvgIcons + icon, - color: color, - ), - width: double.infinity, - height: double.infinity, - decoration: containerRadius(Colors.white, 200), - clipBehavior: Clip.antiAlias, - padding: EdgeInsets.all(15), - margin: EdgeInsets.all(1), - ), - ), - if (title != null) mHeight(2.w), - if (title != null) - Txt( - title, - fontSize: 12.sp, - bold: true, - color: headingColor, - ) - ], - ), - ); -} +// +// Widget floatButton(String icon, {Color? color, required Function onClick, String? title}) { +// return Padding( +// padding: const EdgeInsets.only(top: 12, bottom: 12), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.center, +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// FloatingActionButton( +// onPressed: () { +// onClick(); +// }, +// heroTag: icon, +// backgroundColor: accentColor, +// elevation: 4, +// child: Container( +// child: SvgPicture.asset( +// categorySvgIcons + icon, +// color: color, +// ), +// width: double.infinity, +// height: double.infinity, +// decoration: containerRadius(Colors.white, 200), +// clipBehavior: Clip.antiAlias, +// padding: EdgeInsets.all(15), +// margin: EdgeInsets.all(1), +// ), +// ), +// if (title != null) mHeight(2.w), +// if (title != null) +// Txt( +// title, +// fontSize: 12.sp, +// bold: true, +// color: headingColor, +// ) +// ], +// ), +// ); +// } navigateTo(context, page) { Navigator.push(context, MaterialPageRoute(builder: (context) => page)); diff --git a/lib/widgets/app_bar.dart b/lib/widgets/app_bar.dart index 700a4ac..96ce735 100644 --- a/lib/widgets/app_bar.dart +++ b/lib/widgets/app_bar.dart @@ -1,5 +1,6 @@ import 'package:car_customer_app/theme/colors.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; import 'package:flutter/material.dart'; import 'package:sizer/sizer.dart'; @@ -20,9 +21,6 @@ AppBar appBar({ color: backIconColor ?? Colors.black, //change your color here ), actions: actions, - title: Txt( - title ?? "", - txtType: TxtType.appBar, - ), + title: (title ?? "").toText(fontSize: 20,isBold: true), ); } diff --git a/lib/widgets/button/show_image_button.dart b/lib/widgets/button/show_image_button.dart index cbb50d9..a34e487 100644 --- a/lib/widgets/button/show_image_button.dart +++ b/lib/widgets/button/show_image_button.dart @@ -1,8 +1,9 @@ import 'package:car_customer_app/theme/colors.dart'; import 'package:car_customer_app/utils/utils.dart'; import 'package:flutter/material.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; -import '../txt.dart'; class ShowImageButton extends StatelessWidget { String icon, title; @@ -29,12 +30,8 @@ class ShowImageButton extends StatelessWidget { color: Colors.white, ), ), - mHeight(12), - Txt( - title, - txtType: TxtType.heading2, - color: Colors.blue, - ) + 12.height, + title.toText(color: Colors.blue,isBold: true,fontSize: 18), ], ), ), diff --git a/lib/widgets/dialog/message_dialog.dart b/lib/widgets/dialog/message_dialog.dart index fd30637..62f4cc7 100644 --- a/lib/widgets/dialog/message_dialog.dart +++ b/lib/widgets/dialog/message_dialog.dart @@ -2,13 +2,15 @@ import 'package:car_customer_app/theme/colors.dart'; import 'package:car_customer_app/utils/navigator.dart'; import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:flutter/material.dart'; class MessageDialog extends StatelessWidget { String? title, buttonTitle; VoidCallback? onClick; - MessageDialog({this.title, this.buttonTitle,this.onClick}); + + MessageDialog({this.title, this.buttonTitle, this.onClick}); @override Widget build(BuildContext context) { @@ -19,11 +21,8 @@ class MessageDialog extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Txt( - title ?? "message", - txtType: TxtType.heading3, - ), - mHeight(40), + (title ?? "message").toText24(), + 40.height, ShowFillButton( title: buttonTitle ?? "Continue", width: double.infinity, diff --git a/lib/widgets/dialog/otp_dialog.dart b/lib/widgets/dialog/otp_dialog.dart index b8880e2..deeb32e 100644 --- a/lib/widgets/dialog/otp_dialog.dart +++ b/lib/widgets/dialog/otp_dialog.dart @@ -2,7 +2,8 @@ import 'package:car_customer_app/theme/colors.dart'; import 'package:car_customer_app/utils/navigator.dart'; import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; import 'package:flutter/material.dart'; class OtpDialog extends StatelessWidget { @@ -19,11 +20,8 @@ class OtpDialog extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Txt( - "Please insert OTP Code", - txtType: TxtType.heading3, - ), - mHeight(20), + "Please insert OTP Code".toText24(), + 20.height, Row( children: [ Expanded( @@ -33,7 +31,7 @@ class OtpDialog extends StatelessWidget { color: accentColor.withOpacity(0.3), ), ), - mWidth(12), + 12.width, Expanded( child: Container( width: double.infinity, @@ -41,7 +39,7 @@ class OtpDialog extends StatelessWidget { color: accentColor.withOpacity(0.3), ), ), - mWidth(12), + 12.width, Expanded( child: Container( width: double.infinity, @@ -49,7 +47,7 @@ class OtpDialog extends StatelessWidget { color: accentColor.withOpacity(0.3), ), ), - mWidth(12), + 12.width, Expanded( child: Container( width: double.infinity, @@ -59,7 +57,7 @@ class OtpDialog extends StatelessWidget { ), ], ), - mHeight(40), + 40.height, ShowFillButton( title: "Check Code", width: double.infinity, diff --git a/lib/widgets/show_fill_button.dart b/lib/widgets/show_fill_button.dart index 2c99eef..f0aa328 100644 --- a/lib/widgets/show_fill_button.dart +++ b/lib/widgets/show_fill_button.dart @@ -1,12 +1,13 @@ +import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:car_customer_app/theme/colors.dart'; -import 'package:car_customer_app/widgets/txt.dart'; + import 'package:flutter/material.dart'; class ShowFillButton extends StatelessWidget { String title; VoidCallback onPressed; Color txtColor; - double elevation, radius,width; + double elevation, radius, width; ShowFillButton({ required this.title, @@ -14,7 +15,7 @@ class ShowFillButton extends StatelessWidget { this.txtColor = Colors.white, this.elevation = 4, this.radius = 6, - this.width=88, + this.width = 88, }); @override @@ -31,11 +32,7 @@ class ShowFillButton extends StatelessWidget { ), ), onPressed: onPressed, - child: Txt( - title.toUpperCase(), - color: txtColor, - txtType: TxtType.heading1, - ), + child: title.toUpperCase().toText(fontSize: 16, isBold: true), ); } } diff --git a/lib/widgets/txt.dart b/lib/widgets/txt.dart deleted file mode 100644 index dadc28f..0000000 --- a/lib/widgets/txt.dart +++ /dev/null @@ -1,170 +0,0 @@ -// import 'package:auto_size_text/auto_size_text.dart'; -import 'package:car_customer_app/theme/colors.dart'; -import 'package:car_customer_app/utils/utils.dart'; -import 'package:flutter/material.dart'; -import 'package:sizer/sizer.dart'; - -enum TxtType { - small, - normal, - heading1, - heading2, - heading3, - appBar, -} - -class Txt extends StatelessWidget { - String text; - int? maxLines; - double? fontSize; - Color? color; - bool? bold; - bool? isUnderline; - bool? isFlatButton; - double? pedding; - TextAlign? textAlign; - FontWeight? fontWeight; - Function? onTap; - TxtType txtType; - - Txt(this.text, {this.maxLines, this.color, this.bold, this.fontSize, this.isUnderline, this.isFlatButton, this.pedding, this.textAlign, this.fontWeight, this.onTap, this.txtType = TxtType.normal}); - - @override - Widget build(BuildContext context) { - if (isFlatButton != null) - return Padding( - padding: EdgeInsets.only(right: pedding ?? 0, left: pedding ?? 0), - child: InkWell( - onTap: () { - onTap!(); - }, - customBorder: inkWellCorner(r: 4), - child: Padding( - padding: const EdgeInsets.only( - left: 14, - right: 14, - top: 6, - bottom: 6, - ), - child: getText(), - ), - ), - ); - else - return getText(); - } - - Widget getText() { - return Material( - type: MaterialType.transparency, - child: Text( - text, - maxLines: maxLines, - textAlign: textAlign, - overflow: maxLines != null ? TextOverflow.ellipsis : null, - style: TextStyle( - fontSize: fontSize ?? - (txtType == TxtType.small - ? 8.sp - : txtType == TxtType.normal - ? 10.sp - : txtType == TxtType.heading1 - ? 11.sp - : txtType == TxtType.heading2 - ? 12.sp - : txtType == TxtType.heading3 - ? 13.sp - : txtType == TxtType.appBar - ? 14.sp - : 8.sp), - color: color ?? - (txtType == TxtType.appBar - ? Colors.black - : txtType == TxtType.heading1 - ? headingColor - : txtType == TxtType.heading2 - ? headingColor - : txtType == TxtType.heading3 - ? headingColor - : null), - fontWeight: (fontWeight != null) - ? fontWeight - : ((bold != null) - ? FontWeight.bold - : (txtType == TxtType.appBar - ? FontWeight.bold - : txtType == TxtType.heading1 - ? FontWeight.bold - : txtType == TxtType.heading2 - ? FontWeight.bold - : txtType == TxtType.heading3 - ? FontWeight.bold - : null)), - decoration: (isUnderline != null) ? TextDecoration.underline : null, - ), - ), - ); - } -} - -// class TxtAuto extends StatelessWidget { -// String text; -// int? maxLines; -// double? fontSize; -// Color? color; -// bool? bold; -// bool? isUnderline; -// bool? isFlatButton; -// double? pedding; -// TextAlign? textAlign; -// -// TxtAuto( -// this.text, { -// this.maxLines, -// this.color, -// this.bold, -// this.fontSize, -// this.isUnderline, -// this.isFlatButton, -// this.pedding, -// this.textAlign, -// }); -// -// @override -// Widget build(BuildContext context) { -// if (isFlatButton != null) -// return Padding( -// padding: EdgeInsets.only(right: pedding ?? 0, left: pedding ?? 0), -// child: InkWell( -// onTap: () {}, -// customBorder: inkWellCorner(r: 4), -// child: Padding( -// padding: const EdgeInsets.only( -// left: 14, -// right: 14, -// top: 6, -// bottom: 6, -// ), -// child: getText(), -// ), -// ), -// ); -// else -// return getText(); -// } -// -// Widget getText() { -// return AutoSizeText( -// text, -// maxLines: maxLines, -// textAlign: textAlign, -// overflow: maxLines != null ? TextOverflow.ellipsis : null, -// style: TextStyle( -// fontSize: fontSize, -// color: color, -// fontWeight: (bold != null) ? FontWeight.bold : null, -// decoration: (isUnderline != null) ? TextDecoration.underline : null, -// ), -// ); -// } -// } diff --git a/lib/widgets/txt_field.dart b/lib/widgets/txt_field.dart index 9431b0b..48a99d0 100644 --- a/lib/widgets/txt_field.dart +++ b/lib/widgets/txt_field.dart @@ -1,6 +1,7 @@ +import 'package:car_customer_app/extensions/int_extensions.dart'; import 'package:car_customer_app/theme/colors.dart'; import 'package:car_customer_app/utils/utils.dart'; -import 'package:car_customer_app/widgets/txt.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:flutter/material.dart'; import 'package:sizer/sizer.dart'; @@ -97,7 +98,7 @@ class TxtField extends StatelessWidget { ), ), ), - if (isNeedFilterButton) mWidth(8), + if (isNeedFilterButton) 8.width, if (isNeedFilterButton) InkWell( onTap: isNeedClickAll @@ -133,12 +134,7 @@ class TxtField extends StatelessWidget { child: Center( child: Padding( padding: const EdgeInsets.only(left: 12, right: 12), - child: Txt( - buttonTitle ?? "Search", - color: Colors.white, - fontSize: 18, - bold: true, - ), + child: (buttonTitle ?? "Search").toText16(color: Colors.white), ), ), ), diff --git a/pubspec.lock b/pubspec.lock index 544036a..6250209 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -14,7 +14,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.1" + version: "2.8.2" boolean_selector: dependency: transitive description: @@ -28,7 +28,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: @@ -181,7 +181,7 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" meta: dependency: transitive description: @@ -424,7 +424,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.4.3" typed_data: dependency: transitive description: @@ -445,7 +445,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" win32: dependency: transitive description: