wala_plus
FaizHashmi 3 hours ago
parent 4541bfb1db
commit 858fa7edb7

@ -4,4 +4,8 @@ android.useAndroidX=true
android.enableJetifier=true
apmsInstrumentationEnabled=false
#org.gradle.java.home=/Users/amirs/Library/Java/JavaVirtualMachines/jbr-17.0.12/Contents/Home/
#org.gradle.java.home=/Users/amirs/Library/Java/JavaVirtualMachines/jbr-17.0.12/Contents/Home/
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false

@ -0,0 +1,4 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.3315 5.33146C10.5145 5.1484 10.5145 4.8516 10.3315 4.66854C10.1484 4.48549 9.8516 4.48549 9.66854 4.66854L7.50009 6.83699L5.95644 5.29352C5.77337 5.11048 5.47657 5.11049 5.29352 5.29356C5.11048 5.47663 5.11049 5.77343 5.29356 5.95648L6.83718 7.49991L6.54354 7.79354C6.36049 7.9766 6.36049 8.2734 6.54354 8.45646C6.7266 8.63951 7.0234 8.63951 7.20646 8.45646L7.50013 8.16278L7.79364 8.45625C7.97671 8.6393 8.27351 8.63928 8.45655 8.45621C8.6396 8.27314 8.63958 7.97634 8.45651 7.79329L8.16305 7.49987L10.3315 5.33146Z" fill="#047857"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.53573 1.09375H7.46427C6.09508 1.09374 5.01965 1.09374 4.18001 1.20662C3.3196 1.3223 2.63694 1.5642 2.10057 2.10057C1.5642 2.63694 1.3223 3.3196 1.20662 4.18001C1.09374 5.01965 1.09374 6.09508 1.09375 7.46427V7.53573C1.09374 8.90492 1.09374 9.98035 1.20662 10.82C1.3223 11.6804 1.5642 12.3631 2.10057 12.8994C2.63694 13.4358 3.3196 13.6777 4.18001 13.7934C5.01965 13.9063 6.09507 13.9063 7.46425 13.9062H7.53573C8.90491 13.9063 9.98035 13.9063 10.82 13.7934C11.6804 13.6777 12.3631 13.4358 12.8994 12.8994C13.4358 12.3631 13.6777 11.6804 13.7934 10.82C13.9063 9.98035 13.9063 8.90493 13.9062 7.53575V7.46427C13.9063 6.09509 13.9063 5.01965 13.7934 4.18001C13.6777 3.3196 13.4358 2.63694 12.8994 2.10057C12.3631 1.5642 11.6804 1.3223 10.82 1.20662C9.98035 1.09374 8.90492 1.09374 7.53573 1.09375ZM2.76348 2.76348C3.09664 2.43033 3.54848 2.23746 4.30493 2.13576C5.07487 2.03225 6.08727 2.03125 7.5 2.03125C8.91273 2.03125 9.92513 2.03225 10.6951 2.13576C11.4515 2.23746 11.9034 2.43033 12.2365 2.76348C12.5697 3.09664 12.7625 3.54848 12.8642 4.30493C12.9678 5.07487 12.9688 6.08727 12.9688 7.5C12.9688 8.91273 12.9678 9.92513 12.8642 10.6951C12.7625 11.4515 12.5697 11.9034 12.2365 12.2365C11.9034 12.5697 11.4515 12.7625 10.6951 12.8642C9.92513 12.9678 8.91273 12.9688 7.5 12.9688C6.08727 12.9688 5.07487 12.9678 4.30493 12.8642C3.54848 12.7625 3.09664 12.5697 2.76348 12.2365C2.43033 11.9034 2.23746 11.4515 2.13576 10.6951C2.03225 9.92513 2.03125 8.91273 2.03125 7.5C2.03125 6.08727 2.03225 5.07487 2.13576 4.30493C2.23746 3.54848 2.43033 3.09664 2.76348 2.76348Z" fill="#047857"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@ -0,0 +1,5 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 9.1875C7.656 9.1875 6.5625 8.094 6.5625 6.75C6.5625 5.406 7.656 4.3125 9 4.3125C10.344 4.3125 11.4375 5.406 11.4375 6.75C11.4375 8.094 10.344 9.1875 9 9.1875ZM9 5.4375C8.27625 5.4375 7.6875 6.02625 7.6875 6.75C7.6875 7.47375 8.27625 8.0625 9 8.0625C9.72375 8.0625 10.3125 7.47375 10.3125 6.75C10.3125 6.02625 9.72375 5.4375 9 5.4375Z" fill="#737373"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.66722 13.5263C8.02722 13.872 8.50047 14.0625 8.99997 14.0625C9.49947 14.0625 9.97272 13.872 10.3327 13.5255C10.5082 13.3568 10.6882 13.1858 10.8705 13.0133C13.1174 10.8818 15.9149 8.22811 14.3692 4.51199C13.4805 2.37374 11.322 0.9375 8.99997 0.9375C6.67797 0.9375 4.52021 2.37374 3.63146 4.51199C2.09096 8.21474 4.86521 10.8555 7.09421 12.9773L7.11578 12.9978C7.30192 13.1753 7.48597 13.3508 7.66722 13.5263ZM4.67022 4.94399C5.38647 3.22049 7.12647 2.0625 8.99997 2.0625C10.8735 2.0625 12.6142 3.22049 13.3312 4.94399C14.5792 7.94549 12.3007 10.107 10.0965 12.1972C10.0547 12.237 10.0129 12.2766 9.97134 12.3162C9.83004 12.4504 9.69004 12.5834 9.55273 12.7155C9.40348 12.8588 9.20697 12.9375 8.99997 12.9375C8.79297 12.9375 8.59646 12.858 8.44871 12.7163C8.25971 12.5333 8.06623 12.3487 7.86973 12.162C5.68581 10.0831 3.42677 7.93263 4.67022 4.94399Z" fill="#737373"/>
<path d="M11.0385 17.0625H6.96142C4.53817 17.0625 3.32169 17.0625 2.72319 16.1745C2.66544 16.0882 2.61517 15.999 2.57392 15.909C2.11666 14.93 2.85295 13.8806 3.87139 12.429L3.87295 12.4267C4.05145 12.1725 4.40243 12.111 4.65668 12.2895C4.91093 12.468 4.97243 12.819 4.79393 13.0733C3.98468 14.2268 3.42443 15.072 3.59543 15.4373C3.61343 15.4763 3.63367 15.5115 3.65692 15.5468C3.92017 15.9375 5.12991 15.9375 6.96138 15.9375H11.0385C12.8699 15.9375 14.0797 15.9375 14.3437 15.546C14.3669 15.5115 14.3872 15.4762 14.4029 15.441C14.5754 15.072 14.0152 14.2268 13.2059 13.0733C13.0274 12.819 13.0889 12.468 13.3432 12.2895C13.5974 12.111 13.9484 12.1725 14.1269 12.4267C15.1462 13.8795 15.8827 14.9295 15.4244 15.9127C15.3847 15.999 15.3352 16.0882 15.2775 16.1737C14.6782 17.0625 13.4617 17.0625 11.0385 17.0625Z" fill="#737373"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@ -0,0 +1,6 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.8848 0.782465C11.6672 0.777969 11.077 0.780422 10.3952 0.783256L10.074 0.784571C9.25489 0.787826 8.36176 0.790261 7.8034 0.782363L3.41832 0.782363C3.30775 0.782363 3.09409 0.784794 2.86663 0.826585C2.65209 0.866 2.34887 0.953285 2.12257 1.17828C2.01295 1.28728 1.92531 1.4256 1.85771 1.5488C1.78696 1.67774 1.72248 1.81951 1.66613 1.95532C1.55744 2.2173 1.46792 2.48443 1.41557 2.64068L1.41079 2.65493L0.986568 3.88476C0.919741 4.06317 0.849387 4.33704 0.811103 4.61007C0.791433 4.75035 0.778628 4.90141 0.781624 5.04747C0.784495 5.18744 0.802226 5.35457 0.864472 5.50929C0.963954 5.75657 1.18158 6.01838 1.36007 6.20866C1.36856 6.21771 1.3771 6.22675 1.38569 6.23576C1.38552 6.24088 1.38544 6.24602 1.38544 6.25118L1.38544 9.41047C1.38543 10.2652 1.38541 10.9542 1.45827 11.496C1.5339 12.0586 1.69571 12.5322 2.0719 12.9084C2.4481 13.2846 2.92177 13.4465 3.48434 13.5221C4.0262 13.595 4.71515 13.5949 5.5699 13.5949L7.47919 13.5949C7.73807 13.5949 7.94794 13.3851 7.94794 13.1262C7.94794 12.8673 7.73807 12.6574 7.47919 12.6574L5.60419 12.6574C4.70705 12.6574 4.08136 12.6564 3.60926 12.593C3.15066 12.5313 2.9078 12.4185 2.73482 12.2455C2.56184 12.0726 2.44906 11.8297 2.38741 11.3711C2.32393 10.899 2.32294 10.2733 2.32294 9.37618L2.32294 6.97328C2.45051 7.03849 2.59529 7.10093 2.75359 7.15501C3.17457 7.29882 3.7203 7.39381 4.3406 7.31265C4.89853 7.23967 5.351 7.00851 5.70918 6.71013C6.09419 7.00458 6.70331 7.30587 7.47811 7.31657C8.04917 7.32446 8.56216 7.12979 8.95868 6.90312C9.08184 6.83271 9.19674 6.75753 9.30188 6.68132C9.77763 7.08237 10.6727 7.56818 11.9991 7.20432C13.5774 6.77137 14.083 5.75144 14.209 5.1425C14.2154 5.11127 14.2187 5.07946 14.2187 5.04757C14.2187 4.75732 14.1289 4.33991 13.9659 3.80861C13.7986 3.26346 13.5405 2.55589 13.1738 1.66657C13.1701 1.65753 13.166 1.6486 13.1618 1.63981C13.0956 1.50407 12.9647 1.3046 12.7653 1.13192C12.5616 0.95548 12.2655 0.790329 11.8848 0.782465ZM7.49106 6.37916C6.97962 6.3721 6.58006 6.18008 6.33319 6.00595C6.55391 5.67199 6.6951 5.33553 6.76663 5.07693C6.83564 4.82742 6.68931 4.5692 6.4398 4.50019C6.19028 4.43117 5.93206 4.5775 5.86305 4.82702C5.70947 5.3823 5.16544 6.25926 4.21899 6.38308C3.76402 6.4426 3.36434 6.37295 3.05665 6.26784C2.73842 6.15914 2.54601 6.02235 2.50231 5.98113C2.48528 5.96506 2.46707 5.9503 2.44784 5.93696C2.37021 5.88311 2.20722 5.74146 2.04383 5.56728C1.87113 5.38316 1.76292 5.23071 1.73421 5.15935C1.73421 5.15935 1.73024 5.14811 1.72656 5.12505C1.72269 5.10085 1.71976 5.0687 1.71893 5.02824C1.71725 4.94644 1.72447 4.84757 1.73952 4.74025C1.77015 4.52178 1.82659 4.31346 1.86579 4.21019C1.86748 4.20572 1.86911 4.20123 1.87067 4.19671L2.29773 2.95872L2.30261 2.94414C2.3555 2.78638 2.43617 2.5457 2.53206 2.3146C2.58103 2.19657 2.63099 2.0884 2.67962 1.99977C2.73141 1.90538 2.7681 1.85849 2.78357 1.8431C2.80747 1.81934 2.88262 1.77684 3.03603 1.74865C3.17652 1.72284 3.32038 1.71986 3.41832 1.71986L7.79347 1.71986C8.36231 1.72785 9.26287 1.7253 10.0778 1.72206L10.3974 1.72076C11.0847 1.71792 11.6606 1.71553 11.8655 1.71977C11.9719 1.72196 12.0657 1.76626 12.1515 1.84057C12.2347 1.91263 12.2907 1.99706 12.314 2.0407C12.6704 2.90597 12.9148 3.57905 13.0696 4.08359C13.214 4.55415 13.2701 4.84632 13.2797 5.00173C13.1969 5.33137 12.8878 5.98842 11.7511 6.30022C10.8759 6.54033 10.2955 6.26948 9.96995 6.01784C10.0887 5.82356 10.2297 5.52285 10.3667 5.09485C10.4456 4.84828 10.3097 4.58443 10.0631 4.50553C9.81653 4.42662 9.55268 4.56254 9.47378 4.8091C9.30754 5.32855 9.16081 5.54992 9.1304 5.58829C9.02102 5.71208 8.79354 5.91764 8.4934 6.08922C8.18993 6.2627 7.84298 6.38402 7.49106 6.37916Z" fill="#C2410C"/>
<path d="M3.88544 10.6262C3.88544 10.3673 4.0953 10.1574 4.35419 10.1574L6.85419 10.1574C7.11307 10.1574 7.32294 10.3673 7.32294 10.6262C7.32294 10.8851 7.11307 11.0949 6.85419 11.0949L4.35419 11.0949C4.0953 11.0949 3.88544 10.8851 3.88544 10.6262Z" fill="#C2410C"/>
<path d="M10.9167 10.6262C10.9167 10.281 11.1965 10.0012 11.5417 10.0012L11.5473 10.0012C11.8925 10.0012 12.1723 10.281 12.1723 10.6262C12.1723 10.9714 11.8925 11.2512 11.5473 11.2512L11.5417 11.2512C11.1965 11.2512 10.9167 10.9714 10.9167 10.6262Z" fill="#C2410C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5624 7.96748C10.1037 7.96748 8.90619 9.13055 8.90619 10.5835C8.90619 11.4113 9.32257 12.0297 9.75433 12.5247C9.9082 12.7011 10.0773 12.876 10.2353 13.0394C10.2951 13.1013 10.3536 13.1618 10.4088 13.2199C10.619 13.4408 10.7995 13.6441 10.9391 13.8516C11.0558 14.0251 11.2645 14.2195 11.5661 14.2195C11.8728 14.2195 12.0808 14.0193 12.1939 13.8391C12.3264 13.6278 12.5016 13.425 12.7082 13.2072C12.7757 13.1361 12.85 13.0599 12.9271 12.981C13.0706 12.8339 13.2237 12.677 13.3595 12.525C13.7946 12.038 14.2187 11.4281 14.2187 10.5835C14.2187 9.13055 13.0212 7.96748 11.5624 7.96748ZM9.84369 10.5835C9.84369 9.66465 10.605 8.90498 11.5624 8.90498C12.5199 8.90498 13.2812 9.66465 13.2812 10.5835C13.2812 11.0803 13.0441 11.4709 12.6604 11.9004C12.5358 12.0398 12.4117 12.1667 12.28 12.3015L12.2796 12.302C12.1992 12.3842 12.1159 12.4694 12.028 12.562C11.869 12.7297 11.7058 12.9111 11.5583 13.1097C11.4095 12.9183 11.2464 12.7402 11.0881 12.5738C11.0212 12.5034 10.956 12.436 10.8923 12.3701C10.7408 12.2134 10.5979 12.0656 10.4608 11.9084C10.0786 11.4703 9.84369 11.0692 9.84369 10.5835Z" fill="#C2410C"/>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

