New Structure Implemented

fatima
devmirza121 4 years ago
parent 1eb4ad1db9
commit 0c5d43c04b

@ -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> = U Function(dynamic);
class APIError {
int errorCode;
String errorMessage;
APIError(this.errorCode, this.errorMessage);
Map<String, dynamic> 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<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? 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<Response> postJsonForResponse<T>(String url, T jsonObject, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? 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<Response> _postForResponse(String url, requestBody, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
try {
var _headers = <String, String>{};
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<T> _withClient<T>(Future<T> Function(Client) fn) async {
var httpClient = HttpClient()..badCertificateCallback = _certificateCheck;
var client = IOClient(httpClient);
try {
return await fn(client);
} finally {
client.close();
}
}
Future<Response> _post(url, {Map<String, String>? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding));
}

@ -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<SurahModel> getSurahs() async {
String url = "${ApiConsts.tangheemUsers}AlSuar_Get";
var postParams = {};
return await ApiClient().postJsonForObject((json) => SurahModel.fromJson(json), url, postParams);
}
Future<MemberModel> getMembers() async {
String url = "${ApiConsts.tangheemUsers}Committee_Get";
var postParams = {};
return await ApiClient().postJsonForObject((json) => MemberModel.fromJson(json), url, postParams);
}
Future<ContentInfoModel> getContentInfo(int contentId) async {
String url = "${ApiConsts.tangheemUsers}ContentInfo_Get";
var postParams = {"contentTypeId": contentId};
return await ApiClient().postJsonForObject((json) => ContentInfoModel.fromJson(json), url, postParams);
}
}

@ -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;
}
}

@ -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);
}

@ -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";
}

@ -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<dynamic> 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);
}
}
}

@ -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,
// );
}
}

@ -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<ISharedPreferences>()
.promotionNotificationsEnabled;
if (isPromotionNotificationEnabled == null) {
await Injector.appInstance
.getDependency<ISharedPreferences>()
.setPromotionNotificationEnabled(true);
Injector.appInstance
.getDependency<IFirebaseService>()
.subscribeForPromotions();
} */
} catch (_) {
//something wend wrong, set it to true
await Injector.appInstance
.getDependency<ISharedPreferences>()
.setPromotionNotificationEnabled(true);
/*Injector.appInstance
.getDependency<IFirebaseService>()
.subscribeForPromotions();*/
}
}
}

@ -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<IAcRepository>(() => AcRepository());
// injector.registerSingleton<IAcRepository>((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();
}
}

@ -1,18 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
class AppLocalizations {
static const Iterable<LocalizationsDelegate<dynamic>> localizationsDelegates =
[
// ... app-specific localization delegate[s] here
// S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate
];
static const List<Locale> supportedLocales = [
const Locale("en", "US")
];
}

@ -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<String, dynamic> toJson() => {'message': message, 'error': error, 'arguments': '$arguments'};
@override
String toString() {
return jsonEncode(this);
}
}

@ -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());
}

@ -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";
}
}
}

@ -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);
}

@ -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<void> main() async {
@ -24,10 +24,7 @@ Future<void> main() async {
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
MyApp() {
AppDependencies.addDependencies();
}
@override
Widget build(BuildContext context) {

@ -0,0 +1,65 @@
class ContentInfoModel {
int? totalItemsCount;
int? statusCode;
String? message;
List<ContentInfoDataModel>? data;
ContentInfoModel({this.totalItemsCount, this.statusCode, this.message, this.data});
ContentInfoModel.fromJson(Map<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> json) {
contentInfoId = json['contentInfoId'];
contentTypeId = json['contentTypeId'];
content = json['content'];
contentTypeNameEn = json['contentTypeNameEn'];
contentTypeNameAr = json['contentTypeNameAr'];
fileName = json['fileName'];
exposeFilePath = json['exposeFilePath'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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;
}
}

@ -0,0 +1,62 @@
class MemberModel {
int? totalItemsCount;
int? statusCode;
String? message;
List<MemberDataModel>? data;
MemberModel({this.totalItemsCount, this.statusCode, this.message, this.data});
MemberModel.fromJson(Map<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> json) {
committeeId = json['committeeId'];
firstName = json['firstName'];
lastName = json['lastName'];
description = json['description'];
picture = json['picture'];
orderNo = json['orderNo'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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;
}
}

@ -0,0 +1,74 @@
class SurahModel {
int? totalItemsCount;
int? statusCode;
String? message;
List<SurahModelData>? data;
SurahModel({this.totalItemsCount, this.statusCode, this.message, this.data});
SurahModel.fromJson(Map<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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;
}
}

@ -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);

@ -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,

@ -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,

@ -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: () {

@ -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: () {

@ -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,

@ -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,

@ -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),
],
),

@ -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));
}
}

