editing card details

This commit is contained in:
ahmadherafi 2023-11-13 09:59:14 +03:00
parent 537122e45d
commit 5a2f57f714
26 changed files with 1397 additions and 529 deletions

11
assets/icons/Eye.svg Normal file
View File

@ -0,0 +1,11 @@
<svg id="Eye" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14.218" height="9.173" viewBox="0 0 14.218 9.173">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_817" data-name="Rectangle 817" width="14.218" height="9.173" fill="#fff"/>
</clipPath>
</defs>
<g id="Group_1881" data-name="Group 1881" clip-path="url(#clip-path)">
<path id="Path_1734" data-name="Path 1734" d="M7.118,9.174A6.924,6.924,0,0,1,3.5,8.066,13.188,13.188,0,0,1,.263,5.231.9.9,0,0,1,.212,4.012,11.734,11.734,0,0,1,4.728.493,6.212,6.212,0,0,1,10.352.9a12.591,12.591,0,0,1,3.615,3.061A.9.9,0,0,1,14,5.162,11.856,11.856,0,0,1,9.387,8.729a6.259,6.259,0,0,1-2.269.445m3.047-4.582A3.057,3.057,0,1,0,7.1,7.644a3.06,3.06,0,0,0,3.067-3.052" transform="translate(0 -0.001)" fill="#fff"/>
<path id="Path_1735" data-name="Path 1735" d="M113.273,54.226a2.181,2.181,0,1,1-2.175,2.187,2.171,2.171,0,0,1,2.175-2.187" transform="translate(-106.171 -51.821)" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1011 B

View File

@ -0,0 +1,37 @@
<svg xmlns="http://www.w3.org/2000/svg" width="71.194" height="34.287" viewBox="0 0 71.194 34.287">
<g id="Group_1695" data-name="Group 1695" transform="translate(-383.127 -774.584)">
<g id="Group_1685" data-name="Group 1685" transform="translate(383.127 774.584)">
<path id="Path_1573" data-name="Path 1573" d="M961.677,936.871l4.254,0H966l4.254,0a4.22,4.22,0,0,1-1.16,1.717A4.666,4.666,0,0,1,966,939.639h-.072a4.675,4.675,0,0,1-3.094-1.051A4.218,4.218,0,0,1,961.677,936.871Z" transform="translate(-956.998 -921.545)" fill="#7986cb"/>
<g id="Group_1679" data-name="Group 1679" transform="translate(0 20.021)">
<path id="Path_1574" data-name="Path 1574" d="M1261.461,1000.909c0-.007,0-.016-.007-.024l-.265-.734-4.635-12.877a.284.284,0,0,0-.266-.187H1253.1a.284.284,0,0,0-.265.186l-4.653,12.877-.265.735-.136.378h3.767l.125-.346.124-.346c.008-.023.016-.046.025-.069l.529-1.463a.281.281,0,0,1,.264-.186h4.1a.282.282,0,0,1,.265.186l.8,2.224h3.806C1261.547,1001.146,1261.5,1001.027,1261.461,1000.909Zm-5.72-4.992h-2.495l1.15-3.874a.282.282,0,0,1,.54,0l.87,2.89q.093.311.188.623c.035.12.072.24.108.36Z" transform="translate(-1216.086 -987.043)" fill="#7986cb"/>
<path id="Path_1575" data-name="Path 1575" d="M1090.921,992.466a.28.28,0,0,1-.166-.469,13.98,13.98,0,0,1,2.883-2.365.283.283,0,0,0,.137-.241v-2.779H1084.9a.282.282,0,0,0-.28.281v2.718h3.992a.279.279,0,0,1,.187.486,16.9,16.9,0,0,0-1.846,2.013.275.275,0,0,0-.059.172v2.064a.281.281,0,0,0,.312.279l.554-.065a3.531,3.531,0,0,1,.4-.021c1.669,0,2.555.645,2.555,1.671,0,.985-.724,1.529-1.911,1.529a5.436,5.436,0,0,1-3.221-1.281.279.279,0,0,0-.424.089l-1.2,2.324a.279.279,0,0,0,.068.344,6.221,6.221,0,0,0,1.8,1.08,8.585,8.585,0,0,0,3.26.584,6,6,0,0,0,3.682-1.107,3.86,3.86,0,0,0,1.57-3.2C1094.337,994.2,1093.194,992.8,1090.921,992.466Z" transform="translate(-1067.702 -986.613)" fill="#44bfe9"/>
<path id="Path_1576" data-name="Path 1576" d="M1464.132,987.375v2.717a.282.282,0,0,1-.282.282H1458.3v2.571h4.375a.283.283,0,0,1,.283.282v2.655a.283.283,0,0,1-.283.281H1458.3v5.1h-3.625V987.375a.282.282,0,0,1,.281-.282h8.893A.282.282,0,0,1,1464.132,987.375Z" transform="translate(-1403.445 -987.048)" fill="#7986cb"/>
<g id="Group_1678" data-name="Group 1678" transform="translate(66.836 0.043)">
<path id="Path_1577" data-name="Path 1577" d="M1623.64,1025.357v10.564h-3.625v-10.558h2.947v-.006Z" transform="translate(-1620.008 -1021.742)" fill="#7986cb"/>
<path id="Path_1578" data-name="Path 1578" d="M1622.885,987.834l-.052-.035a4.406,4.406,0,0,0-2.091-.7c-.232-.023-.5-.027-.5-.027-.126,0-.231,0-.3,0v2.664q1.829,0,3.657,0h.7A4.008,4.008,0,0,0,1622.885,987.834Z" transform="translate(-1619.943 -987.07)" fill="#7986cb"/>
</g>
<path id="Path_1579" data-name="Path 1579" d="M923.26,989.874v.5h-3.347a.376.376,0,0,0-.376.376v10.518h-3.645V990.75a.376.376,0,0,0-.376-.376h-3.391v-2.9a.378.378,0,0,1,.378-.378h7.854a2.905,2.905,0,0,1,2.892,2.624C923.254,989.769,923.258,989.821,923.26,989.874Z" transform="translate(-912.125 -987.048)" fill="#44bfe9"/>
</g>
<g id="Group_1684" data-name="Group 1684" transform="translate(0.004 0)">
<path id="Path_1580" data-name="Path 1580" d="M1359.464,822.9c0-1.01,0-3.943,5.088-4.272a.741.741,0,0,0,.651-.977l-.517-1.528a.746.746,0,0,0-.732-.5c-8.185.259-8.185,6.234-8.185,7.281h-5.049v2.968h14.8V822.9Z" transform="translate(-1309.309 -811.744)" fill="#44bfe9"/>
<path id="Path_1581" data-name="Path 1581" d="M930.625,800.66c-2.8,0-4.681,1.614-4.681,4.035v4.641H915.865c0-.08-.008-.2-.008-.337a4.587,4.587,0,0,1,.815-2.951,3.051,3.051,0,0,1,1.519-.873,1.549,1.549,0,0,0,1.085-1.993l-.016-.047a1.545,1.545,0,0,0-1.649-1.03c-5.447.653-5.447,5.539-5.447,7.232v2.986h17.472l-.02-.02v-7.607a.959.959,0,0,1,1.008-1.029h1.009v8.656h3.712V800.66Z" transform="translate(-912.164 -798.198)" fill="#7986cb"/>
<path id="Path_1582" data-name="Path 1582" d="M1153.4,892.75v2.589a.376.376,0,0,0,.377.377h.026V892.75Z" transform="translate(-1130.625 -881.592)" fill="#7986cb"/>
<path id="Path_1583" data-name="Path 1583" d="M1337.836,785.742a.2.2,0,0,1-.2-.2v-9.122a1.836,1.836,0,1,0-3.671,0v11.314a.977.977,0,0,0,.977.977h4.189v-2.967Z" transform="translate(-1294.136 -774.584)" fill="#7986cb"/>
<path id="Path_1584" data-name="Path 1584" d="M1506.614,847.649a1.838,1.838,0,0,0-3.136,1.3v2.14a.336.336,0,0,1-.334.334H1490.58v2.967h15.232a1.337,1.337,0,0,0,1.338-1.338v-4.1A1.843,1.843,0,0,0,1506.614,847.649Z" transform="translate(-1435.963 -840.264)" fill="#44bfe9"/>
<g id="Group_1680" data-name="Group 1680" transform="translate(57.751 1.33)">
<path id="Path_1585" data-name="Path 1585" d="M1532.352,820.542l-4.254,0h-.072l-4.254,0a4.217,4.217,0,0,1,1.16-1.717,4.667,4.667,0,0,1,3.094-1.051h.072a4.677,4.677,0,0,1,3.094,1.051A4.221,4.221,0,0,1,1532.352,820.542Z" transform="translate(-1523.771 -815.025)" fill="#44bfe9"/>
<path id="Path_1586" data-name="Path 1586" d="M1553.638,788.667h-.035v0A.257.257,0,0,1,1553.638,788.667Z" transform="translate(-1550.786 -788.665)" fill="#e84653"/>
</g>
<g id="Group_1683" data-name="Group 1683" transform="translate(65.571 1.33)">
<g id="Group_1682" data-name="Group 1682">
<g id="Group_1681" data-name="Group 1681">
<path id="Path_1587" data-name="Path 1587" d="M1606.628,788.665v0h-.035A.257.257,0,0,1,1606.628,788.665Z" transform="translate(-1606.593 -788.665)" fill="#e84653"/>
</g>
</g>
</g>
<path id="Path_1588" data-name="Path 1588" d="M1269.288,775.36l-.052-.035a4.416,4.416,0,0,0-2.1-.7c-.232-.023-.5-.027-.5-.027-.127,0-.232,0-.3,0v2.669q1.832,0,3.664,0h.7A4.017,4.017,0,0,0,1269.288,775.36Z" transform="translate(-1232.898 -774.594)" fill="#7986cb"/>
<path id="Path_1589" data-name="Path 1589" d="M1168.61,815.61c-6.071,0-6.288,3.9-6.3,6.952a.333.333,0,0,1-.334.332h-4.307v2.966h11.219c2.139,0,3.41-1.271,3.41-3.046v-7.2Zm0,6.95a.334.334,0,0,1-.335.334h-1.953a.335.335,0,0,1-.335-.336c.005-2.7.106-3.867,2.275-3.973a.334.334,0,0,1,.348.334Z" transform="translate(-1134.492 -811.736)" fill="#7986cb"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