@ -711,6 +711,7 @@
"riyadh": "الرياض",
"noInstructionsAvailable": "لا توجد طريقة استخدام محددة.",
"contactInformation": "معلومات التواصل:",
"contactInfo": "معلومات التواصل",
"humanResources": "الموارد البشرية",
"drSulaimanAlHabib": "سليمان الحبيب",
"allCategories": "الكل",

@ -711,6 +711,7 @@
"riyadh": "Riyadh",
"noInstructionsAvailable": "No instructions available.",
"contactInformation": "Contact Information:",
"contactInfo": "Contact Information",
"humanResources": "Human Resources",
"drSulaimanAlHabib": "DR SULAIMAN AL HABIB",
"allCategories": "All",

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/cupertino.dart';
@ -86,15 +87,14 @@ class ApiClient {
_headers.addAll(headers);
}
if (!kReleaseMode) {
print("Url:$url");
log("Url: $url");
var bodyJson = json.encode(jsonObject);
print("body:$bodyJson" );
log("body:$bodyJson");
}
var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes, isFormData: isFormData);
try {
if (!kReleaseMode) {
logger.i("Url: " + url);
logger.i("res: " + response.body);
log("res: " + response.body);
}
var jsonData = jsonDecode(response.body);
@ -112,7 +112,7 @@ class ApiClient {
} else if (jsonData["MessageStatus"] == 2 && jsonData["IsOTPMaxLimitExceed"] == true) {
await Utils.performLogout(AppRoutes.navigatorKey.currentContext, null);
throw const APIException(APIException.UNAUTHORIZED, error: null);
} else {
} else {
APIError? apiError;
apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorEndUserMessage'], jsonData['ErrorType'] ?? 0, jsonData['ErrorStatusCode']);
throw APIException(APIException.BAD_REQUEST, error: apiError);

@ -1,15 +1,15 @@
import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
class ApiConsts {
// static String baseUrl = "http://10.201.214.101:2027"; // Local server
// static String baseUrl = "http://10.201.214.101:2027"; // Local server
// static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server
// static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver
// static String baseUrl = "http://10.201.204.101:2024";
// static String baseUrl = "https://webservices.hmg.com"; // PreProd
// static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver
// static String baseUrl = "http://10.201.204.101:2024";
// static String baseUrl = "https://webservices.hmg.com"; // PreProd
// static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrl = "https://mohemm.hmg.com"; // New Live server
// static String baseUrl = "https://mohemm.hmg.com"; // New Live server
static String ssoBaseUrl = "https://sso.hmg.com"; // New Live server
//
// static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver
@ -21,8 +21,8 @@ class ApiConsts {
// static String baseUrl = "http://10.20.200.111:1010/";
// static String baseUrl = "https://webservices.hmg.com"; // PreProd
// static String baseUrl = "https://mohemm.hmg.com";
// static String baseUrl = "https://webservices.hmg.com"; // PreProd
// static String baseUrl = "https://mohemm.hmg.com";
// static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server
@ -48,7 +48,6 @@ class ApiConsts {
static String ssoAuthRedirection = ssoBaseUrl + "/api/auth/connect";
//Chat
static String chatServerBaseUrl = "https://apiderichat.hmg.com/";
static String chatServerBaseApiUrl = chatServerBaseUrl + "api/";
@ -99,11 +98,15 @@ class ApiConsts {
static String notificationCenterForgotPasswordServiceGUID = "5CCCC2C9-EEA0-4207-9BE9-EE1FBBFFE8D0";
static MemberType selectedMemberType = MemberType.employee;
static bool get ISDependetLogin => selectedMemberType == MemberType.dependent;
static set ISDependetLogin(bool value) {
selectedMemberType = value ? MemberType.dependent : MemberType.employee;
}
static bool get isDependetLogin => ISDependetLogin;
static set isDependetLogin(bool value) => ISDependetLogin = value;
}
@ -112,9 +115,11 @@ enum MemberType {
dependent(2);
final int value;
const MemberType(this.value);
bool get isEmployee => this == MemberType.employee;
bool get isDependent => this == MemberType.dependent;
static MemberType fromValue(int? value) {
@ -136,7 +141,3 @@ class SharedPrefsConsts {
static String mohemmWifiPassword = "mohemmWifiPassword";
static String editItemForSale = "editItemForSale";
}

@ -63,63 +63,58 @@ extension EmailValidator on String {
Widget get toWidget => Text(this);
Widget toText10({Color? color, bool isBold = false, int? maxlines, FontStyle? fontStyle}) => Text(
this,
maxLines: maxlines,
style: TextStyle(fontSize: 10, fontStyle: fontStyle ?? FontStyle.normal, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4),
);
this,
maxLines: maxlines,
style: TextStyle(fontSize: 10, fontStyle: fontStyle ?? FontStyle.normal, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4),
);
Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0, TextOverflow? overflow}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: (maxLine > 0) ? maxLine : null,
overflow: overflow,
style: TextStyle(
fontSize: 11,
fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600),
color: color ?? MyColors.darkTextColor,
letterSpacing: -0.33,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
Widget toText12({Color? color, bool isUnderLine = false, Color? underlineColor, double underlineGap = 2, bool isBold = false, bool isCenter = false, int? maxLine, TextOverflow? overflow}) {
Widget text = Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: maxLine == 0 ? null : maxLine,
style: TextStyle(fontSize: 12, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.72, overflow: TextOverflow.visible),
);
Widget toText11({Color? color, FontWeight? weight, 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: 11,
fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600),
color: color ?? MyColors.darkTextColor,
letterSpacing: -0.33,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
if (!isUnderLine) return text;
Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int? maxLine, TextOverflow? overflow}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: maxLine == 0 ? null : maxLine,
style: TextStyle(
fontSize: 12,
fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
color: color ?? MyColors.darkTextColor,
letterSpacing: -0.72,
decoration: isUnderLine ? TextDecoration.underline : null,
overflow: TextOverflow.visible
),
);
Widget toText12Auto({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int? maxLine,TextOverflow? overflow}) => AutoSizeText(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: maxLine == 0 ? null : maxLine,
minFontSize: 8,
style: TextStyle(
fontSize: 12,
fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
color: color ?? MyColors.darkTextColor,
overflow: overflow,
letterSpacing: -0.72,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
return Container(
padding: EdgeInsets.only(bottom: underlineGap),
decoration: BoxDecoration(border: Border(bottom: BorderSide(color: underlineColor ?? color ?? MyColors.darkTextColor, width: 1))),
child: text,
);
}
Widget toTextAuto({
Color? color,
bool isUnderLine = false,
bool isBold = false,
bool isCenter = false,
int maxLine = 0,
double fontSize = 12,
double letterSpacing = -0.72,
double height = 1,
}) =>
Widget toText12Auto({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int? maxLine, TextOverflow? overflow}) => AutoSizeText(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: maxLine == 0 ? null : maxLine,
minFontSize: 8,
style: TextStyle(
fontSize: 12,
fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
color: color ?? MyColors.darkTextColor,
overflow: overflow,
letterSpacing: -0.72,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
Widget toTextAuto({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0, double fontSize = 12, double letterSpacing = -0.72, double height = 1}) =>
AutoSizeText(
this,
textAlign: isCenter ? TextAlign.center : null,
@ -135,101 +130,102 @@ extension EmailValidator on String {
);
Widget toText13({Color? color, bool isUnderLine = false, bool isBold = false, int? maxlines, TextOverflow? overflow}) => Text(
this,
maxLines: maxlines,
overflow: overflow,
style: TextStyle(fontSize: 13, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null),
);
Widget toText14({Color? color, bool isUnderLine = false, bool isBold = false, FontWeight? weight, int? maxlines, TextAlign? textAlign, bool isCenter = false}) => Text(
this,
textAlign: isCenter ? TextAlign.center : textAlign,
maxLines: maxlines,
style: TextStyle(
color: color ?? MyColors.darkTextColor,
fontSize: 14,
letterSpacing: -0.48,
fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600),
decoration: isUnderLine ? TextDecoration.underline : null),
);
this,
maxLines: maxlines,
overflow: overflow,
style: TextStyle(
fontSize: 13,
fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
color: color ?? MyColors.darkTextColor,
letterSpacing: -0.52,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
Widget toText14({Color? color, bool isUnderLine = false, bool isBold = false, FontWeight? weight, int? maxlines, TextAlign? textAlign, bool isCenter = false, TextOverflow? overflow}) => Text(
this,
textAlign: isCenter ? TextAlign.center : textAlign,
maxLines: maxlines,
style: TextStyle(
overflow: overflow,
color: color ?? MyColors.darkTextColor,
fontSize: 14,
letterSpacing: -0.48,
fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600),
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
Widget toText16({Color? color, bool isUnderLine = false, bool isBold = false, int? maxlines, double? height, bool isCentered = false}) => Text(
this,
maxLines: maxlines,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(
color: color ?? MyColors.darkTextColor,
fontSize: 16,
letterSpacing: -0.64,
height: height,
fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
this,
maxLines: maxlines,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(
color: color ?? MyColors.darkTextColor,
fontSize: 16,
letterSpacing: -0.64,
height: height,
fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
Widget toText17({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 17, letterSpacing: -0.68, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 17, letterSpacing: -0.68, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText18({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(fontSize: 18, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -1.08),
);
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(fontSize: 18, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -1.08),
);
Widget toText19({Color? color, bool isBold = false}) => Text(
this,
style: TextStyle(fontSize: 19, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -1.14),
);
Widget toText19({Color? color, bool isBold = false}) =>
Text(this, style: TextStyle(fontSize: 19, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -1.14));
Widget toText20({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(fontSize: 20, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4),
);
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(fontSize: 20, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4),
);
Widget toText21({Color? color, bool isBold = false, FontWeight? weight, int? maxlines}) => Text(
this,
maxLines: maxlines,
style: TextStyle(color: color ?? MyColors.grey3AColor, fontSize: 21, letterSpacing: -0.84, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600)),
);
Widget toText21({Color? color, bool isBold = false, FontWeight? weight, int? maxlines}) =>
Text(this, maxLines: maxlines, style: TextStyle(color: color ?? MyColors.grey3AColor, fontSize: 21, letterSpacing: -0.84, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600)));
Widget toText22({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText23({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 23, letterSpacing: -0.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 23, letterSpacing: -0.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText24({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText30({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 20 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.2, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 20 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.2, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText32({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText44({Color? color, bool isBold = false}) => Text(
this,
style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 44, letterSpacing: -2.64, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText44({Color? color, bool isBold = false}) =>
Text(this, style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 44, letterSpacing: -2.64, fontWeight: isBold ? FontWeight.bold : FontWeight.w600));
Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) {
String upper = "";
@ -253,14 +249,7 @@ extension EmailValidator on String {
lower = lowerHeading;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (upper.isNotEmpty) upper.toText12(),
lower.toText24(isBold: true),
],
);
return Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [if (upper.isNotEmpty) upper.toText12(), lower.toText24(isBold: true)]);
}
bool isValidEmail() {

@ -727,6 +727,7 @@ class CodegenLoader extends AssetLoader{
"riyadh": "الرياض",
"noInstructionsAvailable": "لا توجد طريقة استخدام محددة.",
"contactInformation": "معلومات التواصل:",
"contactInfo": "معلومات التواصل",
"humanResources": "الموارد البشرية",
"drSulaimanAlHabib": "سليمان الحبيب",
"allCategories": "الكل",
@ -1509,6 +1510,7 @@ static const Map<String,dynamic> _en_US = {
"riyadh": "Riyadh",
"noInstructionsAvailable": "No instructions available.",
"contactInformation": "Contact Information:",
"contactInfo": "Contact Information",
"humanResources": "Human Resources",
"drSulaimanAlHabib": "DR SULAIMAN AL HABIB",
"allCategories": "All",

@ -699,6 +699,7 @@ abstract class LocaleKeys {
static const riyadh = 'riyadh';
static const noInstructionsAvailable = 'noInstructionsAvailable';
static const contactInformation = 'contactInformation';
static const contactInfo = 'contactInfo';
static const humanResources = 'humanResources';
static const drSulaimanAlHabib = 'drSulaimanAlHabib';
static const allCategories = 'allCategories';

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mohem_flutter_app/classes/colors.dart';

@ -290,9 +290,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
});
},
),
Image
.asset("assets/images/logos/main_mohemm_logo.png", width: 134, height: 28)
.expanded,
Image.asset("assets/images/logos/main_mohemm_logo.png", width: 134, height: 28).expanded,
SvgPicture.asset("assets/images/announcements.svg", matchTextDirection: true).onPress(() async {
await Navigator.pushNamed(context, AppRoutes.announcements);
}),
@ -324,103 +322,103 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
child: Consumer<DashboardProviderModel>(
builder: (BuildContext context, DashboardProviderModel model, Widget? child) {
return (model.isAttendanceTrackingLoading
? GetAttendanceTrackingShimmer()
: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: const LinearGradient(
transform: GradientRotation(.46),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [MyColors.gradiantEndColor, MyColors.gradiantStartColor],
),
),
child: Stack(
alignment: Alignment.center,
children: [
if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true),
if (model.isTimeRemainingInSeconds == 0) DateTime.now().toString().split(" ")[0].toText12(color: Colors.white),
if (model.isTimeRemainingInSeconds != 0)
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
? GetAttendanceTrackingShimmer()
: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: const LinearGradient(
transform: GradientRotation(.46),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [MyColors.gradiantEndColor, MyColors.gradiantStartColor],
),
),
child: Stack(
alignment: Alignment.center,
children: [
if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true),
if (model.isTimeRemainingInSeconds == 0) DateTime.now().toString().split(" ")[0].toText12(color: Colors.white),
if (model.isTimeRemainingInSeconds != 0)
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
9.height,
Directionality(
textDirection: ui.TextDirection.ltr,
child: CountdownTimer(
endTime: model.endTime,
onEnd: null,
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true),
textStyle: const TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold),
),
),
LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white),
9.height,
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(20)),
child: LinearProgressIndicator(
value: model.progress,
minHeight: 8,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
backgroundColor: const Color(0xff196D73),
),
),
],
),
],
).paddingOnly(top: 12, right: 15, left: 12),
),
Row(
children: [
9.height,
Directionality(
textDirection: ui.TextDirection.ltr,
child: CountdownTimer(
endTime: model.endTime,
onEnd: null,
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true),
textStyle: const TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold),
),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.checkIn.tr().toText12(color: Colors.white),
(model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn).toString().toText14(
color: Colors.white,
isBold: true,
),
4.height,
],
).paddingOnly(left: 12, right: 12),
),
LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white),
9.height,
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(20)),
child: LinearProgressIndicator(
value: model.progress,
minHeight: 8,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
backgroundColor: const Color(0xff196D73),
Container(
margin: EdgeInsets.only(top: AppState().isArabic(context) ? 6 : 0),
width: 45,
height: 45,
padding: const EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
color: const Color(0xff259EA4),
borderRadius: BorderRadius.only(
bottomRight: AppState().isArabic(context) ? const Radius.circular(0) : const Radius.circular(15),
bottomLeft: AppState().isArabic(context) ? const Radius.circular(15) : const Radius.circular(0),
),
),
),
child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/biometrics.svg" : "assets/images/biometrics.svg"),
).onPress(() {
showMyBottomSheet(context, callBackFunc: () {}, child: MarkAttendanceWidget(model, isFromDashboard: true));
}),
],
),
],
).paddingOnly(top: 12, right: 15, left: 12),
),
Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.checkIn.tr().toText12(color: Colors.white),
(model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn).toString().toText14(
color: Colors.white,
isBold: true,
),
4.height,
],
).paddingOnly(left: 12, right: 12),
],
),
Container(
margin: EdgeInsets.only(top: AppState().isArabic(context) ? 6 : 0),
width: 45,
height: 45,
padding: const EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
color: const Color(0xff259EA4),
borderRadius: BorderRadius.only(
bottomRight: AppState().isArabic(context) ? const Radius.circular(0) : const Radius.circular(15),
bottomLeft: AppState().isArabic(context) ? const Radius.circular(15) : const Radius.circular(0),
),
),
child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/biometrics.svg" : "assets/images/biometrics.svg"),
).onPress(() {
showMyBottomSheet(context, callBackFunc: () {}, child: MarkAttendanceWidget(model, isFromDashboard: true));
}),
],
),
],
),
],
),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.todayAttendance);
}))
).onPress(() {
Navigator.pushNamed(context, AppRoutes.todayAttendance);
}))
.animatedSwither();
},
),
@ -455,7 +453,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
},
).paddingOnly(bottom: 18, left: 24, right: 24),
// eventActivityWidget(context),
if (isDisplayMazaya) ...[
if (isDisplayMazaya) ...<Widget>[
InkWell(
borderRadius: BorderRadius.circular(20),
onTap: () {
@ -466,9 +464,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
child: AspectRatio(
aspectRatio: 386 / 121.37,
child: SvgPicture.asset(
AppState().isArabic(context)
? "assets/images/mazaya_banner_ar.svg"
: "assets/images/mazaya_banner_en.svg",
AppState().isArabic(context) ? "assets/images/mazaya_banner_ar.svg" : "assets/images/mazaya_banner_en.svg",
width: double.infinity,
fit: BoxFit.fill,
),
@ -570,7 +566,6 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
],
),
*/
Container(
width: double.infinity,
padding: const EdgeInsets.only(top: 31),
@ -583,9 +578,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
mainAxisSize: MainAxisSize.min,
children: [
ServicesWidget(),
context
.watch<MarathonProvider>()
.isLoading ? const MarathonBannerShimmer().paddingAll(20) : const MarathonBanner().paddingOnly(left: 21, right: 21, bottom: 8, top: 8),
context.watch<MarathonProvider>().isLoading ? const MarathonBannerShimmer().paddingAll(20) : const MarathonBanner().paddingOnly(left: 21, right: 21, bottom: 8, top: 8),
// context.watch<MarathonProvider>().isTutorialLoading
// ? const MarathonBannerShimmer().paddingAll(20)
// : Container(
@ -689,28 +682,28 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
SvgPicture.asset(
"assets/icons/chat/chat.svg",
color:
!checkIfPrivilegedForChat()
? MyColors.lightGreyE3Color
: currentIndex == 4
? MyColors.grey3AColor
: cProvider.disbaleChatForThisUser
? MyColors.lightGreyE3Color
: MyColors.grey98Color,
!checkIfPrivilegedForChat()
? MyColors.lightGreyE3Color
: currentIndex == 4
? MyColors.grey3AColor
: cProvider.disbaleChatForThisUser
? MyColors.lightGreyE3Color
: MyColors.grey98Color,
).paddingAll(4),
Consumer<ChatProviderModel>(
builder: (BuildContext cxt, ChatProviderModel data, Widget? child) {
return !checkIfPrivilegedForChat()
? const SizedBox()
: Positioned(
right: 0,
top: 0,
child: Container(
padding: const EdgeInsets.only(left: 4, right: 4),
alignment: Alignment.center,
decoration: BoxDecoration(color: cProvider.disbaleChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)),
child: data.chatUConvCounter.toString().toText10(color: Colors.white),
),
);
right: 0,
top: 0,
child: Container(
padding: const EdgeInsets.only(left: 4, right: 4),
alignment: Alignment.center,
decoration: BoxDecoration(color: cProvider.disbaleChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)),
child: data.chatUConvCounter.toString().toText10(color: Colors.white),
),
);
},
),
],
@ -746,16 +739,9 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
}
Widget eventActivityWidget(BuildContext context) {
return (context
.watch<DashboardProviderModel>()
.isEventLoadingLoading)
return (context.watch<DashboardProviderModel>().isEventLoadingLoading)
? const MarathonBannerShimmer().paddingOnly(left: 21, right: 21, bottom: 21, top: 0)
: (context
.watch<DashboardProviderModel>()
.eventActivity != null && context
.watch<DashboardProviderModel>()
.eventActivity!
.isActive == true)
: (context.watch<DashboardProviderModel>().eventActivity != null && context.watch<DashboardProviderModel>().eventActivity!.isActive == true)
? const EventActivityBanner().paddingOnly(left: 21, right: 21, bottom: 21, top: 0)
: const SizedBox();
}