@ -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<Account> getAccountList();
Future<BackendResponse> 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<Account> getAccountList() async {
BackendResponse response = await Injector.appInstance
.getDependency<IBackendApiService>()
.getAuthenticatedAPI(ACCOUNT_LIST);
if (response != null && response.isOk) {
return Account.fromJson(response.result);
} else {
throw Exception();
}
}
@override
Future<BackendResponse> updateAccount(String dataAsJson) async {
BackendResponse response = await Injector.appInstance
.getDependency<IBackendApiService>()
.postAuthenticatedAPI(UPDATE_LIST, dataAsJson);
if (response != null && response.isOk) {
//if parsing failed, throw exception
return response;
} else {
throw Exception();
}
}
}

@ -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<BackendResponse> getUnauthenticatedAPI(String route);
Future<BackendResponse> getAuthenticatedAPI(String route);
Future<BackendResponse> postUnauthenticatedAPI(
String route, String dataAsJson);
Future<BackendResponse> postAuthenticatedAPI(String route, String dataAsJson);
Future<BackendResponse> 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<ISecureStorage>();
final IHttpService _httpService =
Injector.appInstance.getDependency<IHttpService>();
///internal helper functions which executes the given api call
///and wraps the response
Future<BackendResponse> _callApi(Future<dynamic> 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<BackendResponse> 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<BackendResponse> getUnauthenticatedAPI(String route) async {
await checkConnection();
return _callApi(_httpService.get(_serverApiBaseUrl + route,
headers: {'Content-Type': 'application/json', 'Accept': '*/*'}));
}
@override
Future<BackendResponse> 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<BackendResponse> postUnauthenticatedAPI(
String route, String dataAsJson) async {
await checkConnection();
return _callApi(_httpService.post(_serverApiBaseUrl + route,
body: dataAsJson, headers: {'Content-Type': 'application/json'}));
}
Future<void> checkConnection() async {
if (!(await Injector.appInstance
.getDependency<INetworkService>()
.isHostAvailable(_homeUrl))) throw NetworkException();
}
@override
Future<BackendResponse> 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"
}));
}
}

@ -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<String> get token;
Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message);
Future<dynamic> messageHandler(Map<String, dynamic> message);
Future<dynamic> onLaunch(Map<String, dynamic> message);
Future<dynamic> onResume(Map<String, dynamic> 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<String> 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<dynamic> 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<String, dynamic> message) async {
await myBackgroundMessageHandler(message);
}
@override
Future messageHandler(Map<String, dynamic> 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<String, dynamic> message) async {
print("onLaunch: $message");
}
@override
Future onResume(Map<String, dynamic> message) async {
print("onResume: $message");
}
@override
Future<String> get token => _firebaseMessaging.getToken();
@override
void subscribeForPromotions() {
_firebaseMessaging.subscribeToTopic("promotions");
}
@override
void unsubscribeFromPromotions() {
_firebaseMessaging.unsubscribeFromTopic("promotions");
}
}
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> 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.
}
*/

@ -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<Response> post(url,
{Map<String, String> headers, body, Encoding encoding});
Future<Response> get(url, {Map<String, String> headers});
Future<Response> delete(url, {Map<String, String> headers});
}
class HttpService implements IHttpService {
@override
Future<Response> delete(url, {Map<String, String>? headers}) {
return http.delete(url, headers: headers);
}
@override
Future<Response> get(url, {Map<String, String>? headers}) {
return http.get(url, headers: headers);
}
@override
Future<Response> post(url,
{Map<String, String>? headers, body, Encoding? encoding}) {
return http.post(url, headers: headers, body: body, encoding: encoding);
}
}

