commit
						cc6a48c52b
					
				| @ -0,0 +1,5 @@ | |||||||
|  | <svg width="15" height="18" viewBox="0 0 15 18" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  |     <path d="M14.3341 2.73593C13.3465 0.996493 11.1438 0.387116 9.41507 1.40204L1.9783 5.76797C0.259805 6.77686 -0.316545 8.99649 0.665687 10.7264C1.25916 11.7717 2.29147 12.4098 3.39807 12.5307C3.79951 12.5746 4.16073 12.2868 4.20487 11.888C4.24902 11.4891 3.95937 11.1302 3.55794 11.0864C2.90888 11.0155 2.2965 10.6413 1.93949 10.0125C1.34085 8.95816 1.70266 7.61757 2.7223 7.01897L5.81204 5.20506L6.50525 6.3668C6.7112 6.71196 7.15978 6.82588 7.50718 6.62126C7.85458 6.41663 7.96924 5.97095 7.76329 5.62579L7.07116 4.46586L10.1591 2.65303C11.1684 2.06046 12.4671 2.40504 13.0603 3.44987C13.5393 4.29342 13.4044 5.3279 12.8 6.01304C12.5338 6.31478 12.5642 6.7738 12.8679 7.03829C13.1716 7.30278 13.6336 7.27258 13.8998 6.97083C14.9042 5.83238 15.1252 4.1292 14.3341 2.73593Z" fill="#ED1C2B"/> | ||||||
|  |     <path d="M13.7153 8.93673C13.6985 9.04274 13.5953 9.10233 13.3889 9.22151L5.54435 13.7505C5.33793 13.8697 5.23473 13.9293 5.13452 13.8908C5.03432 13.8523 4.99968 13.7456 4.9304 13.5322C4.20822 11.3077 5.10997 8.80563 7.21681 7.58925C9.32364 6.37287 11.9414 6.84295 13.5068 8.58065C13.657 8.74735 13.732 8.83071 13.7153 8.93673Z" fill="#ED1C2B"/> | ||||||
|  |     <path d="M14.3613 10.0554C14.2611 10.017 14.1579 10.0765 13.9515 10.1957L6.10671 14.7249C5.90032 14.8441 5.79713 14.9036 5.78034 15.0096C5.76356 15.1156 5.83862 15.199 5.98875 15.3657C7.55409 17.1039 10.1722 17.5743 12.2793 16.3578C14.3864 15.1412 15.2881 12.6387 14.5654 10.4139C14.4961 10.2006 14.4615 10.0939 14.3613 10.0554Z" fill="#ED1C2B"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.6 KiB | 
| @ -0,0 +1,5 @@ | |||||||
|  | <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  |     <rect width="40" height="40" rx="10" fill="#EFEFF0"/> | ||||||
|  |     <path d="M23 14.75C22.3096 14.75 21.75 15.3096 21.75 16C21.75 16.6904 22.3096 17.25 23 17.25C23.6904 17.25 24.25 16.6904 24.25 16C24.25 15.3096 23.6904 14.75 23 14.75Z" fill="#8F9AA3"/> | ||||||
|  |     <path fill-rule="evenodd" clip-rule="evenodd" d="M9.25 20C9.25 14.0629 14.0629 9.25 20 9.25C25.9371 9.25 30.75 14.0629 30.75 20C30.75 25.9371 25.9371 30.75 20 30.75C14.0629 30.75 9.25 25.9371 9.25 20ZM20.25 16C20.25 14.4812 21.4812 13.25 23 13.25C24.5188 13.25 25.75 14.4812 25.75 16C25.75 17.5188 24.5188 18.75 23 18.75C21.4812 18.75 20.25 17.5188 20.25 16ZM13.6495 21.2591C14.432 22.1485 15.7722 21.7914 16.2203 20.7727L16.4401 21.021C16.7157 21.3343 17.1898 21.3619 17.499 21.0828C17.8082 20.8036 17.8355 20.3234 17.5599 20.0102L17.3505 19.7721C16.568 18.8827 15.2277 19.2399 14.7796 20.2586L14.5599 20.0102C14.2843 19.697 13.8103 19.6693 13.501 19.9485C13.1918 20.2276 13.1645 20.7078 13.4401 21.021L13.6495 21.2591ZM22.3872 22.2861C22.7816 22.4128 22.9986 22.8351 22.8719 23.2295L22.7611 23.5746C22.7375 23.638 22.7358 23.7627 22.9187 23.7545C24.1221 23.6247 25.0403 24.7168 24.6653 25.8844L24.5545 26.2295C24.4279 26.6239 24.0055 26.8409 23.6111 26.7143C23.2167 26.5876 22.9997 26.1653 23.1264 25.7709L23.2372 25.4258C23.2886 25.2656 23.1536 25.2391 23.0796 25.2459C21.8762 25.3757 20.958 24.2836 21.333 23.116L21.4438 22.7709C21.5704 22.3765 21.9928 22.1595 22.3872 22.2861ZM26.9955 20C26.4457 20 26 20.4477 26 21C26 21.5523 26.4457 22 26.9955 22H27.0045C27.5543 22 28 21.5523 28 21C28 20.4477 27.5543 20 27.0045 20H26.9955ZM16 25C16 24.4477 16.4457 24 16.9955 24H17.0045C17.5543 24 18 24.4477 18 25C18 25.5523 17.5543 26 17.0045 26H16.9955C16.4457 26 16 25.5523 16 25ZM15.9955 15C15.4457 15 15 15.4477 15 16C15 16.5523 15.4457 17 15.9955 17H16.0045C16.5543 17 17 16.5523 17 16C17 15.4477 16.5543 15 16.0045 15H15.9955Z" fill="#8F9AA3"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.0 KiB | 
| @ -0,0 +1,5 @@ | |||||||
|  | <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  |     <rect width="40" height="40" rx="10" fill="#EFEFF0"/> | ||||||
|  |     <path d="M20.75 12.5C20.75 12.0858 20.4142 11.75 20 11.75C19.5858 11.75 19.25 12.0858 19.25 12.5V13.25H18.5C18.0858 13.25 17.75 13.5858 17.75 14C17.75 14.4142 18.0858 14.75 18.5 14.75H19.25V15.5C19.25 15.9142 19.5858 16.25 20 16.25C20.4142 16.25 20.75 15.9142 20.75 15.5V14.75H21.5C21.9142 14.75 22.25 14.4142 22.25 14C22.25 13.5858 21.9142 13.25 21.5 13.25H20.75V12.5Z" fill="#8F9AA3"/> | ||||||
|  |     <path fill-rule="evenodd" clip-rule="evenodd" d="M19.948 9.25H20.052C20.9505 9.24997 21.6997 9.24995 22.2945 9.32991C22.9223 9.41432 23.4891 9.59999 23.9445 10.0555C24.4 10.5109 24.5857 11.0777 24.6701 11.7055C24.695 11.8911 24.7122 12.0917 24.724 12.3072C25.8622 12.4348 26.7867 12.726 27.506 13.4474C28.1807 14.1241 28.476 14.9793 28.6152 16.018C28.75 17.0237 28.75 18.3062 28.75 19.9137V28.75H29C29.5523 28.75 30 29.1977 30 29.75C30 30.3023 29.5523 30.75 29 30.75H11C10.4477 30.75 10 30.3023 10 29.75C10 29.1977 10.4477 28.75 11 28.75H11.25V19.9137C11.25 18.3062 11.25 17.0237 11.3848 16.018C11.524 14.9793 11.8193 14.1241 12.494 13.4474C13.2133 12.726 14.1378 12.4348 15.276 12.3072C15.2878 12.0917 15.305 11.8911 15.3299 11.7055C15.4143 11.0777 15.6 10.5109 16.0555 10.0555C16.5109 9.59999 17.0777 9.41432 17.7055 9.32991C18.3003 9.24995 19.0495 9.24997 19.948 9.25ZM17.9054 10.8165C17.4439 10.8786 17.2464 10.9858 17.1161 11.1161C16.9858 11.2464 16.8786 11.4439 16.8165 11.9054C16.7516 12.3884 16.75 13.036 16.75 14C16.75 14.964 16.7516 15.6116 16.8165 16.0946C16.8786 16.5561 16.9858 16.7536 17.1161 16.8839C17.2464 17.0142 17.4439 17.1214 17.9054 17.1835C18.3884 17.2484 19.036 17.25 20 17.25C20.964 17.25 21.6116 17.2484 22.0946 17.1835C22.5561 17.1214 22.7536 17.0142 22.8839 16.8839C23.0142 16.7536 23.1214 16.5561 23.1835 16.0946C23.2484 15.6116 23.25 14.964 23.25 14C23.25 13.036 23.2484 12.3884 23.1835 11.9054C23.1214 11.4439 23.0142 11.2464 22.8839 11.1161C22.7536 10.9858 22.5561 10.8786 22.0946 10.8165C21.6116 10.7516 20.964 10.75 20 10.75C19.036 10.75 18.3884 10.7516 17.9054 10.8165ZM23.25 28.75V27.4678C23.25 27.028 23.25 26.6486 23.2218 26.3374C23.192 26.0082 23.1259 25.6822 22.9486 25.375C22.7511 25.033 22.467 24.7489 22.125 24.5514C21.8178 24.3741 21.4918 24.308 21.1627 24.2782C20.8514 24.25 20.472 24.25 20.0323 24.25C19.5925 24.25 19.1486 24.25 18.8374 24.2782C18.5082 24.308 18.1822 24.3741 17.875 24.5514C17.533 24.7489 17.2489 25.033 17.0514 25.375C16.8741 25.6822 16.808 26.0082 16.7782 26.3374C16.75 26.6486 16.75 27.028 16.75 27.4677V28.75H18.25V27.5C18.25 27.0189 18.2507 26.7082 18.2721 26.4727C18.3015 26.2392 18.4223 25.7721 18.9727 25.7721C19.2082 25.7507 19.5189 25.75 20 25.75C20.4811 25.75 20.7918 25.7507 21.0273 25.7721C21.2608 25.7843 21.7279 25.9415 21.7279 26.4727C21.7493 26.7082 21.75 27.0189 21.75 27.5V28.75H23.25ZM15 21C15 20.4477 15.4477 20 16 20H16.009C16.5612 20 17.009 20.4477 17.009 21C17.009 21.5523 16.5612 22 16.009 22H16C15.4477 22 15 21.5523 15 21ZM18.991 21C18.991 20.4477 19.4388 20 19.991 20H20C20.5523 20 21 20.4477 21 21C21 21.5523 20.5523 22 20 22H19.991C19.4388 22 18.991 21.5523 18.991 21ZM22.9922 21C22.9922 20.4477 23.4399 20 23.9922 20H24.0011C24.5534 20 25.0011 20.4477 25.0011 21C25.0011 21.5523 24.5534 22 24.0011 22H23.9922C23.4399 22 22.9922 21.5523 22.9922 21Z" fill="#8F9AA3"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 3.3 KiB | 
| @ -0,0 +1,5 @@ | |||||||
|  | <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  |     <rect width="40" height="40" rx="10" fill="#EFEFF0"/> | ||||||
|  |     <path d="M18.5303 20.4696C18.3897 20.329 18.1989 20.25 18 20.25C17.7425 20.25 17.4921 20.25 17.25 20.2507V24.3535C18.4043 24.6799 19.25 25.7412 19.25 27V28C19.25 28.4142 18.9142 28.75 18.5 28.75C18.0858 28.75 17.75 28.4142 17.75 28V27C17.75 26.3096 17.1904 25.75 16.5 25.75C15.8096 25.75 15.25 26.3096 15.25 27V28C15.25 28.4142 14.9142 28.75 14.5 28.75C14.0858 28.75 13.75 28.4142 13.75 28V27C13.75 25.7412 14.5957 24.6799 15.75 24.3535V20.2764C15.3284 20.2933 14.9463 20.321 14.6083 20.3665C13.7081 20.4875 12.9503 20.7464 12.3484 21.3483C11.7464 21.9502 11.4875 22.7081 11.3665 23.6082C11.25 24.4752 11.25 25.5775 11.25 26.9451V30C11.25 30.4142 11.5858 30.75 12 30.75H28C28.4142 30.75 28.75 30.4142 28.75 30V26.9451C28.75 25.5775 28.75 24.4752 28.6335 23.6082C28.5125 22.7081 28.2536 21.9502 27.6517 21.3483C27.0497 20.7464 26.2919 20.4875 25.3918 20.3665C25.1928 20.3397 24.9786 20.3191 24.75 20.3033V25.9506C25.1984 26.21 25.5 26.6948 25.5 27.25C25.5 28.0784 24.8284 28.75 24 28.75C23.1716 28.75 22.5 28.0784 22.5 27.25C22.5 26.6948 22.8017 26.21 23.25 25.9506V20.2538C22.8569 20.25 22.4396 20.25 22.0005 20.25C21.8016 20.25 21.6103 20.329 21.4697 20.4696L20 21.9393L18.5303 20.4696Z" fill="#8F9AA3"/> | ||||||
|  |     <path d="M20 9.25C17.6528 9.25 15.75 11.1528 15.75 13.5V14.5C15.75 16.8472 17.6528 18.75 20 18.75C22.3472 18.75 24.25 16.8472 24.25 14.5V13.5C24.25 11.1528 22.3472 9.25 20 9.25Z" fill="#8F9AA3"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.5 KiB | 
| @ -0,0 +1,5 @@ | |||||||
|  | <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  |     <rect width="40" height="40" rx="10" fill="#EFEFF0"/> | ||||||
|  |     <path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 17.5869C11.75 13.0186 15.5222 9.25 20 9.25C24.4778 9.25 28.25 13.0186 28.25 17.5869C28.25 22.2513 24.4018 25.4121 21.1696 27.4294L21.1583 27.4365L21.1467 27.4431C20.7978 27.644 20.4026 27.75 20 27.75C19.5974 27.75 19.2022 27.644 18.8533 27.4431L18.84 27.4355L18.8271 27.4273C15.6075 25.3945 11.75 22.2671 11.75 17.5869ZM16.5 17.5C16.5 15.567 18.067 14 20 14C21.933 14 23.5 15.567 23.5 17.5C23.5 19.433 21.933 21 20 21C18.067 21 16.5 19.433 16.5 17.5Z" fill="#8F9AA3"/> | ||||||
|  |     <path d="M14.9958 27.6578C14.9493 27.1487 14.5212 26.75 14 26.75C13.4477 26.75 13 27.1977 13 27.75C13 28.4639 13.4349 28.9848 13.8525 29.3139C14.2814 29.6519 14.84 29.9125 15.4411 30.1129C16.6538 30.5171 18.2656 30.75 20 30.75C21.7344 30.75 23.3462 30.5171 24.5589 30.1129C25.16 29.9125 25.7186 29.6519 26.1475 29.3139C26.5651 28.9848 27 28.4639 27 27.75C27 27.1977 26.5523 26.75 26 26.75C25.4788 26.75 25.0507 27.1487 25.0042 27.6578C24.9869 27.6768 24.9574 27.7053 24.9095 27.7431C24.7311 27.8836 24.4111 28.054 23.9264 28.2155C22.9675 28.5352 21.5793 28.75 20 28.75C18.4207 28.75 17.0325 28.5352 16.0736 28.2155C15.5889 28.054 15.2689 27.8836 15.0905 27.7431C15.0426 27.7053 15.0131 27.6768 14.9958 27.6578Z" fill="#8F9AA3"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.4 KiB | 
| @ -0,0 +1,4 @@ | |||||||
|  | <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  |     <rect width="40" height="40" rx="10" fill="#EFEFF0"/> | ||||||
|  |     <path fill-rule="evenodd" clip-rule="evenodd" d="M25.0357 9.25C25.5617 9.25 25.9881 9.67639 25.9881 10.2024C25.9881 10.7417 25.9966 10.8274 26.0161 10.8959C26.0315 10.9499 26.0531 11.0019 26.0803 11.051C26.115 11.1132 26.1696 11.1798 26.551 11.5612L28.4388 13.449C28.8202 13.8304 28.8868 13.885 28.949 13.9197C28.9981 13.9469 29.0501 13.9685 29.1041 13.9839C29.1726 14.0034 29.2583 14.0119 29.7976 14.0119C30.3236 14.0119 30.75 14.4383 30.75 14.9643C30.75 15.4902 30.3236 15.9166 29.7976 15.9166C29.3989 15.9172 28.94 15.9177 28.5819 15.8157C28.3873 15.7602 28.1998 15.6825 28.023 15.5841C27.897 15.5141 27.7805 15.4317 27.6686 15.3406L25.0402 18.626L26.7071 20.2929C27.0976 20.6834 27.0976 21.3166 26.7071 21.7071C26.3166 22.0976 25.6834 22.0976 25.2929 21.7071L24.9767 21.3909L20.5751 25.7925C20.066 26.3015 19.6441 26.7235 19.2685 27.0298C18.8764 27.3495 18.4719 27.5972 17.9834 27.6944C17.6106 27.7685 17.2268 27.7685 16.8541 27.6944C16.7033 27.6644 16.5606 27.6201 16.4238 27.5638L15.3831 28.3071C15.1732 28.4571 14.962 28.6081 14.7694 28.7193C14.5522 28.8447 14.2807 28.9677 13.9455 28.9941C13.9025 28.9975 13.8594 28.9981 13.8163 28.9959C13.522 28.981 13.1623 28.8608 12.7837 28.6305L10.9571 30.4571C10.5666 30.8476 9.93342 30.8476 9.54289 30.4571C9.15237 30.0666 9.15237 29.4334 9.54289 29.0429L11.3713 27.2145C11.2346 26.9877 11.1412 26.775 11.083 26.5884C11.0343 26.4305 10.9655 26.0271 11.0801 25.6775C11.1948 25.3122 11.4474 24.96 11.6601 24.6638L12.4366 23.577C12.3801 23.44 12.3357 23.297 12.3056 23.146C12.2315 22.7732 12.2315 22.3894 12.3056 22.0166C12.4028 21.5281 12.6505 21.1237 12.9702 20.7315C13.2765 20.3559 13.6984 19.934 14.2075 19.4249L18.6091 15.0233L18.2929 14.7071C17.9024 14.3166 17.9024 13.6834 18.2929 13.2929C18.6834 12.9024 19.3166 12.9024 19.7071 13.2929L21.374 14.9598L24.6594 12.3314C24.5683 12.2195 24.4859 12.103 24.4159 11.9771C24.3175 11.8002 24.2398 11.6127 24.1843 11.4181C24.0823 11.06 24.0828 10.6011 24.0834 10.2024C24.0834 9.67639 24.5098 9.25 25.0357 9.25ZM22.7291 16.3149L23.6851 17.2709L26.2992 14.0032L25.9968 13.7008L22.7291 16.3149ZM13.7094 25.2359C13.8843 25.4145 14.071 25.6012 14.2623 25.7925C14.4395 25.9697 14.6064 26.1365 14.7642 26.2914L14.2498 26.6589C14.0609 26.7938 13.9399 26.8794 13.8497 26.9378C13.7418 26.8755 13.5895 26.7678 13.4111 26.5894C13.2332 26.4115 13.1263 26.2573 13.0645 26.1483C13.1271 26.0517 13.2127 25.9314 13.3417 25.7508L13.7094 25.2359Z" fill="#8F9AA3"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.5 KiB | 
| @ -0,0 +1,17 @@ | |||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/services/error_handler_service.dart'; | ||||||
|  | 
 | ||||||