10
assets/icons/Share.svg Normal file
View File

@ -0,0 +1,10 @@
<svg id="Share" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.871" height="14.048" viewBox="0 0 12.871 14.048">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_818" data-name="Rectangle 818" width="12.871" height="14.048" fill="#fff"/>
</clipPath>
</defs>
<g id="Group_1883" data-name="Group 1883" clip-path="url(#clip-path)">
<path id="Path_1736" data-name="Path 1736" d="M12.855,2.54a2.19,2.19,0,0,1-1.408,1.938,2.233,2.233,0,0,1-2.489-.409.241.241,0,0,0-.335-.045Q6.715,5.123,4.8,6.205a.289.289,0,0,0-.178.352,4.327,4.327,0,0,1-.008.976.216.216,0,0,0,.125.256Q6.7,8.9,8.655,10.027c.124.071.188.037.28-.047a2.326,2.326,0,0,1,3.785.933,2.208,2.208,0,0,1-.6,2.471,2.19,2.19,0,0,1-2.516.453A2.239,2.239,0,0,1,8.188,11.73a.753.753,0,0,1,.012-.283c.1-.278-.059-.377-.267-.494Q6.052,9.9,4.184,8.815a.3.3,0,0,0-.4.028,2.334,2.334,0,1,1,0-3.66.308.308,0,0,0,.417.025Q6.1,4.114,8,3.038a.332.332,0,0,0,.2-.4A2.335,2.335,0,0,1,10.341,0,2.381,2.381,0,0,1,12.855,2.54" transform="translate(0 0)" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,4 @@
<svg id="whatsapp_1_" data-name="whatsapp (1)" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30">
<path id="Path_1731" data-name="Path 1731" d="M15,0H15A14.991,14.991,0,0,0,2.856,23.792L.986,29.364l5.766-1.843A15,15,0,1,0,15,0Z" fill="#44bfe9"/>
<path id="Path_1732" data-name="Path 1732" d="M124.711,131.409a4.233,4.233,0,0,1-2.944,2.117c-.784.167-1.807.3-5.254-1.129-4.408-1.826-7.247-6.306-7.468-6.6a8.567,8.567,0,0,1-1.781-4.524,4.789,4.789,0,0,1,1.534-3.651,2.179,2.179,0,0,1,1.534-.538c.186,0,.353.009.5.017.441.019.662.045.952.741.362.872,1.243,3.024,1.348,3.246a.893.893,0,0,1,.064.812,2.592,2.592,0,0,1-.486.688c-.221.255-.431.45-.653.724-.2.238-.431.493-.176.934a13.315,13.315,0,0,0,2.434,3.024,11.028,11.028,0,0,0,3.518,2.169.948.948,0,0,0,1.057-.167,18.149,18.149,0,0,0,1.172-1.552.837.837,0,0,1,1.076-.326c.4.141,2.548,1.2,2.989,1.419s.731.326.838.512A3.736,3.736,0,0,1,124.711,131.409Z" transform="translate(-100.979 -110.227)" fill="#fafafa"/>
</svg>

After

Width:  |  Height:  |  Size: 998 B

BIN
assets/images/download.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View File

@ -7,6 +7,7 @@ class ListViewWidget extends StatelessWidget {
final Axis? scrollDirection;
final ScrollController? scrollController;
final double? itemExtent;
final EdgeInsetsGeometry? padding;
const ListViewWidget(
{super.key,
required this.itemCount,
@ -14,11 +15,13 @@ class ListViewWidget extends StatelessWidget {
this.itemExtent,
this.physics,
this.scrollDirection,
this.scrollController});
this.scrollController,
this.padding});
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: padding,
itemExtent: itemExtent,
controller: scrollController,
scrollDirection: scrollDirection ?? Axis.vertical,

View File