@ -1,26 +0,0 @@
// import 'dart:io';
//
// import 'package:image_picker/image_picker.dart';
//
// abstract class IMediaService {
// Future<File?> takePicture();
//
// Future<File?> openImageFromGallery();
// }
//
// class MediaService implements IMediaService {
// @override
// Future<File?> openImageFromGallery() async {
// final pickedFile =
// await ImagePicker().getImage(source: ImageSource.gallery);
// if (pickedFile == null) return null;
// return File(pickedFile.path);
// }
//
// @override
// Future<File?> takePicture() async {
// final pickedFile = await ImagePicker().getImage(source: ImageSource.camera);
// if (pickedFile == null) return null;
// return File(pickedFile.path);
// }
// }

@ -1,25 +0,0 @@
import 'dart:io';
abstract class INetworkService {
Future<bool> isHostAvailable(String endpoint);
}
class NetworkService implements INetworkService{
@override
Future<bool> 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 {
}

@ -1,33 +0,0 @@
abstract class ISecureStorage {
Future<String> readBearerToken();
Future<void> clearUserCredentials();
}
class SecureStorage implements ISecureStorage {
///return bearer token if present, or null if not
@override
Future<String> readBearerToken() async {
try {
return "";
} catch (_) {
//an error occured returning null
return "";
}
}
///returns true if write was successful, false otherwise
@override
Future<bool> writeBearerToken(String token) async {
try {
await "";
return true;
} catch (_) {
//an error occured returning false
return false;
}
}
@override
Future<void> clearUserCredentials() async {}
}

@ -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<int?> get authState;
Future<void> setAuthState(int authState);
Future<int?> get configState;
Future<void> setConfigState(int confState);
Future<ConfigModel?> get config;
Future<void> setConfig(ConfigModel config);
Future<bool?> get promotionNotificationsEnabled;
Future<void> setPromotionNotificationEnabled(bool newSetting);
Future<bool?> get helpAlreadyShown;
Future<void> setHelpAlreadyShown();
Future<int?> get useS3;
Future<void> 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<int?> get authState async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
return sharedPrefs.getInt(_AUTH_STATE_KEY);
}
@override
Future<void> setAuthState(int authState) async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
sharedPrefs.setInt(_AUTH_STATE_KEY, authState);
}
@override
Future<ConfigModel?> get config async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
final configAsJson = sharedPrefs.getString(_CONFIG_KEY);
return ConfigModel.fromJson(jsonDecode(configAsJson!));
}
@override
Future<void> setConfig(ConfigModel config) async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
sharedPrefs.setString(_CONFIG_KEY, jsonEncode(config));
setConfigState(1);
}
@override
Future<bool?> get promotionNotificationsEnabled async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
return sharedPrefs.getBool(_PROMOTION_NOTIFICATION_KEY);
}
@override
Future<void> setPromotionNotificationEnabled(bool newSetting) async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
sharedPrefs.setBool(_PROMOTION_NOTIFICATION_KEY, newSetting);
}
@override
Future<bool?> get helpAlreadyShown async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
return sharedPrefs.getBool(_HELP_ALREADY_SHOWN);
}
@override
Future<void> setHelpAlreadyShown() async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
sharedPrefs.setBool(_HELP_ALREADY_SHOWN, true);
}
@override
Future<int?> get configState async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
return sharedPrefs.getInt(_CONFIG_STATE_KEY);
}
@override
Future<void> setConfigState(int confState) async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
sharedPrefs.setInt(_CONFIG_STATE_KEY, confState);
}
@override
Future<void> setUseS3(int value) async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
sharedPrefs.setInt(_USE_S3, value);
}
@override
Future<int?> get useS3 async {
final sharedPrefs = await SharedPrefsPlugin.SharedPreferences.getInstance();
return sharedPrefs.getInt(_USE_S3);
}
}

@ -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));

@ -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),
);
}

@ -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),
],
),
),

@ -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,

@ -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,

@ -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),
);
}
}

@ -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,
// ),
// );
// }
// }

@ -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),
),
),
),

@ -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:

Loading…
Cancel
Save