@ -14,6 +14,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_category_model.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_retailer_model.dart';
import 'package:mohem_flutter_app/widgets/info_chip_widget.dart';
import 'package:shimmer/shimmer.dart';
class DashboardScreenForDependet extends StatefulWidget {
@ -105,17 +106,14 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
String dob = AppState().dependentDob ?? "";
String name = AppState().dependentName ?? "";
String mobile = AppState().postParamsObject?.mobileNumber ?? "";
String tokenID = (AppState().postParamsObject?.tokenID != null && AppState().postParamsObject!.tokenID!.isNotEmpty)
? AppState().postParamsObject!.tokenID!
: (AppState().authenticationTokenID ?? "");
String tokenID =
(AppState().postParamsObject?.tokenID != null && AppState().postParamsObject!.tokenID!.isNotEmpty) ? AppState().postParamsObject!.tokenID! : (AppState().authenticationTokenID ?? "");
if (tokenID.isEmpty) {
tokenID = await Utils.getStringFromPrefs("P_DEP_TOKEN_ID");
}
int sessionId = AppState().postParamsObject?.pSessionId ?? 0;
String email = AppState().postParamsObject?.pEmailAddress ?? "";
String deviceToken = AppState().getIsHuawei
? AppState().getHuaweiPushToken
: (AppState().getDeviceToken ?? "");
String deviceToken = AppState().getIsHuawei ? AppState().getHuaweiPushToken : (AppState().getDeviceToken ?? "");
await LoginApiClient().insertMobileLoginInfoDependent(
loginType: loginType,
@ -178,10 +176,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
List<WalaPlusCategoryModel> fullList = [];
bool hasAll = list.any((c) => (c.id == "all" || c.name?.toLowerCase() == "all" || c.name == "الجميع" || c.name == "الكل"));
if (!hasAll) {
fullList.add(WalaPlusCategoryModel(
id: "all",
name: LocaleKeys.allCategories.tr(),
));
fullList.add(WalaPlusCategoryModel(id: "all", name: LocaleKeys.allCategories.tr()));
}
fullList.addAll(list);
@ -201,10 +196,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
List<WalaPlusCategoryModel> fullList = [];
bool hasAll = retryList.any((c) => (c.id == "all" || c.name?.toLowerCase() == "all" || c.name == "الجميع" || c.name == "الكل"));
if (!hasAll) {
fullList.add(WalaPlusCategoryModel(
id: "all",
name: LocaleKeys.allCategories.tr(),
));
fullList.add(WalaPlusCategoryModel(id: "all", name: LocaleKeys.allCategories.tr()));
}
fullList.addAll(retryList);
setState(() {
@ -221,9 +213,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
if (mounted && categoriesList.isEmpty) {
setState(() {
categoriesList = [
WalaPlusCategoryModel(id: "all", name: LocaleKeys.allCategories.tr()),
];
categoriesList = [WalaPlusCategoryModel(id: "all", name: LocaleKeys.allCategories.tr())];
if (currentCategoryId.isEmpty) {
currentCategoryId = "all";
}
@ -322,10 +312,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
}
Future<void> _onRefresh() async {
await Future.wait([
fetchCategories(),
fetchOffers(categoryId: currentCategoryId.isEmpty ? "all" : currentCategoryId),
]);
await Future.wait([fetchCategories(), fetchOffers(categoryId: currentCategoryId.isEmpty ? "all" : currentCategoryId)]);
}
void _runFilter([String? query]) {
@ -335,40 +322,36 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
List<WalaPlusRetailerModel> temp = retailersList;
if (selectedTypeFilter != "all" && selectedTypeFilter.isNotEmpty) {
temp = temp.where((WalaPlusRetailerModel item) {
String? norm = item.normalizedType;
if (selectedTypeFilter == "online") {
return norm == "online";
} else if (selectedTypeFilter == "instore") {
return norm == "instore";
} else {
return norm == selectedTypeFilter || (item.type?.trim().toLowerCase() == selectedTypeFilter);
}
}).toList();
temp =
temp.where((WalaPlusRetailerModel item) {
String? norm = item.normalizedType;
if (selectedTypeFilter == "online") {
return norm == "online";
} else if (selectedTypeFilter == "instore") {
return norm == "instore";
} else {
return norm == selectedTypeFilter || (item.type?.trim().toLowerCase() == selectedTypeFilter);
}
}).toList();
}
if (searchQuery.trim().isNotEmpty) {
String q = searchQuery.trim().toLowerCase();
temp = temp.where((WalaPlusRetailerModel item) {
String name = (item.name ?? "").toLowerCase();
String title = (item.offerTitle ?? "").toLowerCase();
String desc = (item.description ?? "").toLowerCase();
String city = item.displayCity.toLowerCase();
return name.contains(q) || title.contains(q) || desc.contains(q) || city.contains(q);
}).toList();
temp =
temp.where((WalaPlusRetailerModel item) {
String name = (item.name ?? "").toLowerCase();
String title = (item.offerTitle ?? "").toLowerCase();
String desc = (item.description ?? "").toLowerCase();
String city = item.displayCity.toLowerCase();
return name.contains(q) || title.contains(q) || desc.contains(q) || city.contains(q);
}).toList();
}
_filteredRetailersList = temp;
setState(() {});
}
void _openRetailer(WalaPlusRetailerModel item) {
Navigator.pushNamed(
context,
AppRoutes.walaPlusRetailerDetails,
arguments: item,
);
Navigator.pushNamed(context, AppRoutes.walaPlusRetailerDetails, arguments: item);
}
void _performLogout() {
@ -414,19 +397,11 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
child: Icon(
isAr ? Icons.arrow_forward_ios_rounded : Icons.arrow_back_ios_new_rounded,
size: 20,
color: const Color(0xFF1E293B),
),
child: Icon(isAr ? Icons.arrow_forward_ios_rounded : Icons.arrow_back_ios_new_rounded, size: 20, color: const Color(0xFF1E293B)),
),
),
const SizedBox(width: 8),
SvgPicture.asset(
"assets/icons/mazaya_brand.svg",
height: 48,
fit: BoxFit.contain,
),
SvgPicture.asset("assets/icons/mazaya_brand.svg", height: 48, fit: BoxFit.contain),
],
),
Row(
@ -439,20 +414,13 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
width: 24,
height: 24,
color: const Color(0xFF1E293B),
errorBuilder: (context, error, stackTrace) => SvgPicture.asset(
'assets/icons/ic_dependents_top.svg',
width: 24,
height: 24,
colorFilter: const ColorFilter.mode(Color(0xFF1E293B), BlendMode.srcIn),
),
errorBuilder:
(context, error, stackTrace) =>
SvgPicture.asset('assets/icons/ic_dependents_top.svg', width: 24, height: 24, colorFilter: const ColorFilter.mode(Color(0xFF1E293B), BlendMode.srcIn)),
),
tooltip: LocaleKeys.addDependents.tr(),
onPressed: () {
Navigator.pushNamed(
context,
AppRoutes.familyMembers,
arguments: {'fromMazaya': true},
);
Navigator.pushNamed(context, AppRoutes.familyMembers, arguments: {'fromMazaya': true});
},
),
],
@ -490,10 +458,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
_buildBrowseCategoriesHeader(isAr),
// Categories Section
if (categoriesList.isNotEmpty)
_buildCategoriesList(isAr)
else
_buildCategoriesShimmer(),
if (categoriesList.isNotEmpty) _buildCategoriesList(isAr) else _buildCategoriesShimmer(),
// Type Filter Chips (All, In Store, Online)
_buildTypeFilterChips(isAr),
@ -507,12 +472,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.72,
crossAxisSpacing: 12,
mainAxisSpacing: 16,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 0.85, crossAxisSpacing: 12, mainAxisSpacing: 16),
itemCount: _filteredRetailersList.length,
itemBuilder: (context, index) {
return _buildOfferCard(_filteredRetailersList[index], isAr);
@ -520,26 +480,10 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
),
if (isLoadingMore) ...[
16.height,
Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Image.asset(
"assets/images/logos/loading_mohemm_logo.gif",
height: 48.0,
width: 48.0,
),
),
),
Center(child: Padding(padding: const EdgeInsets.symmetric(vertical: 12), child: Image.asset("assets/images/logos/loading_mohemm_logo.gif", height: 48.0, width: 48.0))),
],
] else
Padding(
padding: const EdgeInsets.only(top: 40),
child: Center(
child: LocaleKeys.noOffersAvailable.tr().toText14(
color: const Color(0xFF64748B),
),
),
),
Padding(padding: const EdgeInsets.only(top: 40), child: Center(child: LocaleKeys.noOffersAvailable.tr().toText14(color: const Color(0xFF64748B)))),
],
),
),
@ -557,23 +501,13 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
color: const Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE8E8E8), width: 1.0),
boxShadow: [
BoxShadow(
color: const Color(0xFF000000).withOpacity(0.0314),
offset: const Offset(0, 2),
blurRadius: 5,
spreadRadius: 0,
),
],
boxShadow: [BoxShadow(color: const Color(0xFF000000).withOpacity(0.0314), offset: const Offset(0, 2), blurRadius: 5, spreadRadius: 0)],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.search.tr().toText12(
isBold: true,
color: const Color(0xFF2A333C),
),
LocaleKeys.search.tr().toText12(isBold: true, color: const Color(0xFF2A333C)),
const SizedBox(height: 2),
TextField(
controller: _searchController,
@ -582,19 +516,10 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
isDense: true,
contentPadding: EdgeInsets.zero,
hintText: LocaleKeys.searchItems.tr(),
hintStyle: const TextStyle(
color: Color(0xFFACAFB1),
fontSize: 14,
fontWeight: FontWeight.w400,
height: 1.2,
),
hintStyle: const TextStyle(color: Color(0xFFACAFB1), fontSize: 14, fontWeight: FontWeight.w400, height: 1.2),
border: InputBorder.none,
),
style: const TextStyle(
color: Color(0xFF2A333C),
fontSize: 14,
fontWeight: FontWeight.w400,
),
style: const TextStyle(color: Color(0xFF2A333C), fontSize: 14, fontWeight: FontWeight.w400),
),
],
),
@ -602,13 +527,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
}
Widget _buildBrowseCategoriesHeader(bool isAr) {
return Padding(
padding: const EdgeInsets.only(top: 22, bottom: 14),
child: LocaleKeys.browseCategories.tr().toText18(
isBold: true,
color: const Color(0xFF1E293B),
),
);
return Padding(padding: const EdgeInsets.only(top: 22, bottom: 14), child: LocaleKeys.browseCategories.tr().toText18(isBold: true, color: const Color(0xFF1E293B)));
}
Widget _buildCategoriesList(bool isAr) {
@ -623,8 +542,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
separatorBuilder: (_, __) => const SizedBox(width: 14),
itemBuilder: (BuildContext context, int index) {
WalaPlusCategoryModel item = categoriesList[index];
bool isSelected = (item.id == "all" && (currentCategoryId == "all" || currentCategoryId.isEmpty)) ||
(currentCategoryId.isNotEmpty && currentCategoryId == item.id);
bool isSelected = (item.id == "all" && (currentCategoryId == "all" || currentCategoryId.isEmpty)) || (currentCategoryId.isNotEmpty && currentCategoryId == item.id);
String title = (item.id == "all") ? LocaleKeys.allCategories.tr() : (item.name ?? "");
return InkWell(
@ -691,22 +609,13 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: isSelected ? MyColors.darkIconColor : MyColors.lightGreyEAColor,
),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: isSelected ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 14,
color: isSelected ? MyColors.white : MyColors.black,
),
Icon(icon, size: 14, color: isSelected ? MyColors.white : MyColors.black),
const SizedBox(width: 5),
title.toText12(
color: isSelected ? MyColors.white : MyColors.black,
),
title.toText12(color: isSelected ? MyColors.white : MyColors.black),
],
),
),
@ -723,26 +632,14 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
const double borderWidthVal = 2.8;
const Color activeBorderColor = Color(0xFF00A86B);
bool isAll = (item.id == "all" ||
item.id == "0" ||
(item.name ?? "").toLowerCase() == "all" ||
item.name == "الجميع" ||
item.name == "الكل");
bool isAll = (item.id == "all" || item.id == "0" || (item.name ?? "").toLowerCase() == "all" || item.name == "الجميع" || item.name == "الكل");
Widget imageContent;
if (isAll) {
imageContent = Image.asset(
'assets/images/cat_all.png',
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => _getFallbackCategoryAsset(item),
);
imageContent = Image.asset('assets/images/cat_all.png', width: double.infinity, height: double.infinity, fit: BoxFit.cover, errorBuilder: (_, __, ___) => _getFallbackCategoryAsset(item));
} else {
String categoryImageUrl = item.categoryImageUrl.isNotEmpty
? item.categoryImageUrl
: (item.image?.trim() ?? "");
String categoryImageUrl = item.categoryImageUrl.isNotEmpty ? item.categoryImageUrl : (item.image?.trim() ?? "");
if (categoryImageUrl.isNotEmpty) {
if (categoryImageUrl.toLowerCase().endsWith('.svg') || item.isSvg) {
@ -751,22 +648,10 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
placeholderBuilder: (_) => const Center(
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2, color: Color(0xFF00A86B)),
),
),
placeholderBuilder: (_) => const Center(child: SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2, color: Color(0xFF00A86B)))),
);
} else {
imageContent = Image.network(
categoryImageUrl,
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => _getFallbackCategoryAsset(item),
);
imageContent = Image.network(categoryImageUrl, width: double.infinity, height: double.infinity, fit: BoxFit.cover, errorBuilder: (_, __, ___) => _getFallbackCategoryAsset(item));
}
} else {
imageContent = _getFallbackCategoryAsset(item);
@ -779,19 +664,9 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(borderRadiusVal),
border: isSelected
? Border.all(
color: activeBorderColor,
width: borderWidthVal,
)
: null,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(
isSelected ? (borderRadiusVal - borderWidthVal) : borderRadiusVal,
),
child: imageContent,
border: isSelected ? Border.all(color: activeBorderColor, width: borderWidthVal) : null,
),
child: ClipRRect(borderRadius: BorderRadius.circular(isSelected ? (borderRadiusVal - borderWidthVal) : borderRadiusVal), child: imageContent),
);
}
@ -799,59 +674,20 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
String name = (item.name ?? "").toLowerCase();
if (item.id == "all" || item.id == "0" || name == "all" || name == "الكل" || name == "الجميع") {
return Image.asset(
'assets/images/cat_all.png',
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => _buildFallbackCategoryIconWidget(item),
);
return Image.asset('assets/images/cat_all.png', width: double.infinity, height: double.infinity, fit: BoxFit.cover, errorBuilder: (_, __, ___) => _buildFallbackCategoryIconWidget(item));
} else if (name.contains("shop") || name.contains("retail") || name.contains("تسوق") || name.contains("تجزئة")) {
return Image.asset(
'assets/images/cat_retail.png',
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => _buildFallbackCategoryIconWidget(item),
);
} else if (name.contains("food") ||
name.contains("restaurant") ||
name.contains("مطاعم") ||
name.contains("أغذية") ||
name.contains("cafe") ||
name.contains("مقهى")) {
return Image.asset(
'assets/images/cat_food.png',
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => _buildFallbackCategoryIconWidget(item),
);
} else if (name.contains("fitness") ||
name.contains("wellness") ||
name.contains("sport") ||
name.contains("gym") ||
name.contains("رياضة") ||
name.contains("لياقة") ||
name.contains("صحة")) {
return Image.asset(
'assets/images/cat_fitness.png',
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => _buildFallbackCategoryIconWidget(item),
);
return Image.asset('assets/images/cat_retail.png', width: double.infinity, height: double.infinity, fit: BoxFit.cover, errorBuilder: (_, __, ___) => _buildFallbackCategoryIconWidget(item));
} else if (name.contains("food") || name.contains("restaurant") || name.contains("مطاعم") || name.contains("أغذية") || name.contains("cafe") || name.contains("مقهى")) {
return Image.asset('assets/images/cat_food.png', width: double.infinity, height: double.infinity, fit: BoxFit.cover, errorBuilder: (_, __, ___) => _buildFallbackCategoryIconWidget(item));
} else if (name.contains("fitness") || name.contains("wellness") || name.contains("sport") || name.contains("gym") || name.contains("رياضة") || name.contains("لياقة") || name.contains("صحة")) {
return Image.asset('assets/images/cat_fitness.png', width: double.infinity, height: double.infinity, fit: BoxFit.cover, errorBuilder: (_, __, ___) => _buildFallbackCategoryIconWidget(item));
}
return _buildFallbackCategoryIconWidget(item);
}
Widget _buildFallbackCategoryIconWidget(WalaPlusCategoryModel item) {
return Container(
color: Colors.transparent,
alignment: Alignment.center,
child: _getFallbackCategoryIcon(item, const Color(0xFF168A89)),
);
return Container(color: Colors.transparent, alignment: Alignment.center, child: _getFallbackCategoryIcon(item, const Color(0xFF168A89)));
}
Widget _getFallbackCategoryIcon(WalaPlusCategoryModel item, Color iconColor) {
@ -885,11 +721,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
iconData = Icons.home_rounded;
}
return Icon(
iconData,
color: color,
size: 26,
);
return Icon(iconData, color: color, size: 26);
}
String _getDiscountBadge(WalaPlusRetailerModel item) {
@ -911,23 +743,12 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
}
Widget _buildMerchantMIcon() {
return Container(
color: const Color(0xFFED1C24),
alignment: Alignment.center,
child: "M".toText10(
isBold: true,
color: Colors.white,
),
);
return Container(color: const Color(0xFFED1C24), alignment: Alignment.center, child: "M".toText10(isBold: true, color: Colors.white));
}
Widget _buildOfferCard(WalaPlusRetailerModel item, bool isAr) {
String? bannerUrl = (item.imageThumb != null && item.imageThumb!.isNotEmpty)
? item.imageThumb
: item.image;
String? logoUrl = (item.logoThumb != null && item.logoThumb!.isNotEmpty)
? item.logoThumb
: item.logo;
String? bannerUrl = (item.imageThumb != null && item.imageThumb!.isNotEmpty) ? item.imageThumb : item.image;
String? logoUrl = (item.logoThumb != null && item.logoThumb!.isNotEmpty) ? item.logoThumb : item.logo;
String discountText = _getDiscountBadge(item);
@ -947,9 +768,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
String validityText = item.getDisplayValidity();
String usageText = "";
if (item.displayUsage.isNotEmpty) {
usageText = item.displayUsage
.replaceAll('usage:', LocaleKeys.usageLabel.tr())
.replaceAll('Usage :', LocaleKeys.usageLabel.tr());
usageText = item.displayUsage.replaceAll('usage:', LocaleKeys.usageLabel.tr()).replaceAll('Usage :', LocaleKeys.usageLabel.tr());
}
String cityText = item.getDisplayCity(isAr: isAr);
if (cityText.trim().isEmpty) {
@ -963,14 +782,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: const Color(0xFF0D1720).withOpacity(0.0392),
offset: const Offset(0, 5),
blurRadius: 18,
spreadRadius: 0,
),
],
boxShadow: [BoxShadow(color: const Color(0xFF0D1720).withOpacity(0.0392), offset: const Offset(0, 5), blurRadius: 18, spreadRadius: 0)],
),
padding: const EdgeInsets.all(10),
child: Column(
@ -980,7 +792,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
ClipRRect(
borderRadius: BorderRadius.circular(14),
child: SizedBox(
height: 105,
height: 120,
width: double.infinity,
child: Stack(
fit: StackFit.expand,
@ -988,17 +800,11 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
// Banner Image
(bannerUrl != null && bannerUrl.isNotEmpty)
? Image.network(
bannerUrl,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => Container(
color: const Color(0xFFF1F5F9),
child: const Icon(Icons.image_outlined, color: Color(0xFF94A3B8), size: 32),
),
)
: Container(
color: const Color(0xFFF1F5F9),
child: const Icon(Icons.image_outlined, color: Color(0xFF94A3B8), size: 32),
),
bannerUrl,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => Container(color: const Color(0xFFF1F5F9), child: const Icon(Icons.image_outlined, color: Color(0xFF94A3B8), size: 32)),
)
: Container(color: const Color(0xFFF1F5F9), child: const Icon(Icons.image_outlined, color: Color(0xFF94A3B8), size: 32)),
// Gradient overlay at bottom of image
Positioned(
@ -1007,42 +813,19 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
right: 0,
height: 50,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Colors.black.withOpacity(0.75),
Colors.transparent,
],
),
),
decoration: BoxDecoration(gradient: LinearGradient(begin: Alignment.bottomCenter, end: Alignment.topCenter, colors: [Colors.black.withOpacity(0.75), Colors.transparent])),
),
),
// Discount badge at top right (flush with edge, pill on start side)
if (discountText.isNotEmpty)
PositionedDirectional(
top: 8,
top: 20,
end: 0,
child: Container(
padding: const EdgeInsetsDirectional.only(
start: 14,
end: 10,
top: 4,
bottom: 4,
),
decoration: const BoxDecoration(
color: Color(0xFFED1C24),
borderRadius: BorderRadiusDirectional.only(
topStart: Radius.circular(20),
bottomStart: Radius.circular(20),
),
),
child: discountText.toText14(
isBold: true,
color: Colors.white,
),
padding: const EdgeInsetsDirectional.only(start: 14, end: 10, top: 4, bottom: 4),
decoration: const BoxDecoration(color: Color(0xFFED1C24), borderRadius: BorderRadiusDirectional.only(topStart: Radius.circular(20), bottomStart: Radius.circular(20))),
child: discountText.toText14(isBold: true, color: Colors.white),
),
),
@ -1056,27 +839,12 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
Container(
width: 18,
height: 18,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(4)),
clipBehavior: Clip.antiAlias,
child: (logoUrl != null && logoUrl.isNotEmpty)
? Image.network(
logoUrl,
fit: BoxFit.contain,
errorBuilder: (_, __, ___) => _buildMerchantMIcon(),
)
: _buildMerchantMIcon(),
child: (logoUrl != null && logoUrl.isNotEmpty) ? Image.network(logoUrl, fit: BoxFit.contain, errorBuilder: (_, __, ___) => _buildMerchantMIcon()) : _buildMerchantMIcon(),
),
const SizedBox(width: 5),
Expanded(
child: (item.name ?? "").toText11(
isBold: true,
maxLine: 1,
color: Colors.white,
),
),
Expanded(child: (item.name ?? "").toText11(isBold: true, maxLine: 1, color: Colors.white)),
],
),
),
@ -1088,25 +856,11 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
const SizedBox(height: 8),
// Retailer Name / Bundle Title
(item.name ?? "").toText13(
isBold: true,
maxlines: 1,
overflow: TextOverflow.ellipsis,
color: const Color(0xFF1E293B),
),
if (offerSubtitle.isNotEmpty) ...[
const SizedBox(height: 2),
offerSubtitle.toText11(
maxLine: 1,
color: const Color(0xFF64748B),
),
],
(item.name ?? "").toText14(isBold: true, maxlines: 1, overflow: TextOverflow.ellipsis, color: const Color(0xFF1E293B)),
if (offerSubtitle.isNotEmpty) ...[const SizedBox(height: 2), offerSubtitle.toText14(maxlines: 1, overflow: TextOverflow.ellipsis, isBold: true, color: const Color(0xFF1E293B))],
// Badges Row: Type, Validity, Location & Usage
if ((typeText != null && typeText.trim().isNotEmpty) ||
validityText.trim().isNotEmpty ||
cityText.trim().isNotEmpty ||
usageText.trim().isNotEmpty) ...[
if ((typeText != null && typeText.trim().isNotEmpty) || validityText.trim().isNotEmpty || cityText.trim().isNotEmpty || usageText.trim().isNotEmpty) ...[
const SizedBox(height: 6),
Wrap(
spacing: 5,
@ -1114,80 +868,30 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
children: <Widget>[
// Type Chip (Online or In Store)
if (typeText != null && typeText.trim().isNotEmpty)
Container(
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2.5),
decoration: BoxDecoration(
color: isOnline ? const Color(0xFFEFF6FF) : const Color(0xFFF5F3FF),
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
isOnline ? Icons.language_rounded : Icons.storefront_rounded,
size: 10,
color: isOnline ? const Color(0xFF2563EB) : const Color(0xFF7C3AED),
),
const SizedBox(width: 3),
typeText.toText10(
isBold: true,
color: isOnline ? const Color(0xFF2563EB) : const Color(0xFF7C3AED),
),
],
),
InfoChipWidget(
text: typeText,
icon: isOnline ? Icons.language_rounded : Icons.storefront_rounded,
backgroundColor: isOnline ? const Color(0xFFEFF6FF) : const Color(0xFFF5F3FF),
textColor: isOnline ? const Color(0xFF2563EB) : const Color(0xFF7C3AED),
),
// Validity badge
if (validityText.trim().isNotEmpty)
Container(
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2.5),
decoration: BoxDecoration(
color: const Color(0xFFE6F7F0),
borderRadius: BorderRadius.circular(10),
),
child: validityText.toText10(
isBold: true,
color: const Color(0xFF00A651),
),
),
if (validityText.trim().isNotEmpty) InfoChipWidget(text: validityText, backgroundColor: const Color(0xFFE6F7F0), textColor: const Color(0xFF00A651)),
// Location Badge
if (cityText.trim().isNotEmpty)
Container(
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2.5),
decoration: BoxDecoration(
color: const Color(0xFFF3F4F6),
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Icon(
Icons.location_on_rounded,
size: 10,
color: Color(0xFF64748B),
),
const SizedBox(width: 2.5),
cityText.toText10(
color: const Color(0xFF4B5563),
),
],
),
InfoChipWidget(
text: cityText,
svgIcon: "assets/icons/location.svg",
isBold: false,
backgroundColor: const Color(0xFFF3F4F6),
textColor: const Color(0xFF4B5563),
iconColor: const Color(0xFF64748B),
iconTextGap: 2.5,
),
// Usage badge
if (usageText.trim().isNotEmpty)
Container(
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2.5),
decoration: BoxDecoration(
color: const Color(0xFFFEF3C7),
borderRadius: BorderRadius.circular(10),
),
child: usageText.toText10(
isBold: true,
color: const Color(0xFFB45309),
),
),
if (usageText.trim().isNotEmpty) InfoChipWidget(text: usageText, backgroundColor: const Color(0xFFFEF3C7), textColor: const Color(0xFFB45309)),
],
),
],
@ -1204,78 +908,28 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
child: GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.72,
crossAxisSpacing: 12,
mainAxisSpacing: 16,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 0.72, crossAxisSpacing: 12, mainAxisSpacing: 16),
itemCount: 4,
itemBuilder: (_, __) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)),
padding: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 105,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(14),
),
),
Container(height: 105, width: double.infinity, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(14))),
const SizedBox(height: 8),
Container(
height: 14,
width: 110,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
Container(height: 14, width: 110, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(4))),
const SizedBox(height: 4),
Container(
height: 12,
width: 80,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
Container(height: 12, width: 80, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(4))),
const SizedBox(height: 6),
Wrap(
spacing: 5,
runSpacing: 4,
children: <Widget>[
Container(
height: 16,
width: 50,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
),
Container(
height: 16,
width: 45,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
),
Container(
height: 16,
width: 45,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
),
Container(height: 16, width: 50, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10))),
Container(height: 16, width: 45, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10))),
Container(height: 16, width: 45, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10))),
],
),
],
@ -1306,32 +960,11 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
width: 84,
height: 84,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(18),
),
),
Container(width: 84, height: 84, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(18))),
const SizedBox(height: 8),
Container(
width: 65,
height: 11,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
Container(width: 65, height: 11, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(4))),
const SizedBox(height: 4),
Container(
width: 42,
height: 11,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
Container(width: 42, height: 11, decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(4))),
],
),
);