@ -9,20 +9,17 @@ class PagesTranslations implements Translations {
'cancel_appointment': 'Cancel Appointment',
'appointment_canceling': 'Appontiment Canceling',
'are_you_sure_?': 'Are You Sure?',
'appointment_canceled_successfully':
'Appointment Canceled Successfully',
'appointment_canceled_successfully': 'Appointment Canceled Successfully',
'cancel': 'Cancel',
'appointment': 'Appointment',
'you_have_an_appointment_on': 'You have An Appointment on',
'appointment_scheduled_successfully.':
'Appointment scheduled successfully.',
'appointment_scheduled_successfully.': 'Appointment scheduled successfully.',
'am': 'AM',
'pm': 'PM',
'available_times': 'Available Times',
'you_have_an_appointment': 'Details',
'schedule_an_appointment': 'Appointment',
'There are no notifications to display at this time.':
'There are no notifications to display at this time.',
'There are no notifications to display at this time.': 'There are no notifications to display at this time.',
'no_previous_conversations_!': 'No Previous Conversations !',
'add_some_by_contact_with_others': 'Add Some By Contact With Others',
'this_session_is_terminated': 'This session is terminated',
@ -59,8 +56,7 @@ class PagesTranslations implements Translations {
'yes': 'Yes',
'no': 'No',
'are_you_sure_you_want_to_exit?': 'Are You sure you want to exit?',
'press_(new_card)_to_add_new_card!':
'Press (new card) to add new card!',
'press_(new_card)_to_add_new_card!': 'Press (new card) to add new card!',
'could_not_send_email': 'Could not send e-mail',
'could_not_make_call': 'Could not make call',
'card_images': 'Card Images',
@ -178,24 +174,32 @@ class PagesTranslations implements Translations {
"address": "Address",
"postal_code": "Postal Code",
"website": "Website",
"the_card_has_been_edited_successfully":
"The Card Has been edited Successfully",
"the_card_has_been_edited_successfully": "The Card Has been edited Successfully",
"please_enter_the_website": "Please Enter The Website",
"please_enter_the_service": "please Enter The Service",
"please_enter_the_details": "Please Enter The Details",
"the_card_has_been_added_successfully":
"The Card Has been added Successfully",
"the_card_has_been_added_successfully": "The Card Has been added Successfully",
"add_card": "Add Card",
"your_message": "Your Message",
'search_chat': 'Search Chat',
'photo_has_been_saved_successfully':
'Photo has been saved successfully',
'photo_has_been_saved_successfully': 'Photo has been saved successfully',
'failed_to_save': 'Failed to Save',
'unknown_error': 'UnKnown error',
'the_card_has_been_deleted_successfully':
'The Card has been deleted successfully',
'the_card_has_been_deleted_successfully': 'The Card has been deleted successfully',
'enter_your_email_to_reset_your_password_please_\n_we_will_send_verification_code_to_your_email.':
'Enter your email to reset your password please \n We will send verification code to your Email.',
'consultation price:': "consultation price:",
"Number of users who rate this : ": "Number of users who rate this : ",
"Rate Now": "Rate Now",
"Waiting": "Waiting",
"Performance": "Performance",
"Price": "Price",
"waiting?": "waiting?",
"Performance?": "Performance?",
"Price?": "Price?",
"Next": "Next",
"OK": "OK",
"back": "back",
},
'ar': {
'english': 'الإنجليزية',
@ -213,11 +217,9 @@ class PagesTranslations implements Translations {
'available_times': 'الأوقات المتاحة',
'you_have_an_appointment': 'التفاصيل',
'schedule_an_appointment': 'حجز موعد',
'There are no notifications to display at this time.':
'لا توجد إشعارات لعرضها في الوقت الحالي.',
'There are no notifications to display at this time.': 'لا توجد إشعارات لعرضها في الوقت الحالي.',
'no_previous_conversations_!': 'لا توجد محادثات سابقة!',
'add_some_by_contact_with_others':
'أضف بعضها عن طريق التواصل مع الآخرين',
'add_some_by_contact_with_others': 'أضف بعضها عن طريق التواصل مع الآخرين',
"this_session_is_terminated": "تم إنهاء هذه الجلسة",
"log_out_from_other_devices": "تسجيل الخروج من الأجهزة الأخرى",
'version_update': 'تحديث الإصدار',
@ -253,8 +255,7 @@ class PagesTranslations implements Translations {
'yes': 'نعم',
'no': 'لا',
'are_you_sure_you_want_to_exit?': 'هل تريد الخروج من التطبيق؟',
'press_(new_card)_to_add_new_card!':
'اضغط (بطاقة جديدة) لإضافة بطاقة جديدة!',
'press_(new_card)_to_add_new_card!': 'اضغط (بطاقة جديدة) لإضافة بطاقة جديدة!',
'card_images': 'صور البطاقة',
'photo_has_been_saved_successfully': 'تم حفظ الصورة بنجاح',
'save_to_gallery': 'حفظ في المعرض',
@ -266,10 +267,8 @@ class PagesTranslations implements Translations {
'تواصل معنا, sed do eiusmod tempor incididunt Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididuntLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididuntLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididuntLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididuntLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididuntLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt',
'about_us_content':
'من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن من نحن',
'terms_content':
"الشروط الشروط الشروط الشروط الشروط الشروط الشروط والخصوصية والخصوصية والخصوصية",
'privacy_content':
"الشروط الشروط الشروط الشروط الشروط الشروط الشروط والخصوصية والخصوصية والخصوصية",
'terms_content': "الشروط الشروط الشروط الشروط الشروط الشروط الشروط والخصوصية والخصوصية والخصوصية",
'privacy_content': "الشروط الشروط الشروط الشروط الشروط الشروط الشروط والخصوصية والخصوصية والخصوصية",
'profile_edited_succesfully': 'تم تعديل الملف الشخصي بنجاح',
"enter_your_email_to_reset_your_password_please_\n_we_will_send_verification_code_to_your_email.":
"يرجى إدخال بريدك الإلكتروني لإعادة تعيين كلمة المرور \n سنرسل رمز التحقق إلى بريدك الإلكتروني.",
@ -383,6 +382,18 @@ class PagesTranslations implements Translations {
"your_message": "رسالتك",
'search_chat': 'البحث في الدردشات',
'failed_to_save': 'فشل الحفظ',
'consultation price:': 'سعر المعاينة',
"Number of users who rate this : ": "عدد الأشخاص الذين قيموا هذه البطاقة:",
"Rate Now": "قيم الان",
"Waiting": "الانتظار",
"Performance": "الأداء",
"Price": "السعر",
"waiting?": "الانتطار؟",
"Performance?": "الأداء؟",
"Price?": "السعر؟",
"Next": "التالي",
"OK": "تم",
"back": "رجوع",
},
};
}

View File

@ -8,6 +8,9 @@ import 'package:taafee_mobile/features/auth/presentation_layer/screens/forgot_pa
import 'package:taafee_mobile/features/auth/presentation_layer/screens/reset_password.dart';
import 'package:taafee_mobile/features/auth/presentation_layer/screens/verification_code_reset_password.dart';
import 'package:taafee_mobile/features/card/presentation_layer/screens/card_details.dart';
import 'package:taafee_mobile/features/card/presentation_layer/screens/feedback.dart';
import 'package:taafee_mobile/features/card/presentation_layer/screens/images_view.dart';
import 'package:taafee_mobile/features/card/presentation_layer/screens/review_form.dart';
import 'package:taafee_mobile/features/category/presentation_layer/screens/category_details.dart';
import 'package:taafee_mobile/features/chat/presentation_layer/screens/chat_details.dart';
import 'package:taafee_mobile/features/home/presentation_layer/screens/super_home.dart';
@ -44,8 +47,7 @@ class RouteName {
static String categoryDetails = '/category-details';
static String chatDetails = '/chat-details';
static String resetPassword = '/reset-password-screen';
static String verificationCodeResetPassword =
'/verification-code-reset-password-screen';
static String verificationCodeResetPassword = '/verification-code-reset-password-screen';
static String cardDetails = '/card-details-screen';
static String addCard = '/add-card-screen';
static String notification = '/notification-screen';
@ -54,6 +56,9 @@ class RouteName {
static String contactUs = '/contact-us-screen';
static String privacy = '/privacy-screen';
static String forgotPassword = '/forgot-password-screen';
static String feedback = '/feedback-screen';
static String reviewForm = '/review-form-screen';
static String imageView = '/image-view-screen';
}
class RoutingManager {
@ -154,6 +159,18 @@ class RoutingManager {
name: RouteName.forgotPassword,
page: () => ForgotPasswordScreen(),
),
GetPage(
name: RouteName.feedback,
page: () => const FeedbackScreen(),
),
GetPage(
name: RouteName.reviewForm,
page: () => const ReviewFormScreen(),
),
GetPage(
name: RouteName.imageView,
page: () => ImagesViewScreen(),
),
];
static void off(String route) {

View File

@ -27,4 +27,14 @@ class UrlLauncherService {
Toast.showToast('could_not_make_call'.tr);
}
}
static Future<void> sendWhatsapp(String phoneNumber) async {
// String phone = "+963 940903459";
String androidUrl = "whatsapp://send?phone=$phoneNumber&text=Hi, I need some help";
try {
await launchUrl(Uri.parse(androidUrl));
} on Exception {
Toast.showToast("WhatsApp is not installed.");
}
}
}

View File

@ -4,12 +4,15 @@ import 'package:get/get.dart';
import 'package:taafee_mobile/common/const/const.dart';
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/button.dart';
import 'package:taafee_mobile/common/widgets/listview.dart';
import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/common/widgets/textfiled.dart';
import 'package:taafee_mobile/core/routing/routing_manager.dart';
import 'package:taafee_mobile/features/account/business_logic_layer/account_controller.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/image.dart';
import 'package:taafee_mobile/features/auth/business_logic_layer/auth_controller.dart';
import 'package:taafee_mobile/features/card/business_logic_layer/card_controller.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/consultation_price.dart';
import 'package:taafee_mobile/features/chat/business%20logic%20layer/chat_controller.dart';
import 'package:taafee_mobile/features/chat/data_layer/model/room.dart';
import 'package:taafee_mobile/features/chat/presentation_layer/widgets/circle_avatar.dart';
@ -46,9 +49,8 @@ class AccountScreen extends StatelessWidget {
child: Obx(() {
return (!authController.isGuest.value)
? Row(
mainAxisAlignment: !homeController.isArabic.value
? MainAxisAlignment.end
: MainAxisAlignment.start,
mainAxisAlignment:
!homeController.isArabic.value ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [
SvgPicture.asset(
"assets/icons/log out.svg",
@ -62,11 +64,8 @@ class AccountScreen extends StatelessWidget {
),
Visibility(
visible: authController.logoutState.loading,
child: SizedBox(
width: 16,
height: 16,
child: const CircularProgressIndicator()
.center())),
child:
SizedBox(width: 16, height: 16, child: const CircularProgressIndicator().center())),
],
).onTap(() {
authController.logout(
@ -85,9 +84,8 @@ class AccountScreen extends StatelessWidget {
);
})
: Row(
mainAxisAlignment: !homeController.isArabic.value
? MainAxisAlignment.end
: MainAxisAlignment.start,
mainAxisAlignment:
!homeController.isArabic.value ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [
SvgPicture.asset(
"assets/icons/log out.svg",
@ -101,16 +99,12 @@ class AccountScreen extends StatelessWidget {
),
Visibility(
visible: authController.logoutState.loading,
child: SizedBox(
width: 16,
height: 16,
child: const CircularProgressIndicator()
.center())),
child:
SizedBox(width: 16, height: 16, child: const CircularProgressIndicator().center())),
],
).onTap(() {
RoutingManager.offAll(RouteName.login);
String? languangeCode =
homeController.storage.getLanguage();
String? languangeCode = homeController.storage.getLanguage();
homeController.storage.clearCache();
if (languangeCode != null) {
homeController.storage.saveLanguage(languangeCode);
@ -126,29 +120,49 @@ class AccountScreen extends StatelessWidget {
isUserAvatar: true,
radius: Responsive.isTablet() ? 80 : 40,
).paddingOnly(bottom: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Obx(
() => BoldTextWidget(
" ${homeController.user.value!.firstName} "
" ${homeController.user.value!.lastName} ",
fontSize: Responsive.isTablet() ? 22 : 14,
color: AppColors.textColor,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx(
() => BoldTextWidget(
" ${homeController.user.value!.firstName} "
" ${homeController.user.value!.lastName} ",
fontSize: Responsive.isTablet() ? 22 : 14,
color: AppColors.textColor,
),
),
if (!authController.isGuest.value)
SvgPicture.asset(
"assets/icons/edit-2.svg",
).onTap(() {
RoutingManager.to(RouteName.editProfile);
}),
],
),
MediumTextWidget(
homeController.user.value!.email,
fontSize: Responsive.isTablet() ? 22 : 14,
),
if (!authController.isGuest.value)
SvgPicture.asset(
"assets/icons/edit-2.svg",
).onTap(() {
RoutingManager.to(RouteName.editProfile);
}),
],
),
MediumTextWidget(
homeController.user.value!.email,
fontSize: Responsive.isTablet() ? 22 : 14,
).paddingOnly(bottom: 20),
// Stack(
// alignment: Alignment.topCenter,
// children: [
// Container(
// width: Get.width,
// height: 100,
// color: Colors.red,
// ),
// CircleAvatarWidget(
// isUserAvatar: true,
// radius: Responsive.isTablet() ? 80 : 40,
// ).paddingOnly(bottom: 0),
// ],
// ),
AccountWidget(
icon: "my cards.svg",
title: "my_cards".tr,
@ -267,8 +281,7 @@ class AccountScreen extends StatelessWidget {
onChanged: (value) {
if (value == 'english') {
accountController.changeLanguage(Languages.english);
homeController
.setUiLanguage(Languages.english.code);
homeController.setUiLanguage(Languages.english.code);
}
if (value == 'arabic') {
accountController.changeLanguage(Languages.arabic);
@ -278,8 +291,7 @@ class AccountScreen extends StatelessWidget {
})
],
).paddingSymmetric(horizontal: 15),
).paddingSymmetric(
horizontal: Responsive.isTablet() ? Get.width * 0.15 : 0),
).paddingSymmetric(horizontal: Responsive.isTablet() ? Get.width * 0.15 : 0),
Divider(
color: AppColors.dividerColor,
thickness: 1,
@ -359,10 +371,8 @@ class AccountScreen extends StatelessWidget {
if (error.toString() == "invalid_credentials") {
Toast.showToast("invalid_credentials".tr);
}
if (error.toString() ==
"You Have no Internet Connection") {
Toast.showToast(
"you_have_no_internet_connection".tr);
if (error.toString() == "You Have no Internet Connection") {
Toast.showToast("you_have_no_internet_connection".tr);
}
},
);
@ -409,8 +419,7 @@ class AccountScreen extends StatelessWidget {
Obx(() {
return ButtonWidget(
hideTextOnLoading: true,
isLoading: authController
.terminateOtherSessionsState.loading,
isLoading: authController.terminateOtherSessionsState.loading,
width: 100,
textColor: Colors.white,
color: AppColors.redColor,
@ -420,14 +429,11 @@ class AccountScreen extends StatelessWidget {
RoutingManager.back();
},
onError: (error) {
if (error.toString() ==
"invalid_credentials") {
if (error.toString() == "invalid_credentials") {
Toast.showToast("invalid_credentials".tr);
}
if (error.toString() ==
"You Have no Internet Connection") {
Toast.showToast(
"you_have_no_internet_connection".tr);
if (error.toString() == "You Have no Internet Connection") {
Toast.showToast("you_have_no_internet_connection".tr);
}
},
);

View File

@ -31,8 +31,7 @@ class CardController extends GetxController {
});
}
Future<void> addCard(
{void Function(void)? onSuccess, void Function(Object)? onError}) async {
Future<void> addCard({void Function(void)? onSuccess, void Function(Object)? onError}) async {
await addCardState.observe(
(p0) async {
await cardService.addCard(cardModel.value);
@ -47,14 +46,12 @@ class CardController extends GetxController {
}
//-------------get cards-----------//
RxFuture<Pagination<CardModel>> cardState =
RxFuture(Pagination<CardModel>.zero());
RxFuture<Pagination<CardModel>> cardState = RxFuture(Pagination<CardModel>.zero());
Future<void> getCards({void Function(Object e)? onConnectionError}) async {
await cardState.observe((value) async {
await value?.nextPage((currentPage) async {
List<CardModel> cards = await cardService.getCards(
page: currentPage, onConnectionError: onConnectionError);
List<CardModel> cards = await cardService.getCards(page: currentPage, onConnectionError: onConnectionError);
if (cards.isEmpty) return [];
return cards;
@ -85,22 +82,19 @@ class CardController extends GetxController {
update();
await favoriteState.observe((p0) async {
removeFromFavorite
? await cardService.removeFromFavorite(id)
: await cardService.addToFavorite(id);
removeFromFavorite ? await cardService.removeFromFavorite(id) : await cardService.addToFavorite(id);
}, onSuccess: onSuccess, onError: onError);
}
///-------------my cards------------///
RxFuture<Pagination<CardModel>> myCardState = RxFuture(Pagination.zero());
Future<void> getMyCards(int userId,
{void Function(Object)? onConnectionError}) async {
Future<void> getMyCards(int userId, {void Function(Object)? onConnectionError}) async {
myCardState.result.clear();
await myCardState.observe((value) async {
await value?.nextPage((currentPage) async {
List<CardModel> cards = await cardService.getMyCards(userId,
page: currentPage, onConnectionError: onConnectionError);
List<CardModel> cards =
await cardService.getMyCards(userId, page: currentPage, onConnectionError: onConnectionError);
if (cards.isEmpty) return [];
return cards;
});
@ -115,8 +109,7 @@ class CardController extends GetxController {
Rx<EditCardModel> editCardModel = EditCardModel.zero().obs;
RxFuture<void> editCardState = RxFuture(null);
Future<void> editCard(int cardId,
{void Function(void)? onSuccess, void Function(Object)? onError}) async {
Future<void> editCard(int cardId, {void Function(void)? onSuccess, void Function(Object)? onError}) async {
await editCardState.observe(
(p0) async {
await cardService.editCard(cardId, editCardModel.value);
@ -162,8 +155,7 @@ class CardController extends GetxController {
Future updateNetworkImages(int cardId) async {
networkImagesState.observe(
(p0) async {
return cardModelNetworkImages.value =
await cardService.getCardImages(cardId);
return cardModelNetworkImages.value = await cardService.getCardImages(cardId);
},
onSuccess: (cardImages) {
cardModelNetworkImages.refresh();
@ -176,8 +168,7 @@ class CardController extends GetxController {
cardModel.refresh();
}
void deleteImage(int imageId,
{void Function(void)? onSuccess, required int cardId}) async {
void deleteImage(int imageId, {void Function(void)? onSuccess, required int cardId}) async {
if (!addImagesState.loading) {
deleteImageState.observe(
(p0) async {
@ -226,8 +217,7 @@ class CardController extends GetxController {
final Random random = Random();
RxFuture<void> saveCardState = RxFuture(null);
saveNetworkImage(String imageUrl,
{void Function(Object)? onError, void Function(void)? onSuccess}) async {
saveNetworkImage(String imageUrl, {void Function(Object)? onError, void Function(void)? onSuccess}) async {
saveCardState.observe((p0) async {
Uint8List image = await cardService.downloadImage(imageUrl);
await ImageGallerySaver.saveImage(
@ -247,4 +237,11 @@ class CardController extends GetxController {
await Future.delayed(const Duration(seconds: 3));
});
}
//----------rating----------//
RxInt currentIndex = 1.obs;
void changeCurrentIndex(int index) {
currentIndex.value = index;
}
}

View File

@ -0,0 +1,11 @@
class WorkingTimeModel {
String type;
String startTime;
String endTime;
WorkingTimeModel({
required this.type,
required this.startTime,
required this.endTime,
});
}

View File

@ -4,14 +4,20 @@ import 'package:get/get.dart';
import 'package:taafee_mobile/common/const/const.dart';
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/button.dart';
import 'package:taafee_mobile/common/widgets/listview.dart';
import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/core/routing/routing_manager.dart';
import 'package:taafee_mobile/core/utils/utils.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/image.dart';
import 'package:taafee_mobile/features/card/business_logic_layer/card_controller.dart';
import 'package:taafee_mobile/features/card/data_layer/model/appointment.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_details.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/card_service.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/consultation_price.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/wording_time.dart';
import 'package:taafee_mobile/features/chat/business%20logic%20layer/chat_controller.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import '../../../../common/widgets/header_screen.dart';
import '../../../../common/widgets/toast.dart';
import '../../../../core/url launcher/url_launcher_service.dart';
@ -24,6 +30,10 @@ import '../widgets/card_header.dart';
import '../widgets/card_image.dart';
import '../widgets/card_information.dart';
import '../widgets/card_location.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart' as location;
import '../widgets/rate.dart';
class CardDetailsScreen extends StatelessWidget {
final CardModel cardModel = Get.arguments;
@ -33,443 +43,433 @@ class CardDetailsScreen extends StatelessWidget {
final ChatController chatController = Get.find<ChatController>();
@override
Widget build(BuildContext context) {
void appointmentSchedulingDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
contentPadding: EdgeInsets.zero,
actionsPadding: EdgeInsets.zero,
title: RegularTextWidget(
"available_times".tr,
fontSize: 14,
),
content: Obx(() {
if (cardController.availableAppointmentsState.loading ||
homeController.appointmentSchedulingState.loading) {
return SizedBox(
width: 320,
height: 320,
child: const CircularProgressIndicator().center());
}
return SizedBox(
height: 320,
width: 320,
child: Column(
children: [
const SizedBox(
height: 20,
),
SizedBox(
height: 280,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: 12,
itemBuilder: (context, index) {
DateTime dateTime = Utils.generateRandomDateTime();
return AppointmentWidget(dateTime: dateTime)
.paddingOnly(bottom: 16)
.onTap(() {
homeController.scheduleAnAppointment(
Appointment(
cardId: cardModel.id,
dateTime: dateTime,
user: homeController.user.value!),
onSuccess: () {
Toast.showToast(
'appointment_scheduled_successfully.'.tr);
RoutingManager.back();
});
});
},
).paddingOnly(left: 8, right: 8, top: 8, bottom: 8),
),
const SizedBox(
height: 20,
),
],
),
);
}),
);
});
}
void appointmentDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
contentPadding: EdgeInsets.zero,
actionsPadding: EdgeInsets.zero,
title: HeaderScreen(
' ${"appointment".tr}',
),
content: AppointmentDetails(
appointment: homeController.currentCardAppointment.value!),
);
});
}
cardController.updateCardNetworkImageUrls(cardModel.cardImages);
return Scaffold(
appBar: AppBar(
leadingWidth: homeController.isArabic.value ? 16 : 30,
leading: SizedBox(
child: Obx(
() => (!homeController.isArabic.value)
? SvgPicture.asset(
"assets/icons/arrow-left.svg",
width: Responsive.isTablet() ? 20 : null,
)
: SvgPicture.asset(
"assets/icons/arrow right.svg",
width: Responsive.isTablet() ? 20 : null,
),
),
).paddingSymmetric(horizontal: 3).onTap(
() {
RoutingManager.back();
},
),
centerTitle: true,
backgroundColor: Colors.white,
title: SizedBox(
width: 50,
height: 50,
child: SvgPicture.asset("assets/icons/tafee icon.svg"),
),
),
backgroundColor: AppColors.backGroundColor,
body: SingleChildScrollView(
child: Column(
children: [
if (Responsive.isTablet())
const SizedBox(
height: 30,
),
HeaderScreen(
"page_details".tr,
additionalOnTap: () {
cardController.cardState.result.clear();
cardController.getCards();
},
)
.paddingOnly(top: 30, bottom: 30)
.paddingSymmetric(horizontal: Responsive.isTablet() ? 20 : 20),
if (Responsive.isTablet())
const SizedBox(
height: 20,
),
Container(
width: Get.width * .89,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: Colors.white,
),
child: Column(
crossAxisAlignment: Responsive.isTablet()
? CrossAxisAlignment.start
: CrossAxisAlignment.center,
children: [
CardHeaderWidget(
cardModel: cardModel,
isFromDetailsScreen: true,
),
CardInformation(cardModel: cardModel)
.paddingSymmetric(
horizontal: Responsive.isTablet() ? 0 : 5, vertical: 5)
.paddingOnly(
left: homeController.isArabic.value ? 0 : 3,
right: homeController.isArabic.value ? 3 : 0,
Stack(
alignment: Alignment.topCenter,
children: [
Column(
children: [
Container(
width: Get.width,
height: 60,
decoration: BoxDecoration(
color: AppColors.secondaryColor,
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
const SizedBox(
height: 8,
),
CardEmailWidget(
cardModel: cardModel,
).paddingSymmetric(
horizontal: 7,
),
const SizedBox(
height: 8,
),
CardLocationWidget(
cardModel: cardModel,
).paddingSymmetric(
horizontal: 5,
vertical: 5,
),
CardServiceWidget(
cardModel: cardModel,
maxLines: 4,
width: Get.width * 0.69,
)
.paddingSymmetric(
horizontal: 5,
vertical: 5,
)
.paddingOnly(
left: homeController.isArabic.value ? 0 : 8,
right: homeController.isArabic.value ? 8 : 0,
)
.align(
alignment: homeController.isArabic.value
? Alignment.centerRight
: Alignment.centerLeft),
CardDetailsWidget(
cardModel: cardModel,
).paddingSymmetric(horizontal: Responsive.isTablet() ? 0 : 15),
if (cardModel.cardImages.isEmpty)
const SizedBox(
height: 8,
),
if (cardModel.cardImages.isNotEmpty)
Divider(
color: AppColors.dividerColor,
thickness: 1,
).paddingSymmetric(horizontal: 15),
if (cardModel.cardImages.isNotEmpty)
MediumTextWidget(
"images".tr,
textAlign: TextAlign.left,
).paddingSymmetric(horizontal: 15).align(
alignment: homeController.isArabic.value
? Alignment.centerRight
: Alignment.centerLeft),
if (cardModel.cardImages.isNotEmpty)
if (Responsive.isTablet())
Row(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CardImageWidget(
width: Get.width * 0.4,
height: Get.width * 0.4,
cardImages: cardModel.cardImages[0],
).onTap(() {
cardController.changeImageIndex(0);
cardController.pageControllerInitialValue(0);
RoutingManager.to(RouteName.imagesGalleryView,
arguments: cardController.cardNetworkImagesUrls);
}),
if (cardModel.cardImages.length > 1)
SizedBox(
width: Get.width * 0.4,
height: Get.width * 0.4,
child: GridView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: cardModel.cardImages.length - 1,
shrinkWrap: true,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: Responsive.isTablet() ? 2 : 3,
childAspectRatio:
Responsive.isTablet() ? 1 : 1.5,
),
itemBuilder: (BuildContext context, index) {
return CardImageWidget(
cardImages: cardModel.cardImages[index + 1],
).onTap(() {
cardController.changeImageIndex(index + 1);
cardController
.pageControllerInitialValue(index + 1);
RoutingManager.to(RouteName.imagesGalleryView,
arguments:
cardController.cardNetworkImagesUrls);
});
},
SvgPicture.asset("assets/icons/Share.svg"),
Row(
children: [
const RegularTextWidget(
" 300 ",
color: Colors.white,
),
),
SvgPicture.asset("assets/icons/Eye.svg"),
],
)
],
).paddingSymmetric(horizontal: 20),
),
Container(
alignment: Alignment.bottomCenter,
width: Get.width,
height: 120,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BoldTextWidget(
" ${cardModel.user.firstName} "
" ${cardModel.user.lastName} ",
fontSize: Responsive.isTablet() ? 22 : 14,
color: AppColors.textColor,
),
],
),
MediumTextWidget(
cardModel.name,
fontSize: Responsive.isTablet() ? 22 : 14,
),
],
).paddingOnly(bottom: 20),
if (!Responsive.isTablet())
GridView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: cardModel.cardImages.length,
shrinkWrap: true,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1.5,
),
itemBuilder: (BuildContext context, index) {
return CardImageWidget(
cardImages: cardModel.cardImages[index],
).onTap(() {
cardController.changeImageIndex(index);
cardController.pageControllerInitialValue(index);
RoutingManager.to(RouteName.imagesGalleryView,
arguments: cardController.cardNetworkImagesUrls);
});
},
)
],
),
CircleAvatar(
radius: 60,
backgroundColor: AppColors.secondaryColor,
),
const Positioned(
top: 15,
child: CircleAvatar(
radius: 50,
backgroundImage: AssetImage(
"assets/images/Ellipse 8.png",
),
),
),
],
),
const SizedBox(
height: 20,
),
SizedBox(
width: Get.width * .92,
height: 75,
child: ListViewWidget(
physics: const BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: 4,
childBuilder: (index) {
if (index == 3) {
return const ImageWidget(
numberOfImages: 5,
).onTap(() {
RoutingManager.to(RouteName.imageView);
});
}
return const ImageWidget(numberOfImages: 1);
},
),
),
const SizedBox(
height: 20,
),
ConsultationPriceWidget(
cardModel: cardModel,
),
const SizedBox(
height: 20,
),
WorkingTimeWidget(),
const SizedBox(
height: 20,
),
RateWidget(),
const SizedBox(
height: 20,
),
SizedBox(
width: Get.width * .89,
height: 150,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(8),
// ),
child: FlutterMap(
options: MapOptions(
center: const location.LatLng(51.509364, -0.128928),
),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'com.example.app',
),
// RichAttributionWidget(
// attributions: [
// TextSourceAttribution(
// 'OpenStreetMap contributors',
// onTap: () => launchUrl(Uri.parse('https://openstreetmap.org/copyright')),
// ),
// ],
// ),
],
),
),
const SizedBox(
height: 40,
height: 20,
),
Container(
width: Get.width * .89,
height: 100,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const RegularTextWidget(
"Information about the doctor",
color: Colors.grey,
fontSize: 14,
).paddingSymmetric(horizontal: 30),
RegularTextWidget(cardModel.additionalData).paddingSymmetric(horizontal: 10, vertical: 5)
],
),
),
Row(
children: [
ButtonWidget(
color: AppColors.callColor,
haveIcon: true,
onTap: () async {
await UrlLauncherService.makePhoneCall(cardModel.phoneNumber);
},
title: "call_owner".tr,
textColor: Colors.white,
child: SvgPicture.asset(
"assets/icons/phone.svg",
colorFilter:
const ColorFilter.mode(Colors.white, BlendMode.srcIn),
),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5),
ButtonWidget(
color: AppColors.emailColor,
haveIcon: true,
onTap: () async {
await UrlLauncherService.sendEmail(cardModel.user.email);
},
title: "email".tr,
textColor: Colors.white,
child: SvgPicture.asset("assets/icons/Email.svg"),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5),
if (Responsive.isTablet())
Visibility(
visible:
chatController.chatUser.id != cardModel.user.chatUserId,
child: Obx(() {
return ButtonWidget(
isLoading: chatController.createRoomState.loading,
textColor: Colors.white,
color: AppColors.messageColor,
haveIcon: true,
onTap: () {
if (chatController.connectionState.value ==
SocketConnectionState.connected) {
chatController.createRoom(
chatUserId: cardModel.user.chatUserId,
onSuccess: (room) {
RoutingManager.to(RouteName.chatDetails,
arguments: {
"room": room,
});
});
} else {
Toast.showToast(
'you_have_no_internet_connection.'.tr);
}
},
title: "start_conversation".tr,
fontSize: 13,
child: SvgPicture.asset("assets/icons/message.svg"),
).expanded(Responsive.isTablet() ? 1 : 5);
}),
),
if (Responsive.isTablet())
Obx(() {
return Visibility(
visible: homeController.user.value!.id != cardModel.user.id,
child: (homeController.currentCardAppointment.value != null)
? ButtonWidget(
haveIcon: true,
onTap: () {
appointmentDialog(context);
},
fontSize: 13,
color: AppColors.secondaryColor,
title: 'you_have_an_appointment'.tr,
child: const Icon(
Icons.schedule,
color: Colors.white,
),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5)
: ButtonWidget(
onTap: () {
cardController.getAvailableAppointments();
appointmentSchedulingDialog(context);
},
haveIcon: true,
fontSize: 12,
title: 'schedule_an_appointment'.tr,
color: AppColors.secondaryColor,
child: const Icon(
Icons.schedule,
color: Colors.white,
),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5),
);
}),
],
).paddingSymmetric(
vertical: Responsive.isTablet() ? 20 : 4,
horizontal: Responsive.isTablet() ? 40 : 10),
if (!Responsive.isTablet())
Obx(() {
return Row(
children: [
Obx(() {
return Visibility(
visible:
homeController.user.value!.id != cardModel.user.id,
child:
(homeController.currentCardAppointment.value != null)
? ButtonWidget(
haveIcon: true,
onTap: () {
appointmentDialog(context);
},
fontSize: 12,
color: AppColors.secondaryColor,
title: 'you_have_an_appointment'.tr,
child: const Icon(
Icons.schedule,
color: Colors.white,
),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5)
: ButtonWidget(
onTap: () {
cardController.getAvailableAppointments();
appointmentSchedulingDialog(context);
},
haveIcon: true,
fontSize: 12,
title: 'schedule_an_appointment'.tr,
color: AppColors.secondaryColor,
child: const Icon(
Icons.schedule,
color: Colors.white,
),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5),
);
}),
Visibility(
visible:
chatController.chatUser.id != cardModel.user.chatUserId,
child: ButtonWidget(
isLoading: chatController.createRoomState.loading,
textColor: Colors.white,
color: AppColors.messageColor,
haveIcon: true,
onTap: () {
if (chatController.connectionState.value ==
SocketConnectionState.connected) {
chatController.createRoom(
chatUserId: cardModel.user.chatUserId,
onSuccess: (room) {
RoutingManager.to(RouteName.chatDetails,
arguments: {"room": room});
});
} else {
Toast.showToast('you_have_no_internet_connection'.tr);
}
},
title: "start_conversation".tr,
fontSize: 12,
child: SvgPicture.asset("assets/icons/message.svg"),
)
.paddingSymmetric(horizontal: 4)
.expanded(Responsive.isTablet() ? 1 : 5),
),
],
).paddingSymmetric(
vertical: Responsive.isTablet() ? 20 : 4,
horizontal: Responsive.isTablet() ? 40 : 10);
}),
const SizedBox(
height: 60,
height: 20,
),
// Row(
// children: [
// ButtonWidget(
// color: AppColors.callColor,
// haveIcon: true,
// onTap: () async {
// await UrlLauncherService.makePhoneCall(cardModel.phoneNumber);
// },
// title: "call_owner".tr,
// textColor: Colors.white,
// child: SvgPicture.asset(
// "assets/icons/phone.svg",
// colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
// ),
// ).paddingSymmetric(horizontal: 4).expanded(Responsive.isTablet() ? 1 : 5),
// ButtonWidget(
// color: AppColors.emailColor,
// haveIcon: true,
// onTap: () async {
// await UrlLauncherService.sendEmail(cardModel.user.email);
// },
// title: "email".tr,
// textColor: Colors.white,
// child: SvgPicture.asset("assets/icons/Email.svg"),
// ).paddingSymmetric(horizontal: 4).expanded(Responsive.isTablet() ? 1 : 5),
// if (Responsive.isTablet())
// Visibility(
// visible: chatController.chatUser.id != cardModel.user.chatUserId,
// child: Obx(() {
// return ButtonWidget(
// isLoading: chatController.createRoomState.loading,
// textColor: Colors.white,
// color: AppColors.messageColor,
// haveIcon: true,
// onTap: () {
// if (chatController.connectionState.value == SocketConnectionState.connected) {
// chatController.createRoom(
// chatUserId: cardModel.user.chatUserId,
// onSuccess: (room) {
// RoutingManager.to(RouteName.chatDetails, arguments: {
// "room": room,
// });
// });
// } else {
// Toast.showToast('you_have_no_internet_connection.'.tr);
// }
// },
// title: "start_conversation".tr,
// fontSize: 13,
// child: SvgPicture.asset("assets/icons/message.svg"),
// ).expanded(Responsive.isTablet() ? 1 : 5);
// }),
// ),
// if (Responsive.isTablet())
// Obx(() {
// return Visibility(
// visible: homeController.user.value!.id != cardModel.user.id,
// child: (homeController.currentCardAppointment.value != null)
// ? ButtonWidget(
// haveIcon: true,
// onTap: () {
// appointmentDialog(context);
// },
// fontSize: 13,
// color: AppColors.secondaryColor,
// title: 'you_have_an_appointment'.tr,
// child: const Icon(
// Icons.schedule,
// color: Colors.white,
// ),
// ).paddingSymmetric(horizontal: 4).expanded(Responsive.isTablet() ? 1 : 5)
// : ButtonWidget(
// onTap: () {
// cardController.getAvailableAppointments();
// appointmentSchedulingDialog(context);
// },
// haveIcon: true,
// fontSize: 12,
// title: 'schedule_an_appointment'.tr,
// color: AppColors.secondaryColor,
// child: const Icon(
// Icons.schedule,
// color: Colors.white,
// ),
// ).paddingSymmetric(horizontal: 4).expanded(Responsive.isTablet() ? 1 : 5),
// );
// }),
// ],
// ).paddingSymmetric(vertical: Responsive.isTablet() ? 20 : 4, horizontal: Responsive.isTablet() ? 40 : 10),
// if (!Responsive.isTablet())
// Obx(() {
// return Row(
// children: [
// Obx(() {
// return Visibility(
// visible: homeController.user.value!.id != cardModel.user.id,
// child: (homeController.currentCardAppointment.value != null)
// ? ButtonWidget(
// haveIcon: true,
// onTap: () {
// appointmentDialog(context);
// },
// fontSize: 12,
// color: AppColors.secondaryColor,
// title: 'you_have_an_appointment'.tr,
// child: const Icon(
// Icons.schedule,
// color: Colors.white,
// ),
// ).paddingSymmetric(horizontal: 4).expanded(Responsive.isTablet() ? 1 : 5)
// : ButtonWidget(
// onTap: () {
// cardController.getAvailableAppointments();
// appointmentSchedulingDialog(context);
// },
// haveIcon: true,
// fontSize: 12,
// title: 'schedule_an_appointment'.tr,
// color: AppColors.secondaryColor,
// child: const Icon(
// Icons.schedule,
// color: Colors.white,
// ),
// ).paddingSymmetric(horizontal: 4).expanded(Responsive.isTablet() ? 1 : 5),
// );
// }),
// Visibility(
// visible: chatController.chatUser.id != cardModel.user.chatUserId,
// child: ButtonWidget(
// isLoading: chatController.createRoomState.loading,
// textColor: Colors.white,
// color: AppColors.messageColor,
// haveIcon: true,
// onTap: () {
// if (chatController.connectionState.value == SocketConnectionState.connected) {
// chatController.createRoom(
// chatUserId: cardModel.user.chatUserId,
// onSuccess: (room) {
// RoutingManager.to(RouteName.chatDetails, arguments: {"room": room});
// });
// } else {
// Toast.showToast('you_have_no_internet_connection'.tr);
// }
// },
// title: "start_conversation".tr,
// fontSize: 12,
// child: SvgPicture.asset("assets/icons/message.svg"),
// ).paddingSymmetric(horizontal: 4).expanded(Responsive.isTablet() ? 1 : 5),
// ),
// ],
// ).paddingSymmetric(vertical: Responsive.isTablet() ? 20 : 4, horizontal: Responsive.isTablet() ? 40 : 10);
// }),
// const SizedBox(
// height: 60,
// ),
],
).paddingSymmetric(horizontal: Responsive.isTablet() ? 20 : 0)),
).makeSafeArea();
}
void appointmentSchedulingDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
contentPadding: EdgeInsets.zero,
actionsPadding: EdgeInsets.zero,
title: RegularTextWidget(
"available_times".tr,
fontSize: 14,
),
content: Obx(() {
if (cardController.availableAppointmentsState.loading ||
homeController.appointmentSchedulingState.loading) {
return SizedBox(width: 320, height: 320, child: const CircularProgressIndicator().center());
}
return SizedBox(
height: 320,
width: 320,
child: Column(
children: [
const SizedBox(
height: 20,
),
SizedBox(
height: 280,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: 12,
itemBuilder: (context, index) {
DateTime dateTime = Utils.generateRandomDateTime();
return AppointmentWidget(dateTime: dateTime).paddingOnly(bottom: 16).onTap(() {
homeController.scheduleAnAppointment(
Appointment(cardId: cardModel.id, dateTime: dateTime, user: homeController.user.value!),
onSuccess: () {
Toast.showToast('appointment_scheduled_successfully.'.tr);
RoutingManager.back();
});
});
},
).paddingOnly(left: 8, right: 8, top: 8, bottom: 8),
),
const SizedBox(
height: 20,
),
],
),
);
}),
);
});
}
void appointmentDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
contentPadding: EdgeInsets.zero,
actionsPadding: EdgeInsets.zero,
title: HeaderScreen(
' ${"appointment".tr}',
),
content: AppointmentDetails(appointment: homeController.currentCardAppointment.value!),
);
});
}
}

View File

@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/header_screen.dart';
import 'package:taafee_mobile/common/widgets/listview.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/feedback_widget.dart';
class FeedbackScreen extends StatelessWidget {
const FeedbackScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
HeaderScreen(
"Feedback",
).paddingOnly(top: 20),
SizedBox(
width: Get.width,
child: ListViewWidget(
itemCount: 10,
childBuilder: (index) {
return const FeedbackWidget();
}),
)
],
),
).makeSafeArea();
}
}

View File

@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/header_screen.dart';
class ImagesViewScreen extends StatelessWidget {
final List<String> images = [
"assets/images/download.jpg",
"assets/images/download.jpg",
"assets/images/download.jpg",
"assets/images/download.jpg",
"assets/images/download.jpg"
];
ImagesViewScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
HeaderScreen(
"Images",
).paddingOnly(top: 20),
Expanded(
child: SizedBox(
width: Get.width,
child: PageView.builder(
itemCount: images.length,
itemBuilder: (BuildContext context, index) {
return Container(
width: Get.width,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
images[index],
),
),
),
);
},
),
),
),
],
),
).makeSafeArea();
}
}

View File

@ -0,0 +1,85 @@
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:get/get.dart';
import 'package:taafee_mobile/common/const/const.dart';
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/button.dart';
import 'package:taafee_mobile/common/widgets/header_screen.dart';
import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/common/widgets/textfiled.dart';
import '../../../../core/routing/routing_manager.dart';
class ReviewFormScreen extends StatelessWidget {
const ReviewFormScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
HeaderScreen(
"Add Rating",
).paddingOnly(top: 20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const RegularTextWidget(
"Rate this user",
color: Colors.black,
),
const RegularTextWidget("What you think about this user?").paddingSymmetric(vertical: 10),
Container(
width: Get.width,
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.5),
borderRadius: BorderRadius.circular(20),
),
child: RatingBar.builder(
unratedColor: Colors.grey,
initialRating: 0,
minRating: 1,
itemSize: 40,
direction: Axis.horizontal,
allowHalfRating: false,
glow: false,
itemCount: 5,
// glowColor: ,
itemPadding: const EdgeInsets.symmetric(horizontal: 8.0),
itemBuilder: (context, _) => const Icon(
Icons.star_rounded,
color: Colors.amber,
),
onRatingUpdate: (rating) {},
),
),
TextFieldWidget(
maxLines: 7,
textInputAction: TextInputAction.newline,
onChange: (value) {},
keyboardType: TextInputType.multiline,
label: "",
validate: (value) {
return null;
},
height: Get.height * .3,
).paddingOnly(top: 30),
ButtonWidget(
onTap: () {
RoutingManager.back();
},
title: "Done",
width: Get.width * .3,
).center()
],
).paddingSymmetric(horizontal: 30, vertical: 20),
],
),
),
).makeSafeArea();
}
}