|  | class BookAppointmentsViewModel extends ChangeNotifier { | ||||||
|  |   int selectedTabIndex = 0; | ||||||
|  | 
 | ||||||
|  |   BookAppointmentsRepo bookAppointmentsRepo; | ||||||
|  |   ErrorHandlerService errorHandlerService; | ||||||
|  | 
 | ||||||
|  |   BookAppointmentsViewModel({required this.bookAppointmentsRepo, required this.errorHandlerService}); | ||||||
|  | 
 | ||||||
|  |   void onTabChanged(int index) { | ||||||
|  |     selectedTabIndex = index; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -1,5 +1,5 @@ | |||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:hmg_patient_app_new/features/habib_wallet/models/habib_wallet_repo.dart'; | import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_repo.dart'; | ||||||
| import 'package:hmg_patient_app_new/services/error_handler_service.dart'; | import 'package:hmg_patient_app_new/services/error_handler_service.dart'; | ||||||
| 
 | 
 | ||||||
| class HabibWalletViewModel extends ChangeNotifier { | class HabibWalletViewModel extends ChangeNotifier { | ||||||
| @ -0,0 +1,270 @@ | |||||||
|  | import 'package:dartz/dartz.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/api/api_client.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/api_consts.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/date_util.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/services/logger_service.dart'; | ||||||
|  | 
 | ||||||
|  | import '../authentication/models/resp_models/authenticated_user_resp_model.dart'; | ||||||
|  | 
 | ||||||
|  | abstract class MedicalFileRepo { | ||||||
|  |   Future<Either<Failure, GenericApiModel<List<PatientVaccineResponseModel>>>> getPatientVaccinesList(); | ||||||
|  | 
 | ||||||
|  |   Future<Either<Failure, GenericApiModel<List<PatientSickLeavesResponseModel>>>> getPatientSickLeavesList(); | ||||||
|  | 
 | ||||||
|  |   Future<Either<Failure, GenericApiModel<dynamic>>> getPatientSickLeavePDF(PatientSickLeavesResponseModel patientSickLeavesResponseModel, AuthenticatedUser authenticatedUser); | ||||||
|  | 
 | ||||||
|  |   Future<Either<Failure, GenericApiModel<List<PatientMedicalReportResponseModel>>>> getPatientMedicalReportsList(); | ||||||
|  | 
 | ||||||
|  |   Future<Either<Failure, GenericApiModel<dynamic>>> getPatientMedicalReportPDF(PatientMedicalReportResponseModel patientMedicalReportResponseModel, AuthenticatedUser authenticatedUser); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class MedicalFileRepoImp implements MedicalFileRepo { | ||||||
|  |   final ApiClient apiClient; | ||||||
|  |   final LoggerService loggerService; | ||||||
|  | 
 | ||||||
|  |   MedicalFileRepoImp({required this.loggerService, required this.apiClient}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Future<Either<Failure, GenericApiModel<List<PatientVaccineResponseModel>>>> getPatientVaccinesList() async { | ||||||
|  |     Map<String, dynamic> mapDevice = {"To": "0", "From": "0"}; | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       GenericApiModel<List<PatientVaccineResponseModel>>? apiResponse; | ||||||
|  |       Failure? failure; | ||||||
|  |       await apiClient.post( | ||||||
|  |         GET_VACCINES, | ||||||
|  |         body: mapDevice, | ||||||
|  |         onFailure: (error, statusCode, {messageStatus, failureType}) { | ||||||
|  |           failure = failureType; | ||||||
|  |         }, | ||||||
|  |         onSuccess: (response, statusCode, {messageStatus, errorMessage}) { | ||||||
|  |           try { | ||||||
|  |             final list = response['List_DoneVaccines']; | ||||||
|  |             // if (list == null || list.isEmpty) { | ||||||
|  |             //   throw Exception("lab list is empty"); | ||||||
|  |             // } | ||||||
|  | 
 | ||||||
|  |             final vaccinesList = list.map((item) => PatientVaccineResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<PatientVaccineResponseModel>(); | ||||||
|  | 
 | ||||||
|  |             apiResponse = GenericApiModel<List<PatientVaccineResponseModel>>( | ||||||
|  |               messageStatus: messageStatus, | ||||||
|  |               statusCode: statusCode, | ||||||
|  |               errorMessage: null, | ||||||
|  |               data: vaccinesList, | ||||||
|  |             ); | ||||||
|  |           } catch (e) { | ||||||
|  |             failure = DataParsingFailure(e.toString()); | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |       ); | ||||||
|  |       if (failure != null) return Left(failure!); | ||||||
|  |       if (apiResponse == null) return Left(ServerFailure("Unknown error")); | ||||||
|  |       return Right(apiResponse!); | ||||||
|  |     } catch (e) { | ||||||
|  |       return Left(UnknownFailure(e.toString())); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Future<Either<Failure, GenericApiModel<List<PatientSickLeavesResponseModel>>>> getPatientSickLeavesList() async { | ||||||
|  |     Map<String, dynamic> mapDevice = {}; | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       GenericApiModel<List<PatientSickLeavesResponseModel>>? apiResponse; | ||||||
|  |       Failure? failure; | ||||||
|  |       await apiClient.post( | ||||||
|  |         GET_PATIENT_SICK_LEAVE_STATUS, | ||||||
|  |         body: mapDevice, | ||||||
|  |         onFailure: (error, statusCode, {messageStatus, failureType}) { | ||||||
|  |           failure = failureType; | ||||||
|  |         }, | ||||||
|  |         onSuccess: (response, statusCode, {messageStatus, errorMessage}) { | ||||||
|  |           try { | ||||||
|  |             final list = response['List_SickLeave']; | ||||||
|  |             // if (list == null || list.isEmpty) { | ||||||
|  |             //   throw Exception("lab list is empty"); | ||||||
|  |             // } | ||||||
|  | 
 | ||||||
|  |             final vaccinesList = list.map((item) => PatientSickLeavesResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<PatientSickLeavesResponseModel>(); | ||||||
|  | 
 | ||||||
|  |             apiResponse = GenericApiModel<List<PatientSickLeavesResponseModel>>( | ||||||
|  |               messageStatus: messageStatus, | ||||||
|  |               statusCode: statusCode, | ||||||
|  |               errorMessage: null, | ||||||
|  |               data: vaccinesList, | ||||||
|  |             ); | ||||||
|  |           } catch (e) { | ||||||
|  |             failure = DataParsingFailure(e.toString()); | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |       ); | ||||||
|  |       if (failure != null) return Left(failure!); | ||||||
|  |       if (apiResponse == null) return Left(ServerFailure("Unknown error")); | ||||||
|  |       return Right(apiResponse!); | ||||||
|  |     } catch (e) { | ||||||
|  |       return Left(UnknownFailure(e.toString())); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Future<Either<Failure, GenericApiModel>> getPatientSickLeavePDF(PatientSickLeavesResponseModel patientSickLeavesResponseModel, AuthenticatedUser authenticatedUser) async { | ||||||
|  |     Map<String, dynamic> mapDevice = { | ||||||
|  |       "RequestNo": patientSickLeavesResponseModel.requestNo, | ||||||
|  |       "To": authenticatedUser.emailAddress, | ||||||
|  |       "DateofBirth": authenticatedUser.dateofBirth, | ||||||
|  |       "PatientIditificationNum": authenticatedUser.patientIdentificationNo, | ||||||
|  |       "PatientMobileNumber": authenticatedUser.mobileNumber, | ||||||
|  |       "PatientName": "${authenticatedUser.firstName!} ${authenticatedUser.lastName!}", | ||||||
|  |       "ProjectName": patientSickLeavesResponseModel.projectName, | ||||||
|  |       "DoctorName": patientSickLeavesResponseModel.doctorName, | ||||||
|  |       "ProjectID": patientSickLeavesResponseModel.projectID, | ||||||
|  |       "SetupID": patientSickLeavesResponseModel.setupID, | ||||||
|  |       "IsDownload": true, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       GenericApiModel<dynamic>? apiResponse; | ||||||
|  |       Failure? failure; | ||||||
|  |       await apiClient.post( | ||||||
|  |         SendSickLeaveEmail, | ||||||
|  |         body: mapDevice, | ||||||
|  |         onFailure: (error, statusCode, {messageStatus, failureType}) { | ||||||
|  |           failure = failureType; | ||||||
|  |         }, | ||||||
|  |         onSuccess: (response, statusCode, {messageStatus, errorMessage}) { | ||||||
|  |           try { | ||||||
|  |             // final list = response['List_SickLeave']; | ||||||
|  |             // if (list == null || list.isEmpty) { | ||||||
|  |             //   throw Exception("lab list is empty"); | ||||||
|  |             // } | ||||||
|  | 
 | ||||||
|  |             // final vaccinesList = list.map((item) => PatientSickLeavesResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<PatientSickLeavesResponseModel>(); | ||||||
|  | 
 | ||||||
|  |             apiResponse = GenericApiModel<dynamic>( | ||||||
|  |               messageStatus: messageStatus, | ||||||
|  |               statusCode: statusCode, | ||||||
|  |               errorMessage: null, | ||||||
|  |               data: response["Base64Data"], | ||||||
|  |             ); | ||||||
|  |           } catch (e) { | ||||||
|  |             failure = DataParsingFailure(e.toString()); | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |       ); | ||||||
|  |       if (failure != null) return Left(failure!); | ||||||
|  |       if (apiResponse == null) return Left(ServerFailure("Unknown error")); | ||||||
|  |       return Right(apiResponse!); | ||||||
|  |     } catch (e) { | ||||||
|  |       return Left(UnknownFailure(e.toString())); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Future<Either<Failure, GenericApiModel<List<PatientMedicalReportResponseModel>>>> getPatientMedicalReportsList() async { | ||||||
|  |     Map<String, dynamic> mapDevice = { | ||||||
|  |       "IsReport": true, | ||||||
|  |       "EncounterType": 1, | ||||||
|  |       "RequestType": 1, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       GenericApiModel<List<PatientMedicalReportResponseModel>>? apiResponse; | ||||||
|  |       Failure? failure; | ||||||
|  |       await apiClient.post( | ||||||
|  |         REPORTS, | ||||||
|  |         body: mapDevice, | ||||||
|  |         onFailure: (error, statusCode, {messageStatus, failureType}) { | ||||||
|  |           failure = failureType; | ||||||
|  |         }, | ||||||
|  |         onSuccess: (response, statusCode, {messageStatus, errorMessage}) { | ||||||
|  |           try { | ||||||
|  |             final list = response['GetPatientMedicalStatus']; | ||||||
|  |             // if (list == null || list.isEmpty) { | ||||||
|  |             //   throw Exception("lab list is empty"); | ||||||
|  |             // } | ||||||
|  | 
 | ||||||
|  |             final vaccinesList = list.map((item) => PatientMedicalReportResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<PatientMedicalReportResponseModel>(); | ||||||
|  | 
 | ||||||
|  |             apiResponse = GenericApiModel<List<PatientMedicalReportResponseModel>>( | ||||||
|  |               messageStatus: messageStatus, | ||||||
|  |               statusCode: statusCode, | ||||||
|  |               errorMessage: null, | ||||||
|  |               data: vaccinesList, | ||||||
|  |             ); | ||||||
|  |           } catch (e) { | ||||||
|  |             failure = DataParsingFailure(e.toString()); | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |       ); | ||||||
|  |       if (failure != null) return Left(failure!); | ||||||
|  |       if (apiResponse == null) return Left(ServerFailure("Unknown error")); | ||||||
|  |       return Right(apiResponse!); | ||||||
|  |     } catch (e) { | ||||||
|  |       return Left(UnknownFailure(e.toString())); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Future<Either<Failure, GenericApiModel>> getPatientMedicalReportPDF(PatientMedicalReportResponseModel patientMedicalReportResponseModel, AuthenticatedUser authenticatedUser) async { | ||||||
|  |     Map<String, dynamic> mapDevice = { | ||||||
|  |       "SetupID": patientMedicalReportResponseModel.setupId, | ||||||
|  |       "PrintDate": patientMedicalReportResponseModel.requestDate!, | ||||||
|  |       "ProcedureID": "05005009", | ||||||
|  |       "Reporttype": "MEDICAL REPORT", | ||||||
|  |       "stamp": patientMedicalReportResponseModel.requestDate!, | ||||||
|  |       "To": authenticatedUser.emailAddress, | ||||||
|  |       "DateofBirth": authenticatedUser.dateofBirth, | ||||||
|  |       "PatientIditificationNum": authenticatedUser.patientIdentificationNo, | ||||||
|  |       "PatientMobileNumber": authenticatedUser.mobileNumber, | ||||||
|  |       "PatientName": "${authenticatedUser.firstName!} ${authenticatedUser.lastName!}", | ||||||
|  |       "ProjectName": patientMedicalReportResponseModel.projectName, | ||||||
|  |       "ClinicName": patientMedicalReportResponseModel.clinicDescription, | ||||||
|  |       "ProjectID": patientMedicalReportResponseModel.projectID, | ||||||
|  |       "InvoiceNo": Utils.isVidaPlusProject(patientMedicalReportResponseModel.projectID!) ? patientMedicalReportResponseModel.invoiceNoVP : patientMedicalReportResponseModel.invoiceNo, | ||||||
|  |       "InvoiceNo_VP": Utils.isVidaPlusProject(patientMedicalReportResponseModel.projectID!) ? patientMedicalReportResponseModel.invoiceNoVP : patientMedicalReportResponseModel.invoiceNo, | ||||||
|  |       "PrintedByName": "${authenticatedUser.firstName!} ${authenticatedUser.lastName!}", | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       GenericApiModel<dynamic>? apiResponse; | ||||||
|  |       Failure? failure; | ||||||
|  |       await apiClient.post( | ||||||
|  |         GET_MEDICAL_REPORT_PDF, | ||||||
|  |         body: mapDevice, | ||||||
|  |         onFailure: (error, statusCode, {messageStatus, failureType}) { | ||||||
|  |           failure = failureType; | ||||||
|  |         }, | ||||||
|  |         onSuccess: (response, statusCode, {messageStatus, errorMessage}) { | ||||||
|  |           try { | ||||||
|  |             // final list = response['List_SickLeave']; | ||||||
|  |             // if (list == null || list.isEmpty) { | ||||||
|  |             //   throw Exception("lab list is empty"); | ||||||
|  |             // } | ||||||
|  | 
 | ||||||
|  |             // final vaccinesList = list.map((item) => PatientSickLeavesResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<PatientSickLeavesResponseModel>(); | ||||||
|  | 
 | ||||||
|  |             apiResponse = GenericApiModel<dynamic>( | ||||||
|  |               messageStatus: messageStatus, | ||||||
|  |               statusCode: statusCode, | ||||||
|  |               errorMessage: null, | ||||||
|  |               data: response["MedicalReportBase64"], | ||||||
|  |             ); | ||||||
|  |           } catch (e) { | ||||||
|  |             failure = DataParsingFailure(e.toString()); | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |       ); | ||||||
|  |       if (failure != null) return Left(failure!); | ||||||
|  |       if (apiResponse == null) return Left(ServerFailure("Unknown error")); | ||||||
|  |       return Right(apiResponse!); | ||||||
|  |     } catch (e) { | ||||||
|  |       return Left(UnknownFailure(e.toString())); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -1,12 +1,220 @@ | |||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/services/error_handler_service.dart'; | ||||||
| 
 | 
 | ||||||
| class MedicalFileViewModel extends ChangeNotifier { | class MedicalFileViewModel extends ChangeNotifier { | ||||||
| 
 |  | ||||||
|   int selectedTabIndex = 0; |   int selectedTabIndex = 0; | ||||||
|  |   bool isPatientVaccineListLoading = false; | ||||||
|  |   bool isPatientSickLeaveListLoading = false; | ||||||
|  |   bool isPatientSickLeavePDFLoading = false; | ||||||
|  |   bool isPatientMedicalReportsListLoading = false; | ||||||
|  | 
 | ||||||
|  |   MedicalFileRepo medicalFileRepo; | ||||||
|  |   ErrorHandlerService errorHandlerService; | ||||||
|  | 
 | ||||||
|  |   List<PatientVaccineResponseModel> patientVaccineList = []; | ||||||
|  |   List<PatientSickLeavesResponseModel> patientSickLeaveList = []; | ||||||
|  | 
 | ||||||
|  |   List<PatientMedicalReportResponseModel> patientMedicalReportList = []; | ||||||
|  | 
 | ||||||
|  |   List<PatientMedicalReportResponseModel> patientMedicalReportRequestedList = []; | ||||||
|  |   List<PatientMedicalReportResponseModel> patientMedicalReportReadyList = []; | ||||||
|  |   List<PatientMedicalReportResponseModel> patientMedicalReportCancelledList = []; | ||||||
|  | 
 | ||||||
|  |   String patientSickLeavePDFBase64 = ""; | ||||||
|  |   String patientMedicalReportPDFBase64 = ""; | ||||||
|  | 
 | ||||||
|  |   int selectedMedicalReportsTabIndex = 0; | ||||||
|  | 
 | ||||||
|  |   MedicalFileViewModel({required this.medicalFileRepo, required this.errorHandlerService}); | ||||||
|  | 
 | ||||||
|  |   initMedicalFileProvider() { | ||||||
|  |     isPatientVaccineListLoading = true; | ||||||
|  |     isPatientMedicalReportsListLoading = true; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   void onMedicalReportTabChange(int index) { | ||||||
|  |     selectedMedicalReportsTabIndex = index; | ||||||
|  |     if (index == 0) { | ||||||
|  |       patientMedicalReportList = patientMedicalReportRequestedList; | ||||||
|  |     } else if (index == 1) { | ||||||
|  |       patientMedicalReportList = patientMedicalReportReadyList; | ||||||
|  |     } else if (index == 2) { | ||||||
|  |       patientMedicalReportList = patientMedicalReportCancelledList; | ||||||
|  |     } | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   setIsPatientVaccineListLoading(bool isLoading) { | ||||||
|  |     isPatientVaccineListLoading = isLoading; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   setIsPatientSickLeavePDFLoading(bool isLoading) { | ||||||
|  |     isPatientSickLeavePDFLoading = isLoading; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   setIsPatientSickLeaveListLoading(bool val) { | ||||||
|  |     if (val) { | ||||||
|  |       patientSickLeaveList.clear(); | ||||||
|  |       patientSickLeavePDFBase64 = ""; | ||||||
|  |     } | ||||||
|  |     isPatientSickLeaveListLoading = val; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   setIsPatientMedicalReportsLoading(bool val) { | ||||||
|  |     if (val) { | ||||||
|  |       patientMedicalReportList.clear(); | ||||||
|  |       patientMedicalReportPDFBase64 = ""; | ||||||
|  |     } | ||||||
|  |     isPatientMedicalReportsListLoading = val; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   void onTabChanged(int index) { |   void onTabChanged(int index) { | ||||||
|     selectedTabIndex = index; |     selectedTabIndex = index; | ||||||
|     notifyListeners(); |     notifyListeners(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   Future<void> getPatientVaccinesList({Function(dynamic)? onSuccess, Function(String)? onError}) async { | ||||||
|  |     patientVaccineList.clear(); | ||||||
|  |     final result = await medicalFileRepo.getPatientVaccinesList(); | ||||||
|  | 
 | ||||||
|  |     result.fold( | ||||||
|  |       (failure) async => await errorHandlerService.handleError( | ||||||
|  |         failure: failure, | ||||||
|  |         onOkPressed: () { | ||||||
|  |           onError!(failure.message); | ||||||
|  |         }, | ||||||
|  |       ), | ||||||
|  |       (apiResponse) { | ||||||
|  |         if (apiResponse.messageStatus == 2) { | ||||||
|  |           // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); | ||||||
|  |         } else if (apiResponse.messageStatus == 1) { | ||||||
|  |           patientVaccineList = apiResponse.data!; | ||||||
|  |           isPatientVaccineListLoading = false; | ||||||
|  |           notifyListeners(); | ||||||
|  |           if (onSuccess != null) { | ||||||
|  |             onSuccess(apiResponse); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Future<void> getPatientSickLeaveList({Function(dynamic)? onSuccess, Function(String)? onError}) async { | ||||||
|  |     patientSickLeaveList.clear(); | ||||||
|  |     final result = await medicalFileRepo.getPatientSickLeavesList(); | ||||||
|  | 
 | ||||||
|  |     result.fold( | ||||||
|  |       (failure) async => await errorHandlerService.handleError( | ||||||
|  |         failure: failure, | ||||||
|  |         onOkPressed: () { | ||||||
|  |           onError!(failure.message); | ||||||
|  |         }, | ||||||
|  |       ), | ||||||
|  |       (apiResponse) { | ||||||
|  |         if (apiResponse.messageStatus == 2) { | ||||||
|  |           // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); | ||||||
|  |         } else if (apiResponse.messageStatus == 1) { | ||||||
|  |           patientSickLeaveList = apiResponse.data!; | ||||||
|  |           isPatientSickLeaveListLoading = false; | ||||||
|  |           notifyListeners(); | ||||||
|  |           if (onSuccess != null) { | ||||||
|  |             onSuccess(apiResponse); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Future<void> getPatientSickLeavePDF(PatientSickLeavesResponseModel patientSickLeavesResponseModel, AuthenticatedUser authenticatedUser, | ||||||
|  |       {Function(dynamic)? onSuccess, Function(String)? onError}) async { | ||||||
|  |     final result = await medicalFileRepo.getPatientSickLeavePDF(patientSickLeavesResponseModel, authenticatedUser); | ||||||
|  | 
 | ||||||
|  |     result.fold( | ||||||
|  |       (failure) async => await errorHandlerService.handleError( | ||||||
|  |         failure: failure, | ||||||
|  |         onOkPressed: () { | ||||||
|  |           onError!(failure.message); | ||||||
|  |         }, | ||||||
|  |       ), | ||||||
|  |       (apiResponse) { | ||||||
|  |         if (apiResponse.messageStatus == 2) { | ||||||
|  |           // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); | ||||||
|  |         } else if (apiResponse.messageStatus == 1) { | ||||||
|  |           patientSickLeavePDFBase64 = apiResponse.data!; | ||||||
|  |           isPatientSickLeaveListLoading = false; | ||||||
|  |           notifyListeners(); | ||||||
|  |           if (onSuccess != null) { | ||||||
|  |             onSuccess(apiResponse); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Future<void> getPatientMedicalReportList({Function(dynamic)? onSuccess, Function(String)? onError}) async { | ||||||
|  |     patientMedicalReportList.clear(); | ||||||
|  |     final result = await medicalFileRepo.getPatientMedicalReportsList(); | ||||||
|  | 
 | ||||||
|  |     result.fold( | ||||||
|  |       (failure) async => await errorHandlerService.handleError( | ||||||
|  |         failure: failure, | ||||||
|  |         onOkPressed: () { | ||||||
|  |           onError!(failure.message); | ||||||
|  |         }, | ||||||
|  |       ), | ||||||
|  |       (apiResponse) { | ||||||
|  |         if (apiResponse.messageStatus == 2) { | ||||||
|  |           // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); | ||||||
|  |         } else if (apiResponse.messageStatus == 1) { | ||||||
|  |           patientMedicalReportList = apiResponse.data!; | ||||||
|  |           if (patientMedicalReportList.isNotEmpty) { | ||||||
|  |             patientMedicalReportRequestedList = patientMedicalReportList.where((element) => element.status == 1).toList(); | ||||||
|  |             patientMedicalReportReadyList = patientMedicalReportList.where((element) => element.status == 2).toList(); | ||||||
|  |             patientMedicalReportCancelledList = patientMedicalReportList.where((element) => element.status == 4).toList(); | ||||||
|  |           } | ||||||
|  |           onMedicalReportTabChange(0); | ||||||
|  |           isPatientMedicalReportsListLoading = false; | ||||||
|  |           notifyListeners(); | ||||||
|  |           if (onSuccess != null) { | ||||||
|  |             onSuccess(apiResponse); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Future<void> getPatientMedicalReportPDF(PatientMedicalReportResponseModel patientMedicalReportResponseModel, AuthenticatedUser authenticatedUser, | ||||||
|  |       {Function(dynamic)? onSuccess, Function(String)? onError}) async { | ||||||
|  |     final result = await medicalFileRepo.getPatientMedicalReportPDF(patientMedicalReportResponseModel, authenticatedUser); | ||||||
|  | 
 | ||||||
|  |     result.fold( | ||||||
|  |       (failure) async => await errorHandlerService.handleError( | ||||||
|  |         failure: failure, | ||||||
|  |         onOkPressed: () { | ||||||
|  |           onError!(failure.message); | ||||||
|  |         }, | ||||||
|  |       ), | ||||||
|  |       (apiResponse) { | ||||||
|  |         if (apiResponse.messageStatus == 2) { | ||||||
|  |           // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); | ||||||
|  |         } else if (apiResponse.messageStatus == 1) { | ||||||
|  |           patientMedicalReportPDFBase64 = apiResponse.data!; | ||||||
|  |           notifyListeners(); | ||||||
|  |           if (onSuccess != null) { | ||||||
|  |             onSuccess(apiResponse); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,192 @@ | |||||||
|  | class PatientMedicalReportResponseModel { | ||||||
|  |   int? status; | ||||||
|  |   String? encounterDate; | ||||||
|  |   int? projectID; | ||||||
|  |   int? invoiceNo; | ||||||
|  |   int? encounterNo; | ||||||
|  |   String? procedureId; | ||||||
|  |   int? requestType; | ||||||
|  |   String? setupId; | ||||||
|  |   int? patientID; | ||||||
|  |   int? doctorID; | ||||||
|  |   int? clinicID; | ||||||
|  |   String? requestDate; | ||||||
|  |   bool? isRead; | ||||||
|  |   dynamic isReadOn; | ||||||
|  |   num? actualDoctorRate; | ||||||
|  |   String? admissionDate; | ||||||
|  |   int? admissionNumber; | ||||||
|  |   String? appointmentDate; | ||||||
|  |   int? appointmentNO; | ||||||
|  |   String? appointmentTime; | ||||||
|  |   String? clinicDescription; | ||||||
|  |   dynamic clinicDescriptionN; | ||||||
|  |   num? decimalDoctorRate; | ||||||
|  |   String? docName; | ||||||
|  |   dynamic docNameN; | ||||||
|  |   String? doctorImageURL; | ||||||
|  |   String? doctorName; | ||||||
|  |   dynamic doctorNameN; | ||||||
|  |   num? doctorRate; | ||||||
|  |   num? doctorStarsRate; | ||||||
|  |   int? invoiceNoVP; | ||||||
|  |   dynamic invoiceType; | ||||||
|  |   bool? isDoctorAllowVedioCall; | ||||||
|  |   bool? isExecludeDoctor; | ||||||
|  |   bool? isInOutPatient; | ||||||
|  |   String? isInOutPatientDescription; | ||||||
|  |   String? isInOutPatientDescriptionN; | ||||||
|  |   int? noOfPatientsRate; | ||||||
|  |   String? projectName; | ||||||
|  |   dynamic projectNameN; | ||||||
|  |   int? sourceID; | ||||||
|  |   dynamic sourceName; | ||||||
|  |   dynamic sourceNameN; | ||||||
|  |   String? statusDesc; | ||||||
|  |   dynamic strAppointmentDate; | ||||||
|  | 
 | ||||||
|  |   PatientMedicalReportResponseModel( | ||||||
|  |       {this.status, | ||||||
|  |       this.encounterDate, | ||||||
|  |       this.projectID, | ||||||
|  |       this.invoiceNo, | ||||||
|  |       this.encounterNo, | ||||||
|  |       this.procedureId, | ||||||
|  |       this.requestType, | ||||||
|  |       this.setupId, | ||||||
|  |       this.patientID, | ||||||
|  |       this.doctorID, | ||||||
|  |       this.clinicID, | ||||||
|  |       this.requestDate, | ||||||
|  |       this.isRead, | ||||||
|  |       this.isReadOn, | ||||||
|  |       this.actualDoctorRate, | ||||||
|  |       this.admissionDate, | ||||||
|  |       this.admissionNumber, | ||||||
|  |       this.appointmentDate, | ||||||
|  |       this.appointmentNO, | ||||||
|  |       this.appointmentTime, | ||||||
|  |       this.clinicDescription, | ||||||
|  |       this.clinicDescriptionN, | ||||||
|  |       this.decimalDoctorRate, | ||||||
|  |       this.docName, | ||||||
|  |       this.docNameN, | ||||||
|  |       this.doctorImageURL, | ||||||
|  |       this.doctorName, | ||||||
|  |       this.doctorNameN, | ||||||
|  |       this.doctorRate, | ||||||
|  |       this.doctorStarsRate, | ||||||
|  |       this.invoiceNoVP, | ||||||
|  |       this.invoiceType, | ||||||
|  |       this.isDoctorAllowVedioCall, | ||||||
|  |       this.isExecludeDoctor, | ||||||
|  |       this.isInOutPatient, | ||||||
|  |       this.isInOutPatientDescription, | ||||||
|  |       this.isInOutPatientDescriptionN, | ||||||
|  |       this.noOfPatientsRate, | ||||||
|  |       this.projectName, | ||||||
|  |       this.projectNameN, | ||||||
|  |       this.sourceID, | ||||||
|  |       this.sourceName, | ||||||
|  |       this.sourceNameN, | ||||||
|  |       this.statusDesc, | ||||||
|  |       this.strAppointmentDate}); | ||||||
|  | 
 | ||||||
|  |   PatientMedicalReportResponseModel.fromJson(Map<String, dynamic> json) { | ||||||
|  |     status = json['Status']; | ||||||
|  |     encounterDate = json['EncounterDate']; | ||||||
|  |     projectID = json['ProjectID']; | ||||||
|  |     invoiceNo = json['InvoiceNo']; | ||||||
|  |     encounterNo = json['EncounterNo']; | ||||||
|  |     procedureId = json['ProcedureId']; | ||||||
|  |     requestType = json['RequestType']; | ||||||
|  |     setupId = json['SetupId']; | ||||||
|  |     patientID = json['PatientID']; | ||||||
|  |     doctorID = json['DoctorID']; | ||||||
|  |     clinicID = json['ClinicID']; | ||||||
|  |     requestDate = json['RequestDate']; | ||||||
|  |     isRead = json['IsRead']; | ||||||
|  |     isReadOn = json['IsReadOn']; | ||||||
|  |     actualDoctorRate = json['ActualDoctorRate']; | ||||||
|  |     admissionDate = json['AdmissionDate']; | ||||||
|  |     admissionNumber = json['AdmissionNumber']; | ||||||
|  |     appointmentDate = json['AppointmentDate']; | ||||||
|  |     appointmentNO = json['AppointmentNO']; | ||||||
|  |     appointmentTime = json['AppointmentTime']; | ||||||
|  |     clinicDescription = json['ClinicDescription']; | ||||||
|  |     clinicDescriptionN = json['ClinicDescriptionN']; | ||||||
|  |     decimalDoctorRate = json['DecimalDoctorRate']; | ||||||
|  |     docName = json['DocName']; | ||||||
|  |     docNameN = json['DocNameN']; | ||||||
|  |     doctorImageURL = json['DoctorImageURL']; | ||||||
|  |     doctorName = json['DoctorName']; | ||||||
|  |     doctorNameN = json['DoctorNameN']; | ||||||
|  |     doctorRate = json['DoctorRate']; | ||||||
|  |     doctorStarsRate = json['DoctorStarsRate']; | ||||||
|  |     invoiceNoVP = json['InvoiceNo_VP']; | ||||||
|  |     invoiceType = json['InvoiceType']; | ||||||
|  |     isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; | ||||||
|  |     isExecludeDoctor = json['IsExecludeDoctor']; | ||||||
|  |     isInOutPatient = json['IsInOutPatient']; | ||||||
|  |     isInOutPatientDescription = json['IsInOutPatientDescription']; | ||||||
|  |     isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN']; | ||||||
|  |     noOfPatientsRate = json['NoOfPatientsRate']; | ||||||
|  |     projectName = json['ProjectName']; | ||||||
|  |     projectNameN = json['ProjectNameN']; | ||||||
|  |     sourceID = json['SourceID']; | ||||||
|  |     sourceName = json['SourceName']; | ||||||
|  |     sourceNameN = json['SourceNameN']; | ||||||
|  |     statusDesc = json['StatusDesc']; | ||||||
|  |     strAppointmentDate = json['StrAppointmentDate']; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Map<String, dynamic> toJson() { | ||||||
|  |     final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||||
|  |     data['Status'] = this.status; | ||||||
|  |     data['EncounterDate'] = this.encounterDate; | ||||||
|  |     data['ProjectID'] = this.projectID; | ||||||
|  |     data['InvoiceNo'] = this.invoiceNo; | ||||||
|  |     data['EncounterNo'] = this.encounterNo; | ||||||
|  |     data['ProcedureId'] = this.procedureId; | ||||||
|  |     data['RequestType'] = this.requestType; | ||||||
|  |     data['SetupId'] = this.setupId; | ||||||
|  |     data['PatientID'] = this.patientID; | ||||||
|  |     data['DoctorID'] = this.doctorID; | ||||||
|  |     data['ClinicID'] = this.clinicID; | ||||||
|  |     data['RequestDate'] = this.requestDate; | ||||||
|  |     data['IsRead'] = this.isRead; | ||||||
|  |     data['IsReadOn'] = this.isReadOn; | ||||||
|  |     data['ActualDoctorRate'] = this.actualDoctorRate; | ||||||
|  |     data['AdmissionDate'] = this.admissionDate; | ||||||
|  |     data['AdmissionNumber'] = this.admissionNumber; | ||||||
|  |     data['AppointmentDate'] = this.appointmentDate; | ||||||
|  |     data['AppointmentNO'] = this.appointmentNO; | ||||||
|  |     data['AppointmentTime'] = this.appointmentTime; | ||||||
|  |     data['ClinicDescription'] = this.clinicDescription; | ||||||
|  |     data['ClinicDescriptionN'] = this.clinicDescriptionN; | ||||||
|  |     data['DecimalDoctorRate'] = this.decimalDoctorRate; | ||||||
|  |     data['DocName'] = this.docName; | ||||||
|  |     data['DocNameN'] = this.docNameN; | ||||||
|  |     data['DoctorImageURL'] = this.doctorImageURL; | ||||||
|  |     data['DoctorName'] = this.doctorName; | ||||||
|  |     data['DoctorNameN'] = this.doctorNameN; | ||||||
|  |     data['DoctorRate'] = this.doctorRate; | ||||||
|  |     data['DoctorStarsRate'] = this.doctorStarsRate; | ||||||
|  |     data['InvoiceNo_VP'] = this.invoiceNoVP; | ||||||
|  |     data['InvoiceType'] = this.invoiceType; | ||||||
|  |     data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; | ||||||
|  |     data['IsExecludeDoctor'] = this.isExecludeDoctor; | ||||||
|  |     data['IsInOutPatient'] = this.isInOutPatient; | ||||||
|  |     data['IsInOutPatientDescription'] = this.isInOutPatientDescription; | ||||||
|  |     data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN; | ||||||
|  |     data['NoOfPatientsRate'] = this.noOfPatientsRate; | ||||||
|  |     data['ProjectName'] = this.projectName; | ||||||
|  |     data['ProjectNameN'] = this.projectNameN; | ||||||
|  |     data['SourceID'] = this.sourceID; | ||||||
|  |     data['SourceName'] = this.sourceName; | ||||||
|  |     data['SourceNameN'] = this.sourceNameN; | ||||||
|  |     data['StatusDesc'] = this.statusDesc; | ||||||
|  |     data['StrAppointmentDate'] = this.strAppointmentDate; | ||||||
|  |     return data; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,176 @@ | |||||||
|  | class PatientSickLeavesResponseModel { | ||||||
|  |   String? setupID; | ||||||
|  |   int? projectID; | ||||||
|  |   int? patientID; | ||||||
|  |   int? patientType; | ||||||
|  |   int? clinicID; | ||||||
|  |   int? doctorID; | ||||||
|  |   int? requestNo; | ||||||
|  |   String? requestDate; | ||||||
|  |   int? sickLeaveDays; | ||||||
|  |   int? appointmentNo; | ||||||
|  |   int? admissionNo; | ||||||
|  |   dynamic reportDate; | ||||||
|  |   num? actualDoctorRate; | ||||||
|  |   String? appointmentDate; | ||||||
|  |   String? clinicName; | ||||||
|  |   double? decimalDoctorRate; | ||||||
|  |   String? doctorImageURL; | ||||||
|  |   String? doctorName; | ||||||
|  |   num? doctorRate; | ||||||
|  |   num? doctorStarsRate; | ||||||
|  |   String? doctorTitle; | ||||||
|  |   int? employeeID; | ||||||
|  |   String? endDate; | ||||||
|  |   int? gender; | ||||||
|  |   String? genderDescription; | ||||||
|  |   bool? isActiveDoctorProfile; | ||||||
|  |   bool? isDoctorAllowVedioCall; | ||||||
|  |   bool? isExecludeDoctor; | ||||||
|  |   bool? isInOutPatient; | ||||||
|  |   String? isInOutPatientDescription; | ||||||
|  |   String? isInOutPatientDescriptionN; | ||||||
|  |   bool? isLiveCareAppointment; | ||||||
|  |   dynamic medicalDirectorApprovedStatus; | ||||||
|  |   int? noOfPatientsRate; | ||||||
|  |   dynamic patientName; | ||||||
|  |   String? projectName; | ||||||
|  |   String? qR; | ||||||
|  |   List<String>? speciality; | ||||||
|  |   String? startDate; | ||||||
|  |   int? status; | ||||||
|  |   String? strRequestDate; | ||||||
|  | 
 | ||||||
|  |   PatientSickLeavesResponseModel( | ||||||
|  |       {this.setupID, | ||||||
|  |       this.projectID, | ||||||
|  |       this.patientID, | ||||||
|  |       this.patientType, | ||||||
|  |       this.clinicID, | ||||||
|  |       this.doctorID, | ||||||
|  |       this.requestNo, | ||||||
|  |       this.requestDate, | ||||||
|  |       this.sickLeaveDays, | ||||||
|  |       this.appointmentNo, | ||||||
|  |       this.admissionNo, | ||||||
|  |       this.reportDate, | ||||||
|  |       this.actualDoctorRate, | ||||||
|  |       this.appointmentDate, | ||||||
|  |       this.clinicName, | ||||||
|  |       this.decimalDoctorRate, | ||||||
|  |       this.doctorImageURL, | ||||||
|  |       this.doctorName, | ||||||
|  |       this.doctorRate, | ||||||
|  |       this.doctorStarsRate, | ||||||
|  |       this.doctorTitle, | ||||||
|  |       this.employeeID, | ||||||
|  |       this.endDate, | ||||||
|  |       this.gender, | ||||||
|  |       this.genderDescription, | ||||||
|  |       this.isActiveDoctorProfile, | ||||||
|  |       this.isDoctorAllowVedioCall, | ||||||
|  |       this.isExecludeDoctor, | ||||||
|  |       this.isInOutPatient, | ||||||
|  |       this.isInOutPatientDescription, | ||||||
|  |       this.isInOutPatientDescriptionN, | ||||||
|  |       this.isLiveCareAppointment, | ||||||
|  |       this.medicalDirectorApprovedStatus, | ||||||
|  |       this.noOfPatientsRate, | ||||||
|  |       this.patientName, | ||||||
|  |       this.projectName, | ||||||
|  |       this.qR, | ||||||
|  |       this.speciality, | ||||||
|  |       this.startDate, | ||||||
|  |       this.status, | ||||||
|  |       this.strRequestDate}); | ||||||
|  | 
 | ||||||
|  |   PatientSickLeavesResponseModel.fromJson(Map<String, dynamic> json) { | ||||||
|  |     setupID = json['SetupID']; | ||||||
|  |     projectID = json['ProjectID']; | ||||||
|  |     patientID = json['PatientID']; | ||||||
|  |     patientType = json['PatientType']; | ||||||
|  |     clinicID = json['ClinicID']; | ||||||
|  |     doctorID = json['DoctorID']; | ||||||
|  |     requestNo = json['RequestNo']; | ||||||
|  |     requestDate = json['RequestDate']; | ||||||
|  |     sickLeaveDays = json['SickLeaveDays']; | ||||||
|  |     appointmentNo = json['AppointmentNo']; | ||||||
|  |     admissionNo = json['AdmissionNo']; | ||||||
|  |     reportDate = json['ReportDate']; | ||||||
|  |     actualDoctorRate = json['ActualDoctorRate']; | ||||||
|  |     appointmentDate = json['AppointmentDate']; | ||||||
|  |     clinicName = json['ClinicName']; | ||||||
|  |     decimalDoctorRate = json['DecimalDoctorRate']; | ||||||
|  |     doctorImageURL = json['DoctorImageURL']; | ||||||
|  |     doctorName = json['DoctorName']; | ||||||
|  |     doctorRate = json['DoctorRate']; | ||||||
|  |     doctorStarsRate = json['DoctorStarsRate']; | ||||||
|  |     doctorTitle = json['DoctorTitle']; | ||||||
|  |     employeeID = json['EmployeeID']; | ||||||
|  |     endDate = json['EndDate']; | ||||||
|  |     gender = json['Gender']; | ||||||
|  |     genderDescription = json['GenderDescription']; | ||||||
|  |     isActiveDoctorProfile = json['IsActiveDoctorProfile']; | ||||||
|  |     isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; | ||||||
|  |     isExecludeDoctor = json['IsExecludeDoctor']; | ||||||
|  |     isInOutPatient = json['IsInOutPatient']; | ||||||
|  |     isInOutPatientDescription = json['IsInOutPatientDescription']; | ||||||
|  |     isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN']; | ||||||
|  |     isLiveCareAppointment = json['IsLiveCareAppointment']; | ||||||
|  |     medicalDirectorApprovedStatus = json['MedicalDirectorApprovedStatus']; | ||||||
|  |     noOfPatientsRate = json['NoOfPatientsRate']; | ||||||
|  |     patientName = json['PatientName']; | ||||||
|  |     projectName = json['ProjectName']; | ||||||
|  |     qR = json['QR']; | ||||||
|  |     speciality = json['Speciality'].cast<String>(); | ||||||
|  |     startDate = json['StartDate']; | ||||||
|  |     status = json['Status']; | ||||||
|  |     strRequestDate = json['StrRequestDate']; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Map<String, dynamic> toJson() { | ||||||
|  |     final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||||
|  |     data['SetupID'] = this.setupID; | ||||||
|  |     data['ProjectID'] = this.projectID; | ||||||
|  |     data['PatientID'] = this.patientID; | ||||||
|  |     data['PatientType'] = this.patientType; | ||||||
|  |     data['ClinicID'] = this.clinicID; | ||||||
|  |     data['DoctorID'] = this.doctorID; | ||||||
|  |     data['RequestNo'] = this.requestNo; | ||||||
|  |     data['RequestDate'] = this.requestDate; | ||||||
|  |     data['SickLeaveDays'] = this.sickLeaveDays; | ||||||
|  |     data['AppointmentNo'] = this.appointmentNo; | ||||||
|  |     data['AdmissionNo'] = this.admissionNo; | ||||||
|  |     data['ReportDate'] = this.reportDate; | ||||||
|  |     data['ActualDoctorRate'] = this.actualDoctorRate; | ||||||
|  |     data['AppointmentDate'] = this.appointmentDate; | ||||||
|  |     data['ClinicName'] = this.clinicName; | ||||||
|  |     data['DecimalDoctorRate'] = this.decimalDoctorRate; | ||||||
|  |     data['DoctorImageURL'] = this.doctorImageURL; | ||||||
|  |     data['DoctorName'] = this.doctorName; | ||||||
|  |     data['DoctorRate'] = this.doctorRate; | ||||||
|  |     data['DoctorStarsRate'] = this.doctorStarsRate; | ||||||
|  |     data['DoctorTitle'] = this.doctorTitle; | ||||||
|  |     data['EmployeeID'] = this.employeeID; | ||||||
|  |     data['EndDate'] = this.endDate; | ||||||
|  |     data['Gender'] = this.gender; | ||||||
|  |     data['GenderDescription'] = this.genderDescription; | ||||||
|  |     data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile; | ||||||
|  |     data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; | ||||||
|  |     data['IsExecludeDoctor'] = this.isExecludeDoctor; | ||||||
|  |     data['IsInOutPatient'] = this.isInOutPatient; | ||||||
|  |     data['IsInOutPatientDescription'] = this.isInOutPatientDescription; | ||||||
|  |     data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN; | ||||||
|  |     data['IsLiveCareAppointment'] = this.isLiveCareAppointment; | ||||||
|  |     data['MedicalDirectorApprovedStatus'] = this.medicalDirectorApprovedStatus; | ||||||
|  |     data['NoOfPatientsRate'] = this.noOfPatientsRate; | ||||||
|  |     data['PatientName'] = this.patientName; | ||||||
|  |     data['ProjectName'] = this.projectName; | ||||||
|  |     data['QR'] = this.qR; | ||||||
|  |     data['Speciality'] = this.speciality; | ||||||
|  |     data['StartDate'] = this.startDate; | ||||||
|  |     data['Status'] = this.status; | ||||||
|  |     data['StrRequestDate'] = this.strRequestDate; | ||||||
|  |     return data; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,160 @@ | |||||||
|  | class PatientVaccineResponseModel { | ||||||
|  |   String? setupID; | ||||||
|  |   int? projectID; | ||||||
|  |   int? patientID; | ||||||
|  |   int? invoiceNo; | ||||||
|  |   String? procedureID; | ||||||
|  |   String? vaccineName; | ||||||
|  |   Null? vaccineNameN; | ||||||
|  |   String? invoiceDate; | ||||||
|  |   int? doctorID; | ||||||
|  |   int? clinicID; | ||||||
|  |   String? firstName; | ||||||
|  |   String? middleName; | ||||||
|  |   String? lastName; | ||||||
|  |   Null? firstNameN; | ||||||
|  |   Null? middleNameN; | ||||||
|  |   Null? lastNameN; | ||||||
|  |   String? dateofBirth; | ||||||
|  |   int? actualDoctorRate; | ||||||
|  |   String? age; | ||||||
|  |   String? clinicName; | ||||||
|  |   Null? decimalDoctorRate; | ||||||
|  |   Null? doctorImageURL; | ||||||
|  |   String? doctorName; | ||||||
|  |   int? doctorRate; | ||||||
|  |   int? doctorStarsRate; | ||||||
|  |   String? doctorTitle; | ||||||
|  |   int? gender; | ||||||
|  |   Null? genderDescription; | ||||||
|  |   Null? invoiceNoVP; | ||||||
|  |   bool? isActiveDoctorProfile; | ||||||
|  |   bool? isDoctorAllowVedioCall; | ||||||
|  |   bool? isExecludeDoctor; | ||||||
|  |   int? noOfPatientsRate; | ||||||
|  |   String? patientName; | ||||||
|  |   String? projectName; | ||||||
|  |   String? qR; | ||||||
|  |   String? vaccinationDate; | ||||||
|  | 
 | ||||||
|  |   PatientVaccineResponseModel( | ||||||
|  |       {this.setupID, | ||||||
|  |       this.projectID, | ||||||
|  |       this.patientID, | ||||||
|  |       this.invoiceNo, | ||||||
|  |       this.procedureID, | ||||||
|  |       this.vaccineName, | ||||||
|  |       this.vaccineNameN, | ||||||
|  |       this.invoiceDate, | ||||||
|  |       this.doctorID, | ||||||
|  |       this.clinicID, | ||||||
|  |       this.firstName, | ||||||
|  |       this.middleName, | ||||||
|  |       this.lastName, | ||||||
|  |       this.firstNameN, | ||||||
|  |       this.middleNameN, | ||||||
|  |       this.lastNameN, | ||||||
|  |       this.dateofBirth, | ||||||
|  |       this.actualDoctorRate, | ||||||
|  |       this.age, | ||||||
|  |       this.clinicName, | ||||||
|  |       this.decimalDoctorRate, | ||||||
|  |       this.doctorImageURL, | ||||||
|  |       this.doctorName, | ||||||
|  |       this.doctorRate, | ||||||
|  |       this.doctorStarsRate, | ||||||
|  |       this.doctorTitle, | ||||||
|  |       this.gender, | ||||||
|  |       this.genderDescription, | ||||||
|  |       this.invoiceNoVP, | ||||||
|  |       this.isActiveDoctorProfile, | ||||||
|  |       this.isDoctorAllowVedioCall, | ||||||
|  |       this.isExecludeDoctor, | ||||||
|  |       this.noOfPatientsRate, | ||||||
|  |       this.patientName, | ||||||
|  |       this.projectName, | ||||||
|  |       this.qR, | ||||||
|  |       this.vaccinationDate}); | ||||||
|  | 
 | ||||||
|  |   PatientVaccineResponseModel.fromJson(Map<String, dynamic> json) { | ||||||
|  |     setupID = json['SetupID']; | ||||||
|  |     projectID = json['ProjectID']; | ||||||
|  |     patientID = json['PatientID']; | ||||||
|  |     invoiceNo = json['InvoiceNo']; | ||||||
|  |     procedureID = json['ProcedureID']; | ||||||
|  |     vaccineName = json['VaccineName']; | ||||||
|  |     vaccineNameN = json['VaccineNameN']; | ||||||
|  |     invoiceDate = json['InvoiceDate']; | ||||||
|  |     doctorID = json['DoctorID']; | ||||||
|  |     clinicID = json['ClinicID']; | ||||||
|  |     firstName = json['FirstName']; | ||||||
|  |     middleName = json['MiddleName']; | ||||||
|  |     lastName = json['LastName']; | ||||||
|  |     firstNameN = json['FirstNameN']; | ||||||
|  |     middleNameN = json['MiddleNameN']; | ||||||
|  |     lastNameN = json['LastNameN']; | ||||||
|  |     dateofBirth = json['DateofBirth']; | ||||||
|  |     actualDoctorRate = json['ActualDoctorRate']; | ||||||
|  |     age = json['Age']; | ||||||
|  |     clinicName = json['ClinicName']; | ||||||
|  |     decimalDoctorRate = json['DecimalDoctorRate']; | ||||||
|  |     doctorImageURL = json['DoctorImageURL']; | ||||||
|  |     doctorName = json['DoctorName']; | ||||||
|  |     doctorRate = json['DoctorRate']; | ||||||
|  |     doctorStarsRate = json['DoctorStarsRate']; | ||||||
|  |     doctorTitle = json['DoctorTitle']; | ||||||
|  |     gender = json['Gender']; | ||||||
|  |     genderDescription = json['GenderDescription']; | ||||||
|  |     invoiceNoVP = json['InvoiceNo_VP']; | ||||||
|  |     isActiveDoctorProfile = json['IsActiveDoctorProfile']; | ||||||
|  |     isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; | ||||||
|  |     isExecludeDoctor = json['IsExecludeDoctor']; | ||||||
|  |     noOfPatientsRate = json['NoOfPatientsRate']; | ||||||
|  |     patientName = json['PatientName']; | ||||||
|  |     projectName = json['ProjectName']; | ||||||
|  |     qR = json['QR']; | ||||||
|  |     vaccinationDate = json['VaccinationDate']; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Map<String, dynamic> toJson() { | ||||||
|  |     final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||||
|  |     data['SetupID'] = this.setupID; | ||||||
|  |     data['ProjectID'] = this.projectID; | ||||||
|  |     data['PatientID'] = this.patientID; | ||||||
|  |     data['InvoiceNo'] = this.invoiceNo; | ||||||
|  |     data['ProcedureID'] = this.procedureID; | ||||||
|  |     data['VaccineName'] = this.vaccineName; | ||||||
|  |     data['VaccineNameN'] = this.vaccineNameN; | ||||||
|  |     data['InvoiceDate'] = this.invoiceDate; | ||||||
|  |     data['DoctorID'] = this.doctorID; | ||||||
|  |     data['ClinicID'] = this.clinicID; | ||||||
|  |     data['FirstName'] = this.firstName; | ||||||
|  |     data['MiddleName'] = this.middleName; | ||||||
|  |     data['LastName'] = this.lastName; | ||||||
|  |     data['FirstNameN'] = this.firstNameN; | ||||||
|  |     data['MiddleNameN'] = this.middleNameN; | ||||||
|  |     data['LastNameN'] = this.lastNameN; | ||||||
|  |     data['DateofBirth'] = this.dateofBirth; | ||||||
|  |     data['ActualDoctorRate'] = this.actualDoctorRate; | ||||||
|  |     data['Age'] = this.age; | ||||||
|  |     data['ClinicName'] = this.clinicName; | ||||||
|  |     data['DecimalDoctorRate'] = this.decimalDoctorRate; | ||||||
|  |     data['DoctorImageURL'] = this.doctorImageURL; | ||||||
|  |     data['DoctorName'] = this.doctorName; | ||||||
|  |     data['DoctorRate'] = this.doctorRate; | ||||||
|  |     data['DoctorStarsRate'] = this.doctorStarsRate; | ||||||
|  |     data['DoctorTitle'] = this.doctorTitle; | ||||||
|  |     data['Gender'] = this.gender; | ||||||
|  |     data['GenderDescription'] = this.genderDescription; | ||||||
|  |     data['InvoiceNo_VP'] = this.invoiceNoVP; | ||||||
|  |     data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile; | ||||||
|  |     data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; | ||||||
|  |     data['IsExecludeDoctor'] = this.isExecludeDoctor; | ||||||
|  |     data['NoOfPatientsRate'] = this.noOfPatientsRate; | ||||||
|  |     data['PatientName'] = this.patientName; | ||||||
|  |     data['ProjectName'] = this.projectName; | ||||||
|  |     data['QR'] = this.qR; | ||||||
|  |     data['VaccinationDate'] = this.vaccinationDate; | ||||||
|  |     return data; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,160 @@ | |||||||
|  | import 'package:easy_localization/easy_localization.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/app_assets.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/theme/colors.dart'; | ||||||
|  | import 'package:provider/provider.dart'; | ||||||
|  | 
 | ||||||
|  | import '../../widgets/chip/app_custom_chip_widget.dart'; | ||||||
|  | 
 | ||||||
|  | class MyDoctorsPage extends StatelessWidget { | ||||||
|  |   MyDoctorsPage({super.key}); | ||||||
|  | 
 | ||||||
|  |   late MyAppointmentsViewModel myAppointmentsViewModel; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false); | ||||||
|  |     return Scaffold( | ||||||
|  |       backgroundColor: AppColors.bgScaffoldColor, | ||||||
|  |       body: CollapsingListView( | ||||||
|  |         title: LocaleKeys.myDoctor.tr(context: context), | ||||||
|  |         child: SingleChildScrollView( | ||||||
|  |           child: Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) { | ||||||
|  |             return Column( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |               children: [ | ||||||
|  |                 SizedBox(height: 16.h), | ||||||
|  |                 ListView.separated( | ||||||
|  |                   scrollDirection: Axis.vertical, | ||||||
|  |                   itemCount: myAppointmentsVM.isPatientMyDoctorsLoading ? 5 : myAppointmentsVM.patientMyDoctorsList.length, | ||||||
|  |                   shrinkWrap: true, | ||||||
|  |                   physics: NeverScrollableScrollPhysics(), | ||||||
|  |                   padding: EdgeInsets.only(left: 24.h, right: 24.h), | ||||||
|  |                   itemBuilder: (context, index) { | ||||||
|  |                     return myAppointmentsVM.isPatientMyDoctorsLoading | ||||||
|  |                         ? Container( | ||||||
|  |                             decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |                               color: AppColors.whiteColor, | ||||||
|  |                               borderRadius: 20.h, | ||||||
|  |                               hasShadow: true, | ||||||
|  |                             ), | ||||||
|  |                             child: Padding( | ||||||
|  |                               padding: EdgeInsets.all(14.h), | ||||||
|  |                               child: Column( | ||||||
|  |                                 crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                 children: [ | ||||||
|  |                                   Row( | ||||||
|  |                                     crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                     children: [ | ||||||
|  |                                       Image.network( | ||||||
|  |                                         "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", | ||||||
|  |                                         width: 63.h, | ||||||
|  |                                         height: 63.h, | ||||||
|  |                                         fit: BoxFit.fill, | ||||||
|  |                                       ).circle(100).toShimmer2(isShow: true), | ||||||
|  |                                       SizedBox(width: 16.h), | ||||||
|  |                                       Expanded( | ||||||
|  |                                         child: Column( | ||||||
|  |                                           crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                           children: [ | ||||||
|  |                                             "Dr John Smith".toText16(isBold: true).toShimmer2(isShow: true), | ||||||
|  |                                             SizedBox(height: 8.h), | ||||||
|  |                                             Wrap( | ||||||
|  |                                               direction: Axis.horizontal, | ||||||
|  |                                               spacing: 3.h, | ||||||
|  |                                               runSpacing: 4.h, | ||||||
|  |                                               children: [ | ||||||
|  |                                                 AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), | ||||||
|  |                                                 AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), | ||||||
|  |                                               ], | ||||||
|  |                                             ), | ||||||
|  |                                           ], | ||||||
|  |                                         ), | ||||||
|  |                                       ), | ||||||
|  |                                     ], | ||||||
|  |                                   ), | ||||||
|  |                                 ], | ||||||
|  |                               ), | ||||||
|  |                             ), | ||||||
|  |                           ) | ||||||
|  |                         : AnimationConfiguration.staggeredList( | ||||||
|  |                             position: index, | ||||||
|  |                             duration: const Duration(milliseconds: 1000), | ||||||
|  |                             child: SlideAnimation( | ||||||
|  |                               verticalOffset: 100.0, | ||||||
|  |                               child: FadeInAnimation( | ||||||
|  |                                 child: Container( | ||||||
|  |                                   decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |                                     color: AppColors.whiteColor, | ||||||
|  |                                     borderRadius: 20.h, | ||||||
|  |                                     hasShadow: true, | ||||||
|  |                                   ), | ||||||
|  |                                   child: Padding( | ||||||
|  |                                     padding: EdgeInsets.all(14.h), | ||||||
|  |                                     child: Column( | ||||||
|  |                                       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                       children: [ | ||||||
|  |                                         Row( | ||||||
|  |                                           crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                           children: [ | ||||||
|  |                                             Image.network( | ||||||
|  |                                               myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!, | ||||||
|  |                                               width: 63.h, | ||||||
|  |                                               height: 63.h, | ||||||
|  |                                               fit: BoxFit.fill, | ||||||
|  |                                             ).circle(100).toShimmer2(isShow: false), | ||||||
|  |                                             SizedBox(width: 16.h), | ||||||
|  |                                             Expanded( | ||||||
|  |                                               child: Column( | ||||||
|  |                                                 crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                                 children: [ | ||||||
|  |                                                   (myAppointmentsVM.patientMyDoctorsList[index].doctorName).toString().toText16(isBold: true).toShimmer2(isShow: false), | ||||||
|  |                                                   SizedBox(height: 8.h), | ||||||
|  |                                                   Wrap( | ||||||
|  |                                                     direction: Axis.horizontal, | ||||||
|  |                                                     spacing: 3.h, | ||||||
|  |                                                     runSpacing: 4.h, | ||||||
|  |                                                     children: [ | ||||||
|  |                                                       AppCustomChipWidget(labelText: myAppointmentsVM.patientMyDoctorsList[index].clinicName).toShimmer2(isShow: false, width: 16.h), | ||||||
|  |                                                       AppCustomChipWidget(labelText: myAppointmentsVM.patientMyDoctorsList[index].projectName).toShimmer2(isShow: false, width: 16.h), | ||||||
|  |                                                     ], | ||||||
|  |                                                   ), | ||||||
|  |                                                 ], | ||||||
|  |                                               ), | ||||||
|  |                                             ), | ||||||
|  |                                           ], | ||||||
|  |                                         ), | ||||||
|  |                                         Row( | ||||||
|  |                                           mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                                           children: [ | ||||||
|  |                                             "".toText16(), | ||||||
|  |                                             Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor), | ||||||
|  |                                           ], | ||||||
|  |                                         ), | ||||||
|  |                                       ], | ||||||
|  |                                     ), | ||||||
|  |                                   ), | ||||||
|  |                                 ), | ||||||
|  |                               ), | ||||||
|  |                             ), | ||||||
|  |                           ); | ||||||
|  |                   }, | ||||||
|  |                   separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), | ||||||
|  |                 ), | ||||||
|  |                 SizedBox(height: 60.h), | ||||||
|  |               ], | ||||||
|  |             ); | ||||||
|  |           }), | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,159 @@ | |||||||
|  | import 'package:easy_localization/easy_localization.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/app_assets.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/app_state.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/dependencies.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/theme/colors.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; | ||||||
|  | import 'package:provider/provider.dart'; | ||||||
|  | 
 | ||||||
|  | class BookAppointmentPage extends StatefulWidget { | ||||||
|  |   const BookAppointmentPage({super.key}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   State<BookAppointmentPage> createState() => _BookAppointmentPageState(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class _BookAppointmentPageState extends State<BookAppointmentPage> { | ||||||
|  |   late AppState appState; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     appState = getIt.get<AppState>(); | ||||||
|  |     return Scaffold( | ||||||
|  |       backgroundColor: AppColors.bgScaffoldColor, | ||||||
|  |       body: CollapsingListView( | ||||||
|  |         title: LocaleKeys.bookAppo.tr(context: context), | ||||||
|  |         child: SingleChildScrollView( | ||||||
|  |           child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) { | ||||||
|  |             return Column( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |               children: [ | ||||||
|  |                 SizedBox(height: 16.h), | ||||||
|  |                 CustomTabBar( | ||||||
|  |                   activeTextColor: Color(0xffED1C2B), | ||||||
|  |                   activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), | ||||||
|  |                   tabs: [ | ||||||
|  |                     CustomTabBarModel(null, "General".needTranslation), | ||||||
|  |                     CustomTabBarModel(null, "LiveCare".needTranslation), | ||||||
|  |                   ], | ||||||
|  |                   onTabChange: (index) { | ||||||
|  |                     bookAppointmentsVM.onTabChanged(index); | ||||||
|  |                   }, | ||||||
|  |                 ).paddingSymmetrical(24.h, 0.h), | ||||||
|  |                 SizedBox(height: 24.h), | ||||||
|  |                 getSelectedTabData(bookAppointmentsVM.selectedTabIndex), | ||||||
|  |               ], | ||||||
|  |             ); | ||||||
|  |           }), | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Widget getSelectedTabData(int index) { | ||||||
|  |     switch (index) { | ||||||
|  |       case 0: | ||||||
|  |         return Column( | ||||||
|  |           children: [ | ||||||
|  |             Container( | ||||||
|  |               decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |                 color: AppColors.whiteColor, | ||||||
|  |                 borderRadius: 24.h, | ||||||
|  |                 hasShadow: false, | ||||||
|  |               ), | ||||||
|  |               child: Padding( | ||||||
|  |                 padding: EdgeInsets.all(16.h), | ||||||
|  |                 child: Column( | ||||||
|  |                   crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                   children: [ | ||||||
|  |                     Row( | ||||||
|  |                       mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                       children: [ | ||||||
|  |                         Row( | ||||||
|  |                           children: [ | ||||||
|  |                             Utils.buildSvgWithAssets(icon: AppAssets.search_by_clinic_icon, width: 40.h, height: 40.h), | ||||||
|  |                             SizedBox(width: 12.h), | ||||||
|  |                             Column( | ||||||
|  |                               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                               children: [ | ||||||
|  |                                 "Search By Clinic".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500), | ||||||
|  |                                 "Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), | ||||||
|  |                               ], | ||||||
|  |                             ), | ||||||
|  |                           ], | ||||||
|  |                         ), | ||||||
|  |                         Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), | ||||||
|  |                       ], | ||||||
|  |                     ).onPress(() { | ||||||
|  |                       Navigator.of(context).push( | ||||||
|  |                         FadePage( | ||||||
|  |                           page: SelectClinicPage(), | ||||||
|  |                         ), | ||||||
|  |                       ); | ||||||
|  |                     }), | ||||||
|  |                     SizedBox(height: 16.h), | ||||||
|  |                     Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), | ||||||
|  |                     SizedBox(height: 16.h), | ||||||
|  |                     Row( | ||||||
|  |                       mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                       children: [ | ||||||
|  |                         Row( | ||||||
|  |                           children: [ | ||||||
|  |                             Utils.buildSvgWithAssets(icon: AppAssets.search_by_doctor_icon, width: 40.h, height: 40.h), | ||||||
|  |                             SizedBox(width: 12.h), | ||||||
|  |                             Column( | ||||||
|  |                               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                               children: [ | ||||||
|  |                                 "Search By Doctor".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500), | ||||||
|  |                                 "Tap to select".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), | ||||||
|  |                               ], | ||||||
|  |                             ), | ||||||
|  |                           ], | ||||||
|  |                         ), | ||||||
|  |                         Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), | ||||||
|  |                       ], | ||||||
|  |                     ).onPress(() {}), | ||||||
|  |                     SizedBox(height: 16.h), | ||||||
|  |                     Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), | ||||||
|  |                     SizedBox(height: 16.h), | ||||||
|  |                     Row( | ||||||
|  |                       mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                       children: [ | ||||||
|  |                         Row( | ||||||
|  |                           children: [ | ||||||
|  |                             Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h), | ||||||
|  |                             SizedBox(width: 12.h), | ||||||
|  |                             Column( | ||||||
|  |                               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                               children: [ | ||||||
|  |                                 "Search By Region".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500), | ||||||
|  |                                 "Central Region".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), | ||||||
|  |                               ], | ||||||
|  |                             ), | ||||||
|  |                           ], | ||||||
|  |                         ), | ||||||
|  |                         Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), | ||||||
|  |                       ], | ||||||
|  |                     ).onPress(() {}), | ||||||
|  |                   ], | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ], | ||||||
|  |         ).paddingSymmetrical(24.h, 0.h); | ||||||
|  |       default: | ||||||
|  |         SizedBox.shrink(); | ||||||
|  |     } | ||||||
|  |     return Container(); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | import 'package:easy_localization/easy_localization.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/theme/colors.dart'; | ||||||
|  | 
 | ||||||
|  | class SelectClinicPage extends StatefulWidget { | ||||||
|  |   const SelectClinicPage({super.key}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   State<SelectClinicPage> createState() => _SelectClinicPageState(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class _SelectClinicPageState extends State<SelectClinicPage> { | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Scaffold( | ||||||
|  |       backgroundColor: AppColors.bgScaffoldColor, | ||||||
|  |       body: CollapsingListView( | ||||||
|  |         title: LocaleKeys.selectClinic.tr(context: context), | ||||||
|  |         child: SingleChildScrollView( | ||||||
|  |           child: Column( | ||||||
|  |             children: [], | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,94 @@ | |||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_medical_report_card.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/theme/colors.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; | ||||||
|  | import 'package:provider/provider.dart'; | ||||||
|  | 
 | ||||||
|  | class MedicalReportsPage extends StatefulWidget { | ||||||
|  |   const MedicalReportsPage({super.key}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   State<MedicalReportsPage> createState() => _MedicalReportsPageState(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class _MedicalReportsPageState extends State<MedicalReportsPage> { | ||||||
|  |   late MedicalFileViewModel medicalFileViewModel; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     medicalFileViewModel = Provider.of<MedicalFileViewModel>(context, listen: false); | ||||||
|  |     return Scaffold( | ||||||
|  |       backgroundColor: AppColors.bgScaffoldColor, | ||||||
|  |       body: CollapsingListView( | ||||||
|  |         title: "Medical Reports".needTranslation, | ||||||
|  |         child: SingleChildScrollView( | ||||||
|  |           child: Column( | ||||||
|  |             children: [ | ||||||
|  |               SizedBox(height: 16.h), | ||||||
|  |               CustomTabBar( | ||||||
|  |                 activeTextColor: Color(0xffED1C2B), | ||||||
|  |                 activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), | ||||||
|  |                 tabs: [ | ||||||
|  |                   CustomTabBarModel(null, "Requested".needTranslation), | ||||||
|  |                   CustomTabBarModel(null, "Ready".needTranslation), | ||||||
|  |                   CustomTabBarModel(null, "Cancelled".needTranslation), | ||||||
|  |                 ], | ||||||
|  |                 onTabChange: (index) { | ||||||
|  |                   medicalFileViewModel.onMedicalReportTabChange(index); | ||||||
|  |                 }, | ||||||
|  |               ).paddingSymmetrical(24.h, 0.h), | ||||||
|  |               Consumer<MedicalFileViewModel>(builder: (context, medicalFileVM, child) { | ||||||
|  |                 return ListView.separated( | ||||||
|  |                   padding: EdgeInsets.only(top: 24.h), | ||||||
|  |                   shrinkWrap: true, | ||||||
|  |                   physics: NeverScrollableScrollPhysics(), | ||||||
|  |                   itemCount: medicalFileViewModel.isPatientMedicalReportsListLoading ? 3 : medicalFileViewModel.patientMedicalReportList.length, | ||||||
|  |                   // medicalFileViewModel.patientMedicalReportList.isNotEmpty | ||||||
|  |                   //         ? medicalFileViewModel.patientMedicalReportList.length | ||||||
|  |                   //         : 1, | ||||||
|  |                   itemBuilder: (context, index) { | ||||||
|  |                     return medicalFileViewModel.isPatientMedicalReportsListLoading | ||||||
|  |                         ? PatientMedicalReportCard( | ||||||
|  |                             patientMedicalReportResponseModel: PatientMedicalReportResponseModel(), | ||||||
|  |                             medicalFileViewModel: medicalFileVM, | ||||||
|  |                             isLoading: true, | ||||||
|  |                           ).paddingSymmetrical(24.h, 0.h) | ||||||
|  |                         : AnimationConfiguration.staggeredList( | ||||||
|  |                             position: index, | ||||||
|  |                             duration: const Duration(milliseconds: 500), | ||||||
|  |                             child: SlideAnimation( | ||||||
|  |                               verticalOffset: 100.0, | ||||||
|  |                               child: FadeInAnimation( | ||||||
|  |                                 child: AnimatedContainer( | ||||||
|  |                                   duration: Duration(milliseconds: 300), | ||||||
|  |                                   curve: Curves.easeInOut, | ||||||
|  |                                   decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), | ||||||
|  |                                   child: PatientMedicalReportCard( | ||||||
|  |                                     patientMedicalReportResponseModel: medicalFileVM.patientMedicalReportList[index], | ||||||
|  |                                     medicalFileViewModel: medicalFileVM, | ||||||
|  | 
 | ||||||
|  |                                     isLoading: false, | ||||||
|  |                                   ), | ||||||
|  |                                 ).paddingSymmetrical(24.h, 0.h), | ||||||
|  |                               ), | ||||||
|  |                             ), | ||||||
|  |                           ); | ||||||
|  |                   }, | ||||||
|  |                   separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), | ||||||
|  |                 ); | ||||||
|  |               }), | ||||||
|  |               SizedBox(height: 24.h), | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,88 @@ | |||||||
|  | import 'dart:async'; | ||||||
|  | 
 | ||||||
|  | import 'package:easy_localization/easy_localization.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/theme/colors.dart'; | ||||||
|  | import 'package:provider/provider.dart'; | ||||||
|  | 
 | ||||||
|  | import 'widgets/patient_sick_leave_card.dart'; | ||||||
|  | 
 | ||||||
|  | class PatientSickleavesListPage extends StatefulWidget { | ||||||
|  |   const PatientSickleavesListPage({super.key}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   State<PatientSickleavesListPage> createState() => _PatientSickleavesListPageState(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class _PatientSickleavesListPageState extends State<PatientSickleavesListPage> { | ||||||
|  |   late MedicalFileViewModel medicalFileViewModel; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     scheduleMicrotask(() { | ||||||
|  |       medicalFileViewModel.setIsPatientSickLeaveListLoading(true); | ||||||
|  |       medicalFileViewModel.getPatientSickLeaveList(onError: (error) { | ||||||
|  |         Navigator.of(context).pop(); | ||||||
|  |         Navigator.of(context).pop(); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     super.initState(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     medicalFileViewModel = Provider.of<MedicalFileViewModel>(context, listen: false); | ||||||
|  |     return Scaffold( | ||||||
|  |       backgroundColor: AppColors.bgScaffoldColor, | ||||||
|  |       body: CollapsingListView( | ||||||
|  |         title: "${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}", | ||||||
|  |         child: SingleChildScrollView( | ||||||
|  |           child: Consumer<MedicalFileViewModel>(builder: (context, medicalFileVM, child) { | ||||||
|  |             return Column( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |               children: [ | ||||||
|  |                 ListView.separated( | ||||||
|  |                   scrollDirection: Axis.vertical, | ||||||
|  |                   itemCount: medicalFileVM.isPatientSickLeaveListLoading ? 3 : medicalFileVM.patientSickLeaveList.length, | ||||||
|  |                   shrinkWrap: true, | ||||||
|  |                   physics: NeverScrollableScrollPhysics(), | ||||||
|  |                   itemBuilder: (context, index) { | ||||||
|  |                     return medicalFileVM.isPatientSickLeaveListLoading | ||||||
|  |                         ? PatientSickLeaveCard( | ||||||
|  |                             patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), | ||||||
|  |                             isLoading: true, | ||||||
|  |                           ).paddingSymmetrical(24.h, 0.0) | ||||||
|  |                         : medicalFileVM.patientSickLeaveList.isNotEmpty | ||||||
|  |                             ? AnimationConfiguration.staggeredList( | ||||||
|  |                                 position: index, | ||||||
|  |                                 duration: const Duration(milliseconds: 1000), | ||||||
|  |                                 child: SlideAnimation( | ||||||
|  |                                   verticalOffset: 100.0, | ||||||
|  |                                   child: FadeInAnimation( | ||||||
|  |                                     child: PatientSickLeaveCard( | ||||||
|  |                                       patientSickLeavesResponseModel: medicalFileVM.patientSickLeaveList.first, | ||||||
|  |                                       isLoading: false, | ||||||
|  |                                     ).paddingSymmetrical(24.h, 0.0), | ||||||
|  |                                   ), | ||||||
|  |                                 ), | ||||||
|  |                               ) | ||||||
|  |                             : SizedBox.shrink(); | ||||||
|  |                   }, | ||||||
|  |                   separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 8.h), | ||||||
|  |                 ), | ||||||
|  |                 SizedBox(height: 60.h), | ||||||
|  |               ], | ||||||
|  |             ); | ||||||
|  |           }), | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,181 @@ | |||||||
|  | import 'dart:async'; | ||||||
|  | 
 | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/app_assets.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/date_util.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/theme/colors.dart'; | ||||||
|  | import 'package:provider/provider.dart'; | ||||||
|  | 
 | ||||||
|  | import '../../widgets/chip/app_custom_chip_widget.dart'; | ||||||
|  | 
 | ||||||
|  | class VaccineListPage extends StatefulWidget { | ||||||
|  |   const VaccineListPage({super.key}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   State<VaccineListPage> createState() => _VaccineListPageState(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class _VaccineListPageState extends State<VaccineListPage> { | ||||||
|  |   late MedicalFileViewModel medicalFileViewModel; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     scheduleMicrotask(() { | ||||||
|  |       medicalFileViewModel.setIsPatientVaccineListLoading(true); | ||||||
|  |       medicalFileViewModel.getPatientVaccinesList(onError: (error) { | ||||||
|  |         Navigator.of(context).pop(); | ||||||
|  |         Navigator.of(context).pop(); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |     super.initState(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     medicalFileViewModel = Provider.of<MedicalFileViewModel>(context, listen: false); | ||||||
|  |     return Scaffold( | ||||||
|  |       backgroundColor: AppColors.bgScaffoldColor, | ||||||
|  |       body: CollapsingListView( | ||||||
|  |         title: "Vaccine Info".needTranslation, | ||||||
|  |         child: SingleChildScrollView( | ||||||
|  |           child: Consumer<MedicalFileViewModel>(builder: (context, medicalFileVM, child) { | ||||||
|  |             return Column( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |               children: [ | ||||||
|  |                 SizedBox(height: 16.h), | ||||||
|  |                 ListView.separated( | ||||||
|  |                   scrollDirection: Axis.vertical, | ||||||
|  |                   itemCount: medicalFileVM.isPatientVaccineListLoading ? 5 : medicalFileVM.patientVaccineList.length, | ||||||
|  |                   shrinkWrap: true, | ||||||
|  |                   physics: NeverScrollableScrollPhysics(), | ||||||
|  |                   padding: EdgeInsets.only(left: 24.h, right: 24.h), | ||||||
|  |                   itemBuilder: (context, index) { | ||||||
|  |                     return medicalFileVM.isPatientVaccineListLoading | ||||||
|  |                         ? Container( | ||||||
|  |                             decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |                               color: AppColors.whiteColor, | ||||||
|  |                               borderRadius: 20.h, | ||||||
|  |                               hasShadow: true, | ||||||
|  |                             ), | ||||||
|  |                             child: Padding( | ||||||
|  |                               padding: EdgeInsets.all(14.h), | ||||||
|  |                               child: Column( | ||||||
|  |                                 crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                 children: [ | ||||||
|  |                                   Row( | ||||||
|  |                                     crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                     children: [ | ||||||
|  |                                       Image.network( | ||||||
|  |                                         "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", | ||||||
|  |                                         width: 63.h, | ||||||
|  |                                         height: 63.h, | ||||||
|  |                                         fit: BoxFit.fill, | ||||||
|  |                                       ).circle(100).toShimmer2(isShow: true), | ||||||
|  |                                       SizedBox(width: 16.h), | ||||||
|  |                                       Expanded( | ||||||
|  |                                         child: Column( | ||||||
|  |                                           crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                           children: [ | ||||||
|  |                                             "Dr John Smith".toText16(isBold: true).toShimmer2(isShow: true), | ||||||
|  |                                             SizedBox(height: 8.h), | ||||||
|  |                                             Wrap( | ||||||
|  |                                               direction: Axis.horizontal, | ||||||
|  |                                               spacing: 3.h, | ||||||
|  |                                               runSpacing: 4.h, | ||||||
|  |                                               children: [ | ||||||
|  |                                                 AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), | ||||||
|  |                                                 AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), | ||||||
|  |                                               ], | ||||||
|  |                                             ), | ||||||
|  |                                           ], | ||||||
|  |                                         ), | ||||||
|  |                                       ), | ||||||
|  |                                     ], | ||||||
|  |                                   ), | ||||||
|  |                                 ], | ||||||
|  |                               ), | ||||||
|  |                             ), | ||||||
|  |                           ) | ||||||
|  |                         : AnimationConfiguration.staggeredList( | ||||||
|  |                             position: index, | ||||||
|  |                             duration: const Duration(milliseconds: 1000), | ||||||
|  |                             child: SlideAnimation( | ||||||
|  |                               verticalOffset: 100.0, | ||||||
|  |                               child: FadeInAnimation( | ||||||
|  |                                 child: Container( | ||||||
|  |                                   decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |                                     color: AppColors.whiteColor, | ||||||
|  |                                     borderRadius: 20.h, | ||||||
|  |                                     hasShadow: true, | ||||||
|  |                                   ), | ||||||
|  |                                   child: Padding( | ||||||
|  |                                     padding: EdgeInsets.all(14.h), | ||||||
|  |                                     child: Column( | ||||||
|  |                                       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                       children: [ | ||||||
|  |                                         Row( | ||||||
|  |                                           crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                           children: [ | ||||||
|  |                                             // Image.network( | ||||||
|  |                                             //   medicalFileVM.patientVaccineList[index].doctorImageURL, | ||||||
|  |                                             //   width: 63.h, | ||||||
|  |                                             //   height: 63.h, | ||||||
|  |                                             //   fit: BoxFit.fill, | ||||||
|  |                                             // ).circle(100).toShimmer2(isShow: false), | ||||||
|  |                                             SizedBox(width: 16.h), | ||||||
|  |                                             Expanded( | ||||||
|  |                                               child: Column( | ||||||
|  |                                                 crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                                 children: [ | ||||||
|  |                                                   (medicalFileVM.patientVaccineList[index].doctorName).toString().toText16(isBold: true).toShimmer2(isShow: false), | ||||||
|  |                                                   SizedBox(height: 8.h), | ||||||
|  |                                                   Wrap( | ||||||
|  |                                                     direction: Axis.horizontal, | ||||||
|  |                                                     spacing: 3.h, | ||||||
|  |                                                     runSpacing: 4.h, | ||||||
|  |                                                     children: [ | ||||||
|  |                                                       AppCustomChipWidget( | ||||||
|  |                                                           icon: AppAssets.doctor_calendar_icon, | ||||||
|  |                                                           labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(medicalFileVM.patientVaccineList[index].vaccinationDate), false)), | ||||||
|  |                                                       AppCustomChipWidget(labelText: medicalFileVM.patientVaccineList[index].vaccineName).toShimmer2(isShow: false, width: 16.h), | ||||||
|  |                                                       AppCustomChipWidget(labelText: medicalFileVM.patientVaccineList[index].clinicName).toShimmer2(isShow: false, width: 16.h), | ||||||
|  |                                                       AppCustomChipWidget(labelText: medicalFileVM.patientVaccineList[index].projectName).toShimmer2(isShow: false, width: 16.h), | ||||||
|  |                                                     ], | ||||||
|  |                                                   ), | ||||||
|  |                                                 ], | ||||||
|  |                                               ), | ||||||
|  |                                             ), | ||||||
|  |                                           ], | ||||||
|  |                                         ), | ||||||
|  |                                         // Row( | ||||||
|  |                                         //   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                                         //   children: [ | ||||||
|  |                                         //     "".toText16(), | ||||||
|  |                                         //     Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor), | ||||||
|  |                                         //   ], | ||||||
|  |                                         // ), | ||||||
|  |                                       ], | ||||||
|  |                                     ), | ||||||
|  |                                   ), | ||||||
|  |                                 ), | ||||||
|  |                               ), | ||||||
|  |                             ), | ||||||
|  |                           ); | ||||||
|  |                   }, | ||||||
|  |                   separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), | ||||||
|  |                 ), | ||||||
|  |                 SizedBox(height: 60.h), | ||||||
|  |               ], | ||||||
|  |             ); | ||||||
|  |           }), | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,159 @@ | |||||||
|  | import 'package:easy_localization/easy_localization.dart'; | ||||||
|  | import 'package:flutter/cupertino.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/app_assets.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/app_state.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/dependencies.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/date_util.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/theme/colors.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; | ||||||
|  | import 'package:open_filex/open_filex.dart'; | ||||||
|  | import 'package:share_plus/share_plus.dart'; | ||||||
|  | 
 | ||||||
|  | class PatientMedicalReportCard extends StatelessWidget { | ||||||
|  |   PatientMedicalReportCard({super.key, required this.patientMedicalReportResponseModel, required this.medicalFileViewModel, this.isLoading = false}); | ||||||
|  | 
 | ||||||
|  |   PatientMedicalReportResponseModel patientMedicalReportResponseModel; | ||||||
|  |   MedicalFileViewModel medicalFileViewModel; | ||||||
|  | 
 | ||||||
|  |   bool isLoading = true; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     AppState _appState = getIt.get<AppState>(); | ||||||
|  |     return Container( | ||||||
|  |       decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |         color: AppColors.whiteColor, | ||||||
|  |         borderRadius: 20.h, | ||||||
|  |         hasShadow: true, | ||||||
|  |       ), | ||||||
|  |       child: Padding( | ||||||
|  |         padding: EdgeInsets.all(16.h), | ||||||
|  |         child: Column( | ||||||
|  |           crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |           children: [ | ||||||
|  |             Row( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |               children: [ | ||||||
|  |                 Image.network( | ||||||
|  |                   isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : patientMedicalReportResponseModel.doctorImageURL!, | ||||||
|  |                   width: 63.h, | ||||||
|  |                   height: 63.h, | ||||||
|  |                   fit: BoxFit.fill, | ||||||
|  |                 ).circle(100).toShimmer2(isShow: isLoading), | ||||||
|  |                 SizedBox(width: 16.h), | ||||||
|  |                 Expanded( | ||||||
|  |                   child: Column( | ||||||
|  |                     crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                     children: [ | ||||||
|  |                       (isLoading ? "" : patientMedicalReportResponseModel.doctorName!).toText16(isBold: true).toShimmer2(isShow: isLoading), | ||||||
|  |                       SizedBox(height: 4.h), | ||||||
|  |                       Wrap( | ||||||
|  |                         direction: Axis.horizontal, | ||||||
|  |                         spacing: 3.h, | ||||||
|  |                         runSpacing: 4.h, | ||||||
|  |                         children: [ | ||||||
|  |                           AppCustomChipWidget(labelText: isLoading ? "" : patientMedicalReportResponseModel.clinicDescription!).toShimmer2(isShow: isLoading), | ||||||
|  |                           AppCustomChipWidget(labelText: isLoading ? "" : patientMedicalReportResponseModel.projectName!).toShimmer2(isShow: isLoading), | ||||||
|  |                           AppCustomChipWidget( | ||||||
|  |                                   icon: AppAssets.doctor_calendar_icon, | ||||||
|  |                                   labelText: isLoading | ||||||
|  |                                       ? "" | ||||||
|  |                                       : "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientMedicalReportResponseModel.requestDate), false)}, ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientMedicalReportResponseModel.requestDate), false)}") | ||||||
|  |                               .toShimmer2(isShow: isLoading), | ||||||
|  |                           AppCustomChipWidget( | ||||||
|  |                                   icon: AppAssets.rating_icon, iconColor: AppColors.ratingColorYellow, labelText: isLoading ? "" : "Rating: ${patientMedicalReportResponseModel.decimalDoctorRate}") | ||||||
|  |                               .toShimmer2(isShow: isLoading), | ||||||
|  |                         ], | ||||||
|  |                       ), | ||||||
|  |                     ], | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |             patientMedicalReportResponseModel.status == 2 | ||||||
|  |                 ? Padding( | ||||||
|  |                     padding: EdgeInsets.only(top: 16.h), | ||||||
|  |                     child: Row( | ||||||
|  |                       children: [ | ||||||
|  |                         Expanded( | ||||||
|  |                           child: CustomButton( | ||||||
|  |                             text: "Share", | ||||||
|  |                             onPressed: () { | ||||||
|  |                               getMedicalReportPDF(true, context, _appState); | ||||||
|  |                             }, | ||||||
|  |                             backgroundColor: AppColors.secondaryLightRedColor, | ||||||
|  |                             borderColor: AppColors.secondaryLightRedColor, | ||||||
|  |                             textColor: AppColors.primaryRedColor, | ||||||
|  |                             fontSize: 14, | ||||||
|  |                             fontWeight: FontWeight.w500, | ||||||
|  |                             borderRadius: 12.h, | ||||||
|  |                             height: 40.h, | ||||||
|  |                             icon: AppAssets.download_1, | ||||||
|  |                             iconColor: AppColors.primaryRedColor, | ||||||
|  |                             iconSize: 16.h, | ||||||
|  |                           ).toShimmer2(isShow: isLoading), | ||||||
|  |                         ), | ||||||
|  |                         SizedBox(width: 16.h), | ||||||
|  |                         Expanded( | ||||||
|  |                           child: CustomButton( | ||||||
|  |                             text: "Download", | ||||||
|  |                             onPressed: () async { | ||||||
|  |                               getMedicalReportPDF(false, context, _appState); | ||||||
|  |                             }, | ||||||
|  |                             backgroundColor: AppColors.secondaryLightRedColor, | ||||||
|  |                             borderColor: AppColors.secondaryLightRedColor, | ||||||
|  |                             textColor: AppColors.primaryRedColor, | ||||||
|  |                             fontSize: 14, | ||||||
|  |                             fontWeight: FontWeight.w500, | ||||||
|  |                             borderRadius: 12.h, | ||||||
|  |                             height: 40.h, | ||||||
|  |                             icon: AppAssets.download_1, | ||||||
|  |                             iconColor: AppColors.primaryRedColor, | ||||||
|  |                             iconSize: 16.h, | ||||||
|  |                           ).toShimmer2(isShow: isLoading), | ||||||
|  |                         ), | ||||||
|  |                       ], | ||||||
|  |                     ), | ||||||
|  |                   ) | ||||||
|  |                 : SizedBox.shrink() | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   void getMedicalReportPDF(bool isShare, BuildContext context, AppState _appState) async { | ||||||
|  |     LoaderBottomSheet.showLoader(); | ||||||
|  |     await medicalFileViewModel.getPatientMedicalReportPDF(patientMedicalReportResponseModel, _appState.getAuthenticatedUser()!).then((val) async { | ||||||
|  |       LoaderBottomSheet.hideLoader(); | ||||||
|  |       if (medicalFileViewModel.patientMedicalReportPDFBase64.isNotEmpty) { | ||||||
|  |         String path = await Utils.createFileFromString(medicalFileViewModel.patientMedicalReportPDFBase64, "pdf"); | ||||||
|  |         if (isShare) { | ||||||
|  |           Share.shareXFiles([XFile(path)], text: "Medical Report"); | ||||||
|  |         } else { | ||||||
|  |           try { | ||||||
|  |             OpenFilex.open(path); | ||||||
|  |           } catch (ex) { | ||||||
|  |             showCommonBottomSheetWithoutHeight( | ||||||
|  |               context, | ||||||
|  |               child: Utils.getErrorWidget(loadingText: "Cannot open file".needTranslation), | ||||||
|  |               callBackFunc: () {}, | ||||||
|  |               isFullScreen: false, | ||||||
|  |               isCloseButtonVisible: true, | ||||||
|  |             ); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,191 @@ | |||||||
|  | import 'package:easy_localization/easy_localization.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/app_assets.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/app_state.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/dependencies.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/date_util.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/core/utils/utils.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/presentation/medical_file/patient_sickleaves_list_page.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/theme/colors.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; | ||||||
|  | import 'package:open_filex/open_filex.dart'; | ||||||
|  | import 'package:provider/provider.dart'; | ||||||
|  | 
 | ||||||
|  | class PatientSickLeaveCard extends StatelessWidget { | ||||||
|  |   PatientSickLeaveCard({super.key, required this.patientSickLeavesResponseModel, this.isLoading = false}); | ||||||
|  | 
 | ||||||
|  |   late MedicalFileViewModel medicalFileViewModel; | ||||||
|  |   PatientSickLeavesResponseModel patientSickLeavesResponseModel; | ||||||
|  |   bool isLoading; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     AppState _appState = getIt.get<AppState>(); | ||||||
|  |     medicalFileViewModel = Provider.of<MedicalFileViewModel>(context, listen: false); | ||||||
|  |     return Container( | ||||||
|  |       decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24, hasShadow: true), | ||||||
|  |       child: Padding( | ||||||
|  |         padding: EdgeInsets.all(16.h), | ||||||
|  |         child: Column( | ||||||
|  |           crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |           children: [ | ||||||
|  |             Row( | ||||||
|  |               mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |               children: [ | ||||||
|  |                 "${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}".toText16(isBold: true), | ||||||
|  |                 AppCustomChipWidget( | ||||||
|  |                   labelText: isLoading ? "" : getStatusText(context), | ||||||
|  |                   backgroundColor: getStatusColor().withOpacity(0.15), | ||||||
|  |                   textColor: getStatusColor(), | ||||||
|  |                 ).toShimmer2(isShow: isLoading, width: 100.h), | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |             SizedBox(height: 16.h), | ||||||
|  |             Row( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |               children: [ | ||||||
|  |                 Image.network( | ||||||
|  |                   isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : patientSickLeavesResponseModel.doctorImageURL!, | ||||||
|  |                   width: 30.h, | ||||||
|  |                   height: 30.h, | ||||||
|  |                   fit: BoxFit.fill, | ||||||
|  |                 ).circle(100).toShimmer2(isShow: isLoading), | ||||||
|  |                 SizedBox(width: 16.h), | ||||||
|  |                 Expanded( | ||||||
|  |                   child: Column( | ||||||
|  |                     crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                     children: [ | ||||||
|  |                       (isLoading ? "" : patientSickLeavesResponseModel.doctorName!).toText16(isBold: true).toShimmer2(isShow: isLoading), | ||||||
|  |                       SizedBox(height: 8.h), | ||||||
|  |                       Wrap( | ||||||
|  |                         direction: Axis.horizontal, | ||||||
|  |                         spacing: 3.h, | ||||||
|  |                         runSpacing: 4.h, | ||||||
|  |                         children: [ | ||||||
|  |                           AppCustomChipWidget( | ||||||
|  |                             icon: AppAssets.doctor_calendar_icon, | ||||||
|  |                             labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientSickLeavesResponseModel.appointmentDate), false), | ||||||
|  |                           ).toShimmer2(isShow: isLoading), | ||||||
|  |                           AppCustomChipWidget(labelText: isLoading ? "Pending Activation" : patientSickLeavesResponseModel.clinicName!).toShimmer2(isShow: isLoading), | ||||||
|  |                         ], | ||||||
|  |                       ), | ||||||
|  |                     ], | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |             SizedBox(height: 16.h), | ||||||
|  |             Row( | ||||||
|  |               children: [ | ||||||
|  |                 isLoading | ||||||
|  |                     ? Container().toShimmer2(isShow: true, height: 40.h, width: 100.h, radius: 12.h) | ||||||
|  |                     : Expanded( | ||||||
|  |                         flex: 6, | ||||||
|  |                         child: CustomButton( | ||||||
|  |                           text: "Download Report".needTranslation, | ||||||
|  |                           onPressed: () async { | ||||||
|  |                             LoaderBottomSheet.showLoader(); | ||||||
|  |                             await medicalFileViewModel.getPatientSickLeavePDF(patientSickLeavesResponseModel, _appState.getAuthenticatedUser()!).then((val) async { | ||||||
|  |                               LoaderBottomSheet.hideLoader(); | ||||||
|  |                               if (medicalFileViewModel.patientSickLeavePDFBase64.isNotEmpty) { | ||||||
|  |                                 String path = await Utils.createFileFromString(medicalFileViewModel.patientSickLeavePDFBase64, "pdf"); | ||||||
|  |                                 try { | ||||||
|  |                                   OpenFilex.open(path); | ||||||
|  |                                 } catch (ex) { | ||||||
|  |                                   showCommonBottomSheetWithoutHeight( | ||||||
|  |                                     context, | ||||||
|  |                                     child: Utils.getErrorWidget(loadingText: "Cannot open file".needTranslation), | ||||||
|  |                                     callBackFunc: () {}, | ||||||
|  |                                     isFullScreen: false, | ||||||
|  |                                     isCloseButtonVisible: true, | ||||||
|  |                                   ); | ||||||
|  |                                 } | ||||||
|  |                               } | ||||||
|  |                             }); | ||||||
|  |                           }, | ||||||
|  |                           backgroundColor: AppColors.secondaryLightRedColor, | ||||||
|  |                           borderColor: AppColors.secondaryLightRedColor, | ||||||
|  |                           textColor: AppColors.primaryRedColor, | ||||||
|  |                           fontSize: 14, | ||||||
|  |                           fontWeight: FontWeight.w500, | ||||||
|  |                           borderRadius: 12, | ||||||
|  |                           padding: EdgeInsets.fromLTRB(10, 0, 10, 0), | ||||||
|  |                           height: 40.h, | ||||||
|  |                           icon: AppAssets.download, | ||||||
|  |                           iconColor: AppColors.primaryRedColor, | ||||||
|  |                           iconSize: 14.h, | ||||||
|  |                         ).toShimmer2(isShow: isLoading), | ||||||
|  |                       ), | ||||||
|  |                 SizedBox(width: 8.h), | ||||||
|  |                 Expanded( | ||||||
|  |                   flex: 1, | ||||||
|  |                   child: Container( | ||||||
|  |                     height: 40.h, | ||||||
|  |                     width: 40.h, | ||||||
|  |                     decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |                       color: AppColors.textColor, | ||||||
|  |                       borderRadius: 10.h, | ||||||
|  |                     ), | ||||||
|  |                     child: Padding( | ||||||
|  |                       padding: EdgeInsets.all(10.h), | ||||||
|  |                       child: Utils.buildSvgWithAssets( | ||||||
|  |                         icon: AppAssets.forward_arrow_icon, | ||||||
|  |                         width: 10.h, | ||||||
|  |                         height: 10.h, | ||||||
|  |                         fit: BoxFit.contain, | ||||||
|  |                       ), | ||||||
|  |                     ), | ||||||
|  |                   ).toShimmer2(isShow: isLoading).onPress(() { | ||||||
|  |                     Navigator.of(context).push( | ||||||
|  |                       FadePage( | ||||||
|  |                         page: PatientSickleavesListPage(), | ||||||
|  |                       ), | ||||||
|  |                     ); | ||||||
|  |                   }), | ||||||
|  |                 ), | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   String getStatusText(BuildContext context) { | ||||||
|  |     String statusText = ""; | ||||||
|  |     if (patientSickLeavesResponseModel.status == 1) { | ||||||
|  |       statusText = LocaleKeys.pendingActivation.tr(context: context); | ||||||
|  |     } else if (patientSickLeavesResponseModel.status == 2) { | ||||||
|  |       statusText = LocaleKeys.ready.tr(context: context); | ||||||
|  |     } else if (patientSickLeavesResponseModel.status == 3) { | ||||||
|  |       statusText = LocaleKeys.awaitingApproval.tr(context: context); | ||||||
|  |     } else { | ||||||
|  |       statusText = ""; | ||||||
|  |     } | ||||||
|  |     return statusText; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Color getStatusColor() { | ||||||
|  |     Color statusColor = Colors.white; | ||||||
|  |     if (patientSickLeavesResponseModel.status == 1) { | ||||||
|  |       statusColor = Color(0xffCC9B14); | ||||||
|  |     } else if (patientSickLeavesResponseModel.status == 2) { | ||||||
|  |       statusColor = Color(0xff359846); | ||||||
|  |     } else if (patientSickLeavesResponseModel.status == 3) { | ||||||
|  |       statusColor = Color(0xffD02127); | ||||||
|  |     } else { | ||||||
|  |       statusColor = Colors.white; | ||||||
|  |     } | ||||||
|  |     return statusColor; | ||||||
|  |   } | ||||||
|  | } | ||||||
					Loading…
					
					
				
		Reference in New Issue