File diff suppressed because it is too large Load Diff

@ -10,11 +10,13 @@ import 'package:permission_handler/permission_handler.dart';
class AppInAppWebViewScreen extends StatefulWidget {
final String url;
final String? title;
final void Function(InAppWebViewController controller)? onPageLoaded;
const AppInAppWebViewScreen({
Key? key,
required this.url,
this.title,
this.onPageLoaded,
}) : super(key: key);
@override
@ -136,6 +138,9 @@ class _AppInAppWebViewScreenState extends State<AppInAppWebViewScreen> {
}
}
},
onLoadStop: (InAppWebViewController controller, WebUri? url) async {
widget.onPageLoaded?.call(controller);
},
),
if (_progress < 1.0)
LinearProgressIndicator(

@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
/// Small pill-shaped badge used for retailer/offer meta info (type, validity, location, usage, ...).
/// Flexible via optional params - every call only needs to override what differs from the given defaults.
class InfoChipWidget extends StatelessWidget {
final String text;
final Color backgroundColor;
final Color textColor;
final Color? iconColor;
final IconData? icon;
final String? svgIcon;
final bool isBold;
final double iconSize;
final double iconTextGap;
final double horizontalPadding;
final double verticalPadding;
final double borderRadius;
final Color? borderColor;
final double borderWidth;
const InfoChipWidget({
Key? key,
required this.text,
required this.backgroundColor,
required this.textColor,
this.iconColor,
this.icon,
this.svgIcon,
this.isBold = true,
this.iconSize = 10,
this.iconTextGap = 3,
this.horizontalPadding = 7,
this.verticalPadding = 2.5,
this.borderRadius = 10,
this.borderColor,
this.borderWidth = 1,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: horizontalPadding, vertical: verticalPadding),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(borderRadius),
border: Border.all(color: (borderColor ?? textColor).withValues(alpha: 0.7), width: borderWidth),
),
child:
(icon == null && svgIcon == null)
? text.toText10(isBold: isBold, color: textColor)
: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[_buildIcon(), SizedBox(width: iconTextGap), text.toText10(isBold: isBold, color: textColor)],
),
);
}
Widget _buildIcon() {
if (svgIcon != null) {
return SvgPicture.asset(svgIcon!, width: iconSize, height: iconSize, colorFilter: ColorFilter.mode(iconColor ?? textColor, BlendMode.srcIn));
}
return Icon(icon, size: iconSize, color: iconColor ?? textColor);
}
}
Loading…
Cancel
Save