View File

@ -11,8 +11,7 @@ class CardServiceWidget extends StatelessWidget {
final HomeController homeController = Get.find<HomeController>();
final int maxLines;
final double? width;
CardServiceWidget(
{super.key, required this.cardModel, this.maxLines = 1, this.width});
CardServiceWidget({super.key, required this.cardModel, this.maxLines = 1, this.width});
@override
Widget build(BuildContext context) {
@ -20,18 +19,15 @@ class CardServiceWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
//mainAxisSize: MainAxisSize.min,
children: [
MediumTextWidget("${'service'.tr} : "),
MediumTextWidget("${'description'.tr} : "),
//width: Responsive.isTablet() ? Get.width * 0.3 : null,
SizedBox(
width: width ??
(Responsive.isTablet() ? Get.width * 0.3 : Get.width * 0.669),
width: width ?? (Responsive.isTablet() ? Get.width * 0.3 : Get.width * 0.65),
child: RegularTextWidget(
cardModel.services,
maxLines: maxLines,
textAlign: homeController.isArabic.value
? TextAlign.right
: TextAlign.left,
textAlign: homeController.isArabic.value ? TextAlign.right : TextAlign.left,
overflow: TextOverflow.ellipsis,
).paddingOnly(
right: Responsive.isTablet() ? 0 : 10,

View File

@ -0,0 +1,75 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:taafee_mobile/common/const/const.dart';
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/features/card/data_layer/model/card_model.dart';
import '../../../../core/url launcher/url_launcher_service.dart';
class ConsultationPriceWidget extends StatelessWidget {
final CardModel cardModel;
const ConsultationPriceWidget({
super.key,
required this.cardModel,
});
@override
Widget build(BuildContext context) {
return Container(
width: Get.width * .89,
height: 80,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RegularTextWidget(
"consultation price:".tr,
fontSize: 16,
color: Colors.grey,
),
BoldTextWidget(
"400 SP".tr,
fontSize: 20,
color: Colors.grey,
),
],
),
Row(
children: [
Container(
alignment: Alignment.center,
width: 90,
height: 35,
decoration: BoxDecoration(
color: AppColors.secondaryColor,
borderRadius: BorderRadius.circular(30),
),
child: const RegularTextWidget(
"Call",
color: Colors.white,
fontSize: 14,
),
).onTap(() async {
await UrlLauncherService.makePhoneCall(cardModel.phoneNumber);
}).paddingSymmetric(horizontal: 10),
SvgPicture.asset("assets/icons/whatsapp (1).svg").onTap(
() async {
await UrlLauncherService.sendWhatsapp("+963 940903459");
},
),
],
)
],
).paddingSymmetric(horizontal: 10),
);
}
}

View File

@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taafee_mobile/common/widgets/text.dart';
class FeedbackWidget extends StatelessWidget {
const FeedbackWidget({super.key});
@override
Widget build(BuildContext context) {
return const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
RegularTextWidget(
"Zakoor",
fontSize: 16,
),
RegularTextWidget(
"ggggggggggggggggggg",
fontSize: 14,
),
],
).paddingSymmetric(horizontal: 20, vertical: 8);
}
}

View File

@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/text.dart';
class ImageWidget extends StatelessWidget {
final int numberOfImages;
const ImageWidget({
super.key,
required this.numberOfImages,
});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 5),
width: Get.width * .2,
height: Get.width * .2,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: const DecorationImage(
image: AssetImage("assets/images/download.jpg"),
fit: BoxFit.cover,
),
),
child: numberOfImages > 4
? BoldTextWidget(
"+$numberOfImages",
fontSize: 24,
color: Colors.white,
).center()
: Container(),
);
}
}

View File

@ -20,8 +20,7 @@ class MyCardWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(
horizontal: Responsive.isTablet() ? 2 : 20, vertical: 10),
margin: EdgeInsets.symmetric(horizontal: Responsive.isTablet() ? 2 : 20, vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),

View File

@ -0,0 +1,244 @@
import 'dart:developer';
import 'package:animated_rating_stars/animated_rating_stars.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
import 'package:taafee_mobile/common/widgets/button.dart';
import 'package:taafee_mobile/common/widgets/text.dart';
import 'package:taafee_mobile/core/routing/routing_manager.dart';
import 'package:taafee_mobile/features/card/business_logic_layer/card_controller.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/star.dart';
import 'package:taafee_mobile/features/card/presentation_layer/widgets/view_ratings.dart';
import '../../../../common/const/const.dart';
import '../../../../common/widgets/textfiled.dart';
class RateWidget extends StatelessWidget {
final CardController cardController = Get.find<CardController>();
RateWidget({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: Get.width * .89,
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const RegularTextWidget("Rates"),
Container(
alignment: Alignment.center,
width: 100,
height: 25,
decoration: BoxDecoration(
color: AppColors.primeColor,
borderRadius: BorderRadius.circular(25),
),
child: RegularTextWidget(
"Rate Now".tr,
color: Colors.white,
),
).onTap(() {
RoutingManager.to(RouteName.reviewForm);
}),
],
).paddingSymmetric(horizontal: 20, vertical: 5),
const ViewRatingsWidget(),
],
),
// child: Column(
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Row(
// children: [
// RegularTextWidget("Number of users who rate this : ".tr),
// RegularTextWidget("10".tr),
// ],
// ),
// Container(
// alignment: Alignment.center,
// width: 100,
// height: 25,
// decoration: BoxDecoration(
// color: AppColors.primeColor,
// borderRadius: BorderRadius.circular(25),
// ),
// child: RegularTextWidget(
// "Rate Now".tr,
// color: Colors.white,
// ),
// ).onTap(() {
// dialog();
// cardController.currentIndex(0);
// })
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Column(
// children: [
// const Stack(
// alignment: Alignment.center,
// children: [
// StarWidget(maxRating: 1, starSize: 60, readOnly: true),
// RegularTextWidget(
// "2.5",
// color: Colors.black,
// ),
// ],
// ),
// RegularTextWidget("Waiting".tr),
// ],
// ),
// Column(
// children: [
// const Stack(
// alignment: Alignment.center,
// children: [
// StarWidget(maxRating: 1, starSize: 60, readOnly: true),
// RegularTextWidget(
// "2.5",
// color: Colors.black,
// ),
// ],
// ),
// RegularTextWidget("Performance".tr),
// ],
// ),
// Column(
// children: [
// const Stack(
// alignment: Alignment.center,
// children: [
// StarWidget(maxRating: 1, starSize: 60, readOnly: true),
// RegularTextWidget(
// "2.5",
// color: Colors.black,
// ),
// ],
// ),
// RegularTextWidget("Price".tr),
// ],
// )
// ],
// ).paddingOnly(top: 10).paddingSymmetric(horizontal: 20),
// ],
// ).paddingSymmetric(horizontal: 10, vertical: 10),
).onTap(() {
RoutingManager.to(RouteName.feedback);
log("message");
});
}
final PageController pageController = PageController();
final List<String> rate = [
"waiting?",
"Performance?",
"Price?",
"Feedback",
];
final List<Widget> stars = [
const StarWidget(maxRating: 5, starSize: 30, readOnly: false),
const StarWidget(maxRating: 5, starSize: 30, readOnly: false),
const StarWidget(maxRating: 5, starSize: 30, readOnly: false),
Container(
alignment: Alignment.topCenter,
width: Get.width * .5,
height: 55,
child: TextFormField(
onChanged: (value) {},
maxLines: 4,
textInputAction: TextInputAction.newline,
keyboardType: TextInputType.multiline,
),
),
// TextFieldWidget(
// keyboardType: TextInputType.multiline,
// label: "",
// onChange: (value) {},
// maxLines: 5,
// textInputAction: TextInputAction.newline,
// validate: (p0) {
// return null;
// },
// ),
];
void dialog() {
Get.defaultDialog(
onWillPop: () async {
cardController.currentIndex(0);
return true;
},
confirm: Obx(() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
RegularTextWidget(
"back".tr,
color: Colors.black,
).onTap(() {
if (cardController.currentIndex.value == 0) {
RoutingManager.back();
}
pageController.animateToPage(cardController.currentIndex.value - 1,
duration: const Duration(milliseconds: 250), curve: Curves.easeIn);
}),
ButtonWidget(
width: 80,
onTap: () {
if (cardController.currentIndex.value == 3) {
RoutingManager.back();
}
pageController.animateToPage(cardController.currentIndex.value + 1,
duration: const Duration(milliseconds: 250), curve: Curves.easeIn);
},
title: cardController.currentIndex.value == 3 ? "OK".tr : "Next".tr),
],
).paddingSymmetric(horizontal: 20);
}),
backgroundColor: Colors.white,
title: "",
middleText: "",
content: SizedBox(
width: Get.width * .5,
height: Get.height * .15,
child: PageView.builder(
physics: const BouncingScrollPhysics(),
controller: pageController,
onPageChanged: (value) {
cardController.changeCurrentIndex(value);
},
itemCount: 4,
itemBuilder: (BuildContext context, index) {
return Column(
children: [
BoldTextWidget(rate[index].tr).paddingOnly(bottom: 30),
stars[index],
// SizedBox(
// width: Get.width * .8,
// child: RegularTextWidget(
// textAlign: TextAlign.center,
// text[index].tr,
// color: Colors.black,
// ),
// )
],
);
},
),
));
}
}

View File

@ -0,0 +1,41 @@
import 'package:animated_rating_stars/animated_rating_stars.dart';
import 'package:flutter/material.dart';
class StarWidget extends StatelessWidget {
final double maxRating;
final double starSize;
final bool readOnly;
const StarWidget({
super.key,
required this.maxRating,
required this.starSize,
required this.readOnly,
});
@override
Widget build(BuildContext context) {
return AnimatedRatingStars(
initialRating: 1,
minRating: 0,
maxRating: maxRating,
filledColor: Colors.amber,
emptyColor: Colors.grey,
filledIcon: Icons.star_border_rounded,
halfFilledIcon: Icons.star_half_rounded,
emptyIcon: Icons.star_border_rounded,
onChanged: (double rating) {
// Handle the rating change here
print('Rating: $rating');
},
displayRatingValue: true,
interactiveTooltips: true,
customFilledIcon: Icons.star_border_rounded,
customHalfFilledIcon: Icons.star_half_rounded,
customEmptyIcon: Icons.star_border_rounded,
starSize: starSize,
animationDuration: const Duration(milliseconds: 300),
animationCurve: Curves.easeInOut,
readOnly: readOnly,
);
}
}

View File

@ -0,0 +1,85 @@
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:get/get.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:taafee_mobile/common/const/const.dart';
import 'package:taafee_mobile/common/widgets/listview.dart';
import 'package:taafee_mobile/common/widgets/text.dart';
class ViewRatingsWidget extends StatelessWidget {
const ViewRatingsWidget({super.key});
@override
Widget build(BuildContext context) {
return Row(
children: [
Column(
children: [
Container(
alignment: Alignment.center,
width: 75,
height: 75,
decoration: BoxDecoration(
color: AppColors.primeColor,
shape: BoxShape.circle,
),
child: const BoldTextWidget(
"5.0",
fontSize: 24,
color: Colors.white,
),
),
RatingBar.builder(
itemSize: 15,
initialRating: 3.5,
minRating: 1,
direction: Axis.horizontal,
allowHalfRating: true,
itemCount: 5,
itemPadding: const EdgeInsets.symmetric(horizontal: 2),
itemBuilder: (context, _) => const Icon(
Icons.star,
color: Colors.amber,
),
onRatingUpdate: (rating) {
print(rating);
},
ignoreGestures: true,
)
],
).paddingSymmetric(horizontal: 10),
Expanded(
child: Container(
child: ListViewWidget(
itemCount: 5,
childBuilder: (index) {
return Row(
children: [
Container(
width: 30,
alignment: Alignment.center,
child: RegularTextWidget(
(index + 1).toString(),
),
),
Expanded(
child: LinearPercentIndicator(
key: UniqueKey(),
animation: true,
// lineHeight: 10,
animationDuration: 600,
percent: 1,
backgroundColor: Colors.red,
progressColor: Colors.blue,
),
),
],
);
},
),
),
),
],
).paddingSymmetric(horizontal: 10, vertical: 10);
}
}

View File

@ -0,0 +1,83 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taafee_mobile/features/card/data_layer/model/working_time.dart';
import '../../../../common/const/const.dart';
import '../../../../common/widgets/listview.dart';
import '../../../../common/widgets/text.dart';
class WorkingTimeWidget extends StatelessWidget {
final List<WorkingTimeModel> list = [
WorkingTimeModel(type: "Sunday", startTime: "8:00", endTime: "10:00"),
WorkingTimeModel(type: "Monday", startTime: "8:00", endTime: "10:00"),
WorkingTimeModel(type: "Sunday", startTime: "8:00", endTime: "10:00"),
];
WorkingTimeWidget({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: Get.width * .89,
height: 270,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Stack(
children: [
const BoldTextWidget(
"working time",
color: Colors.grey,
).paddingSymmetric(horizontal: 20),
ListViewWidget(
physics: const BouncingScrollPhysics(),
itemCount: 8,
scrollDirection: Axis.horizontal,
childBuilder: (index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const RegularTextWidget("8:00"),
Expanded(
child: Container(
width: 1,
color: AppColors.dividerColor,
),
),
],
).paddingSymmetric(horizontal: 10);
}).paddingOnly(top: 25),
SizedBox(
width: Get.width * .89,
child: ListViewWidget(
itemCount: list.length,
childBuilder: (index) {
return SizedBox(
width: Get.width * .89,
height: 42,
child: ListViewWidget(
padding: const EdgeInsets.only(top: 20),
scrollDirection: Axis.horizontal,
itemCount: list.length,
childBuilder: (index) {
return Container(
alignment: Alignment.center,
margin: const EdgeInsets.symmetric(horizontal: 10),
width: 100,
decoration: BoxDecoration(
color: AppColors.secondaryColor,
borderRadius: BorderRadius.circular(25),
),
child: RegularTextWidget(
list[index].type,
color: Colors.white,
),
);
}),
);
}),
).paddingOnly(top: 30)
],
));
}
}

View File

@ -65,6 +65,11 @@ dependencies:
# firebase_core: ^2.15.1
# firebase_messaging: ^14.6.7
chat_bubbles: ^1.5.0
flutter_map: ^5.0.0
latlong2: ^0.9.0
animated_rating_stars: ^1.0.1
flutter_rating_bar: ^4.0.1
percent_indicator: ^4.2.3
dev_dependencies:
flutter_test: