swipe module added
| After Width: | Height: | Size: 18 KiB | 
| After Width: | Height: | Size: 19 KiB | 
| @ -0,0 +1,12 @@ | ||||
| <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <g clip-path="url(#clip0_3315_4264)"> | ||||
| <path d="M33.7512 39.2845L30.7402 37.2921C34.1004 32.1687 35.893 26.1529 35.893 20C35.893 13.8471 34.1004 7.8313 30.7402 2.70797L33.7512 0.715515C37.4393 6.45029 39.4303 13.1362 39.4889 19.9824V20.0186C39.4303 26.8645 37.4393 33.5501 33.7512 39.2845Z" fill="#3B3D4A" stroke="#3B3D4A"/> | ||||
| <path d="M26.594 34.9749L23.6074 32.9463C26.1938 29.1382 27.5786 24.6234 27.5786 19.9995C27.5786 15.3756 26.1938 10.8608 23.6074 7.05269L26.594 5.02405C29.5196 9.45119 31.1108 14.6463 31.1732 19.9752V20.0238C31.1109 25.3527 29.5197 30.5478 26.594 34.9749Z" fill="#3B3D4A" stroke="#3B3D4A"/> | ||||
| <path d="M20.1618 30.5113L4.30923 18.1512C4.17465 18.9366 4.10643 19.7322 4.1053 20.5294C4.21082 22.3475 4.75606 24.1113 5.6929 25.6651L2.67371 27.6441C1.36309 25.4998 0.618012 23.0498 0.509998 20.5294C0.498918 18.4074 0.883985 16.3024 1.64487 14.3256L2.56256 12.1904L18.667 24.7469C19.1283 23.2202 19.3506 21.6296 19.3257 20.0331C19.2579 16.9657 18.291 13.9882 16.5481 11.4801L19.496 9.39459C21.6466 12.4937 22.8386 16.172 22.9199 19.9607C22.9601 22.8932 22.3404 25.7964 21.108 28.4495L20.1618 30.5113Z" fill="#3B3D4A" stroke="#3B3D4A"/> | ||||
| </g> | ||||
| <defs> | ||||
| <clipPath id="clip0_3315_4264"> | ||||
| <rect width="40" height="40" fill="white"/> | ||||
| </clipPath> | ||||
| </defs> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.3 KiB | 
| @ -0,0 +1,11 @@ | ||||
| <svg width="82" height="82" viewBox="0 0 82 82" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path d="M62.855 20.7976C55.0013 4.69411 33.6267 -0.701705 18.8103 9.36498C17.6396 10.1603 17.3354 11.754 18.1308 12.9246C18.9261 14.0952 20.5198 14.3994 21.6904 13.6041C33.9953 5.24389 51.7999 9.8215 58.2486 23.0442C58.869 24.3162 60.4031 24.8445 61.6751 24.2241C62.9471 23.6037 63.4754 22.0697 62.855 20.7976Z" fill="#54C166"/> | ||||
| <path d="M35.8615 17.9308C34.4463 17.9308 33.299 19.0781 33.299 20.4933C33.299 21.9086 34.4463 23.0558 35.8615 23.0558C41.8738 23.0558 46.9587 28.2109 46.9587 34.8364C46.9587 36.2516 48.106 37.3989 49.5212 37.3989C50.9365 37.3989 52.0837 36.2516 52.0837 34.8364C52.0837 25.619 44.9371 17.9308 35.8615 17.9308Z" fill="#54C166"/> | ||||
| <path d="M13.4347 23.1255C14.0502 21.8511 13.516 20.3191 12.2417 19.7036C10.9673 19.0881 9.43523 19.6223 8.81975 20.8967C6.99799 24.6687 5.97949 28.8838 5.97949 33.3255V48.5317C5.97949 58.4772 11.0762 67.2373 18.8103 72.492C19.9809 73.2873 21.5746 72.9831 22.3699 71.8125C23.1652 70.6419 22.861 69.0482 21.6904 68.2528C15.2692 63.8901 11.1045 56.672 11.1045 48.5317V33.3255C11.1045 29.6755 11.9399 26.2206 13.4347 23.1255Z" fill="#54C166"/> | ||||
| <path d="M25.8509 29.7456C26.4343 28.4562 25.8619 26.938 24.5725 26.3547C23.2831 25.7713 21.7649 26.3437 21.1816 27.6331C20.1904 29.8241 19.6392 32.2679 19.6392 34.8364V47.1305C19.6392 56.3479 26.7857 64.0361 35.8615 64.0361C36.5507 64.0361 37.2321 63.9913 37.9024 63.9033C39.3056 63.7191 40.2938 62.4323 40.1097 61.0291C39.9255 59.6259 38.6386 58.6377 37.2355 58.8219C36.7871 58.8807 36.3285 58.9111 35.8615 58.9111C29.8491 58.9111 24.7642 53.756 24.7642 47.1305V34.8364C24.7642 33.0052 25.1564 31.2808 25.8509 29.7456Z" fill="#54C166"/> | ||||
| <path d="M65.7435 35.2916C65.7435 33.8764 64.5962 32.7291 63.181 32.7291C61.7657 32.7291 60.6185 33.8764 60.6185 35.2916V39.2759C60.6185 40.6912 61.7657 41.8384 63.181 41.8384C64.5962 41.8384 65.7435 40.6912 65.7435 39.2759V35.2916Z" fill="#54C166"/> | ||||
| <path d="M38.424 35.8609C38.424 34.4457 37.2767 33.2984 35.8615 33.2984C34.4463 33.2984 33.299 34.4457 33.299 35.8609V46.106C33.299 47.5212 34.4463 48.6685 35.8615 48.6685C37.2767 48.6685 38.424 47.5212 38.424 46.106V35.8609Z" fill="#54C166"/> | ||||
| <path d="M41.4787 77.1333C42.8673 76.86 43.7714 75.5127 43.4982 74.1242C43.2249 72.7356 41.8777 71.8314 40.4891 72.1047C37.8559 72.6229 35.1017 72.7236 32.3125 72.3348C30.9108 72.1394 29.6161 73.1173 29.4207 74.5189C29.2253 75.9206 30.2032 77.2153 31.6049 77.4107C34.9745 77.8804 38.3024 77.7584 41.4787 77.1333Z" fill="#54C166"/> | ||||
| <path d="M65.8112 60.5701C66.9947 59.794 67.325 58.2055 66.5489 57.0221C65.7728 55.8386 64.1843 55.5083 63.0008 56.2844C60.5195 57.9116 58.8881 59.9815 57.8293 61.6633C57.3764 61.3016 56.8771 60.9661 56.3573 60.7166C55.0814 60.1041 53.5507 60.642 52.9383 61.9178C52.3258 63.1937 52.8636 64.7244 54.1395 65.3369C54.3092 65.4183 54.6578 65.6561 55.0755 66.0616C55.3759 66.3532 55.6295 66.6513 55.8089 66.9002C55.8478 67.0018 55.8948 67.108 55.9518 67.2149C56.0821 67.4592 56.3952 67.959 57.0262 68.3006C57.7671 68.7016 58.5485 68.6753 59.1444 68.4634C59.6447 68.2855 59.9676 67.9997 60.1091 67.8635C60.2719 67.7069 60.3881 67.5572 60.457 67.4628C60.5935 67.2758 60.7003 67.0881 60.7655 66.9698C60.8682 66.7835 60.9917 66.5382 61.105 66.313L61.1943 66.1362C61.3455 65.8376 61.5162 65.5073 61.7173 65.1495C62.5272 63.7082 63.7899 61.8956 65.8112 60.5701Z" fill="#54C166"/> | ||||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M59.792 45.2702C50.8289 45.2702 43.5628 52.5363 43.5628 61.4994C43.5628 70.4625 50.8289 77.7286 59.792 77.7286C68.7551 77.7286 76.0212 70.4625 76.0212 61.4994C76.0212 52.5363 68.7551 45.2702 59.792 45.2702ZM48.6878 61.4994C48.6878 55.3667 53.6593 50.3952 59.792 50.3952C65.9247 50.3952 70.8962 55.3667 70.8962 61.4994C70.8962 67.6321 65.9247 72.6036 59.792 72.6036C53.6593 72.6036 48.6878 67.6321 48.6878 61.4994Z" fill="#54C166"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.8 KiB | 
| @ -0,0 +1,8 @@ | ||||
| <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path d="M9.34246 3.65546C15.1272 -0.274716 23.4724 1.83188 26.5387 8.11895C26.7808 8.61535 26.5746 9.21401 26.0782 9.45611C25.5818 9.69821 24.9832 9.49206 24.7411 8.99567C22.2231 3.83284 15.271 2.04549 10.4664 5.30977C10.0096 5.62014 9.38765 5.50141 9.07728 5.04459C8.76691 4.58776 8.88564 3.96583 9.34246 3.65546Z" fill="#3DA5E5"/> | ||||
| <path d="M6.77731 7.69205C7.27463 7.93225 7.48307 8.53012 7.24287 9.02744C6.6592 10.2359 6.33301 11.5849 6.33301 13.01V18.947C6.33301 22.1254 7.95917 24.9438 10.4664 26.6472C10.9232 26.9576 11.042 27.5795 10.7316 28.0364C10.4212 28.4932 9.79928 28.6119 9.34246 28.3015C6.32289 26.25 4.33301 22.8298 4.33301 18.947V13.01C4.33301 11.2759 4.73065 9.63029 5.44193 8.15762C5.68212 7.6603 6.27999 7.45186 6.77731 7.69205Z" fill="#3DA5E5"/> | ||||
| <path d="M26.6663 12.7777C27.2186 12.7777 27.6663 13.2254 27.6663 13.7777V18.947C27.6663 25.835 21.207 31.1789 14.3379 30.2219C13.7909 30.1457 13.4092 29.6404 13.4854 29.0934C13.5616 28.5464 14.0669 28.1648 14.6139 28.241C20.3494 29.0401 25.6663 24.5519 25.6663 18.947V13.7777C25.6663 13.2254 26.1141 12.7777 26.6663 12.7777Z" fill="#3DA5E5"/> | ||||
| <path d="M14.9997 7.99974C14.9997 7.44745 15.4474 6.99974 15.9997 6.99974C19.5429 6.99974 22.333 10.0012 22.333 13.5997C22.333 14.152 21.8853 14.5997 21.333 14.5997C20.7807 14.5997 20.333 14.152 20.333 13.5997C20.333 11.0127 18.3475 8.99973 15.9997 8.99973C15.4474 8.99973 14.9997 8.55202 14.9997 7.99974Z" fill="#3DA5E5"/> | ||||
| <path d="M11.5918 10.2886C12.095 10.5163 12.3183 11.1088 12.0907 11.6119C11.8195 12.2114 11.6663 12.8847 11.6663 13.5997V18.3997C11.6663 20.9868 13.6519 22.9997 15.9997 22.9997C18.3475 22.9997 20.333 20.9868 20.333 18.3997C20.333 17.8474 20.7807 17.3997 21.333 17.3997C21.8853 17.3997 22.333 17.8474 22.333 18.3997C22.333 21.9983 19.5429 24.9997 15.9997 24.9997C12.4565 24.9997 9.66634 21.9983 9.66634 18.3997V13.5997C9.66634 12.597 9.8815 11.6429 10.2685 10.7875C10.4961 10.2844 11.0886 10.061 11.5918 10.2886Z" fill="#3DA5E5"/> | ||||
| <path d="M16.9997 13.9997C16.9997 13.4475 16.552 12.9997 15.9997 12.9997C15.4474 12.9997 14.9997 13.4475 14.9997 13.9997V17.9997C14.9997 18.552 15.4474 18.9997 15.9997 18.9997C16.552 18.9997 16.9997 18.552 16.9997 17.9997V13.9997Z" fill="#3DA5E5"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.3 KiB | 
| @ -0,0 +1,14 @@ | ||||
| <svg width="248" height="248" viewBox="0 0 248 248" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <circle cx="124" cy="124" r="124" fill="black" fill-opacity="0.02"/> | ||||
| <circle cx="124" cy="124" r="107" fill="black" fill-opacity="0.02"/> | ||||
| <circle cx="124" cy="124" r="87" fill="white"/> | ||||
| <path d="M145.855 103.798C138.001 87.6941 116.627 82.2983 101.81 92.365C100.64 93.1603 100.335 94.754 101.131 95.9246C101.926 97.0952 103.52 97.3994 104.69 96.6041C116.995 88.2439 134.8 92.8215 141.249 106.044C141.869 107.316 143.403 107.844 144.675 107.224C145.947 106.604 146.475 105.07 145.855 103.798Z" fill="#54C166"/> | ||||
| <path d="M118.861 100.931C117.446 100.931 116.299 102.078 116.299 103.493C116.299 104.909 117.446 106.056 118.861 106.056C124.874 106.056 129.959 111.211 129.959 117.836C129.959 119.252 131.106 120.399 132.521 120.399C133.936 120.399 135.084 119.252 135.084 117.836C135.084 108.619 127.937 100.931 118.861 100.931Z" fill="#54C166"/> | ||||
| <path d="M96.4347 106.126C97.0502 104.851 96.516 103.319 95.2417 102.704C93.9673 102.088 92.4352 102.622 91.8198 103.897C89.998 107.669 88.9795 111.884 88.9795 116.325V131.532C88.9795 141.477 94.0762 150.237 101.81 155.492C102.981 156.287 104.575 155.983 105.37 154.812C106.165 153.642 105.861 152.048 104.69 151.253C98.2692 146.89 94.1045 139.672 94.1045 131.532V116.325C94.1045 112.676 94.9399 109.221 96.4347 106.126Z" fill="#54C166"/> | ||||
| <path d="M108.851 112.746C109.434 111.456 108.862 109.938 107.572 109.355C106.283 108.771 104.765 109.344 104.182 110.633C103.19 112.824 102.639 115.268 102.639 117.836V130.13C102.639 139.348 109.786 147.036 118.861 147.036C119.551 147.036 120.232 146.991 120.902 146.903C122.306 146.719 123.294 145.432 123.11 144.029C122.925 142.626 121.639 141.638 120.235 141.822C119.787 141.881 119.329 141.911 118.861 141.911C112.849 141.911 107.764 136.756 107.764 130.13V117.836C107.764 116.005 108.156 114.281 108.851 112.746Z" fill="#54C166"/> | ||||
| <path d="M148.743 118.292C148.743 116.876 147.596 115.729 146.181 115.729C144.766 115.729 143.618 116.876 143.618 118.292V122.276C143.618 123.691 144.766 124.838 146.181 124.838C147.596 124.838 148.743 123.691 148.743 122.276V118.292Z" fill="#54C166"/> | ||||
| <path d="M121.424 118.861C121.424 117.446 120.277 116.298 118.861 116.298C117.446 116.298 116.299 117.446 116.299 118.861V129.106C116.299 130.521 117.446 131.668 118.861 131.668C120.277 131.668 121.424 130.521 121.424 129.106V118.861Z" fill="#54C166"/> | ||||
| <path d="M124.479 160.133C125.867 159.86 126.771 158.513 126.498 157.124C126.225 155.736 124.878 154.831 123.489 155.105C120.856 155.623 118.102 155.724 115.312 155.335C113.911 155.139 112.616 156.117 112.421 157.519C112.225 158.921 113.203 160.215 114.605 160.411C117.975 160.88 121.302 160.758 124.479 160.133Z" fill="#54C166"/> | ||||
| <path d="M148.811 143.57C149.995 142.794 150.325 141.206 149.549 140.022C148.773 138.839 147.184 138.508 146.001 139.284C143.519 140.912 141.888 142.981 140.829 144.663C140.376 144.302 139.877 143.966 139.357 143.717C138.081 143.104 136.551 143.642 135.938 144.918C135.326 146.194 135.864 147.724 137.14 148.337C137.309 148.418 137.658 148.656 138.075 149.062C138.376 149.353 138.629 149.651 138.809 149.9C138.848 150.002 138.895 150.108 138.952 150.215C139.082 150.459 139.395 150.959 140.026 151.301C140.767 151.702 141.549 151.675 142.144 151.463C142.645 151.285 142.968 151 143.109 150.864C143.272 150.707 143.388 150.557 143.457 150.463C143.593 150.276 143.7 150.088 143.766 149.97C143.868 149.783 143.992 149.538 144.105 149.313L144.194 149.136C144.345 148.838 144.516 148.507 144.717 148.15C145.527 146.708 146.79 144.896 148.811 143.57Z" fill="#54C166"/> | ||||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M142.792 128.27C133.829 128.27 126.563 135.536 126.563 144.499C126.563 153.463 133.829 160.729 142.792 160.729C151.755 160.729 159.021 153.463 159.021 144.499C159.021 135.536 151.755 128.27 142.792 128.27ZM131.688 144.499C131.688 138.367 136.659 133.395 142.792 133.395C148.925 133.395 153.896 138.367 153.896 144.499C153.896 150.632 148.925 155.604 142.792 155.604C136.659 155.604 131.688 150.632 131.688 144.499Z" fill="#54C166"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.0 KiB | 
| @ -0,0 +1,5 @@ | ||||
| <svg width="43" height="31" viewBox="0 0 43 31" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path d="M15.5596 24.422L21.3946 30.257L27.2296 24.422C25.6811 22.8762 23.5825 22.008 21.3946 22.008C19.2066 22.008 17.108 22.8762 15.5596 24.422Z" fill="#3B3D4A"/> | ||||
| <path d="M7.78027 16.643L11.6703 20.533C14.2501 17.9549 17.7481 16.5067 21.3953 16.5067C25.0425 16.5067 28.5404 17.9549 31.1203 20.533L35.0103 16.643C31.3989 13.0329 26.5016 11.0049 21.3953 11.0049C16.2889 11.0049 11.3916 13.0329 7.78027 16.643Z" fill="#3B3D4A"/> | ||||
| <path d="M0 8.86698L3.89 12.757C8.53294 8.1146 14.8298 5.50658 21.3955 5.50658C27.9612 5.50658 34.2581 8.1146 38.901 12.757L42.791 8.86698C37.1165 3.19259 29.4204 0.00476074 21.3955 0.00476074C13.3706 0.00476074 5.67446 3.19259 0 8.86698Z" fill="#3B3D4A"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 789 B | 
| @ -0,0 +1,47 @@ | ||||
| class SwipeHistory { | ||||
|   final int ?id; | ||||
|   final String? swipeTypeName; | ||||
|   final String? userName; | ||||
|   final String ?siteName; | ||||
|   final String ?pointName; | ||||
|   final String  ?swipeTime; | ||||
|   final bool ?isSuccess; | ||||
|   final String? errorMessage; | ||||
| 
 | ||||
|   SwipeHistory({ | ||||
|      this.id, | ||||
|      this.swipeTypeName, | ||||
|      this.userName, | ||||
|      this.siteName, | ||||
|      this.pointName, | ||||
|      this.swipeTime, | ||||
|      this.isSuccess, | ||||
|      this.errorMessage, | ||||
|   }); | ||||
| 
 | ||||
|   factory SwipeHistory.fromJson(Map<String, dynamic> json) { | ||||
|     return SwipeHistory( | ||||
|       id: json['id'], | ||||
|       swipeTypeName: json['swipeTypeName'], | ||||
|       userName: json['userName'], | ||||
|       siteName: json['siteName'], | ||||
|       pointName: json['pointName'], | ||||
|       swipeTime: json['swipeTime']!=null? DateTime.parse(json['swipeTime']).toIso8601String():'', | ||||
|       isSuccess: json['isSuccess'], | ||||
|       errorMessage: json['errorMessage'], | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return { | ||||
|       'id': id, | ||||
|       'swipeTypeName': swipeTypeName, | ||||
|       'userName': userName, | ||||
|       'siteName': siteName, | ||||
|       'pointName': pointName, | ||||
|       'swipeTime': swipeTime, | ||||
|       'isSuccess': isSuccess, | ||||
|       'errorMessage': errorMessage, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,47 @@ | ||||
| class SwipeTransaction { | ||||
|   final int ?id; | ||||
|   final String? swipeTypeName; | ||||
|   final String ?userName; | ||||
|   final String? siteName; | ||||
|   final String? pointName; | ||||
|   final DateTime? swipeTime; | ||||
|   final bool? isSuccess; | ||||
|   final String? errorMessage; | ||||
| 
 | ||||
|   SwipeTransaction({ | ||||
|      this.id, | ||||
|      this.swipeTypeName, | ||||
|      this.userName, | ||||
|      this.siteName, | ||||
|      this.pointName, | ||||
|      this.swipeTime, | ||||
|      this.isSuccess, | ||||
|      this.errorMessage, | ||||
|   }); | ||||
| 
 | ||||
|   factory SwipeTransaction.fromJson(Map<String, dynamic> json) { | ||||
|     return SwipeTransaction( | ||||
|       id: json['id'] as int, | ||||
|       swipeTypeName: json['swipeTypeName'] , | ||||
|       userName: json['userName'] , | ||||
|       siteName: json['siteName'] , | ||||
|       pointName: json['pointName'] , | ||||
|       swipeTime: DateTime.parse(json['swipeTime']), | ||||
|       isSuccess: json['isSuccess'] , | ||||
|       errorMessage: json['errorMessage'] , | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Map<String, dynamic> toJson() { | ||||
|   //   return { | ||||
|   //     'id': id, | ||||
|   //     'swipeTypeName': swipeTypeName, | ||||
|   //     'userName': userName, | ||||
|   //     'siteName': siteName, | ||||
|   //     'pointName': pointName, | ||||
|   //     'swipeTime': swipeTime.toIso8601String(), | ||||
|   //     'isSuccess': isSuccess, | ||||
|   //     'errorMessage': errorMessage, | ||||
|   //   }; | ||||
|   // } | ||||
| } | ||||
| @ -0,0 +1,41 @@ | ||||
| 
 | ||||
| 
 | ||||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| class VerifyOtpModel { | ||||
|   final String ?userId; | ||||
|   final String ?userName; | ||||
|   final String ?email; | ||||
|   final String ?token; | ||||
|   final DateTime? validTo; | ||||
| 
 | ||||
|   VerifyOtpModel({ | ||||
|      this.userId, | ||||
|     this.userName, | ||||
|     this.email, | ||||
|     this.token, | ||||
|      this.validTo, | ||||
|   }); | ||||
| 
 | ||||
|   // Factory constructor to create an instance from a JSON map | ||||
|   factory VerifyOtpModel.fromJson(Map<String, dynamic> json) { | ||||
|     return VerifyOtpModel( | ||||
|       userId: json['userId'], | ||||
|       userName: json['userName'], | ||||
|       email: json['email'], | ||||
|       token: json['token'], | ||||
|       validTo: DateTime.parse(json['validTo']), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Convert the instance to a JSON map | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return { | ||||
|       'userId': userId, | ||||
|       'userName': userName, | ||||
|       'email': email, | ||||
|       'token': token, | ||||
|       'validTo': validTo?.toIso8601String(), | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,166 @@ | ||||
| 
 | ||||
| 
 | ||||
| import 'dart:async'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:pinput/pinput.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:test_sa/controllers/providers/api/user_provider.dart'; | ||||
| import 'package:test_sa/extensions/context_extension.dart'; | ||||
| import 'package:test_sa/extensions/int_extensions.dart'; | ||||
| import 'package:test_sa/extensions/text_extensions.dart'; | ||||
| import 'package:test_sa/extensions/widget_extensions.dart'; | ||||
| import 'package:test_sa/models/new_models/general_response_model.dart'; | ||||
| import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; | ||||
| import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| import 'package:test_sa/new_views/forget_password_module/reset_password_view.dart'; | ||||
| 
 | ||||
| class ForgetPasswordVerifyOtpView extends StatefulWidget { | ||||
|   Map<String,dynamic> data={}; | ||||
| 
 | ||||
|    ForgetPasswordVerifyOtpView({Key ?key,required this.data}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   State<ForgetPasswordVerifyOtpView> createState() => _ForgetPasswordVerifyOtpViewState(); | ||||
| } | ||||
| 
 | ||||
| class _ForgetPasswordVerifyOtpViewState extends State<ForgetPasswordVerifyOtpView> { | ||||
|   String otp = ''; | ||||
|    Timer? _timer; | ||||
|   int _remainingSeconds = 180; // 3 minutes in seconds | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _startTimer(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void dispose() { | ||||
|     _timer?.cancel(); | ||||
|     super.dispose(); | ||||
|   } | ||||
| 
 | ||||
|   void _startTimer() { | ||||
|     setState(() { | ||||
|       _remainingSeconds = 180; | ||||
|     }); | ||||
| 
 | ||||
|     _timer = Timer.periodic(const Duration(seconds: 1), (timer) { | ||||
|       if (_remainingSeconds > 0) { | ||||
|         setState(() { | ||||
|           _remainingSeconds--; | ||||
|         }); | ||||
|       } else { | ||||
|         _timer?.cancel(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     final defaultPinTheme = PinTheme( | ||||
|       width: 68.toScreenWidth, | ||||
|       height: 86.toScreenHeight, | ||||
|       textStyle: const TextStyle( | ||||
|         fontSize: 22, | ||||
|         color: Colors.black, | ||||
|       ), | ||||
|       decoration: BoxDecoration( | ||||
|         color: AppColor.white10, | ||||
|         borderRadius: BorderRadius.circular(15), | ||||
|         border: Border.all(color: AppColor.white10, width: 1), | ||||
|       ), | ||||
|     ); | ||||
| 
 | ||||
|     final minutes = (_remainingSeconds ~/ 60).toString().padLeft(2, '0'); | ||||
|     final seconds = (_remainingSeconds % 60).toString().padLeft(2, '0'); | ||||
| 
 | ||||
|     return Scaffold( | ||||
|       body: Column( | ||||
|         children: [ | ||||
|           SingleChildScrollView( | ||||
|             child: Column( | ||||
|               crossAxisAlignment: CrossAxisAlignment.start, | ||||
|               mainAxisAlignment: MainAxisAlignment.center, | ||||
|               children: [ | ||||
|                 context.translation.otpVerification.heading2(context).custom(color: AppColor.white936, fontWeight: FontWeight.w500), | ||||
|                 8.height, | ||||
|                 '${context.translation.pleaseEnterTheOtpSentTo} ${widget.data['phoneNumber']}'.bodyText2(context).custom(color: AppColor.neutral120, fontWeight: FontWeight.w500), | ||||
|                 40.height, | ||||
|                 Center( | ||||
|                   child: Pinput( | ||||
|                     length: 4, | ||||
|                     defaultPinTheme: defaultPinTheme, | ||||
|                     focusedPinTheme: defaultPinTheme.copyWith( | ||||
|                       decoration: defaultPinTheme.decoration?.copyWith( | ||||
|                         border: Border.all(color: AppColor.neutral40, width: 1), | ||||
|                       ), | ||||
|                     ), | ||||
|                     onCompleted: (pin) { | ||||
|                       //   setState(() { | ||||
|                       otp = pin; | ||||
|                       //}); | ||||
|                       verifyOtp(); | ||||
|                     }, | ||||
|                   ), | ||||
|                 ), | ||||
|                 18.height, | ||||
|                 Row( | ||||
|                   // mainAxisAlignment: MainAxisAlignment.spaceAround, | ||||
|                   children: [ | ||||
|                     InkWell( | ||||
|                       onTap: _remainingSeconds == 0 | ||||
|                           ? () async { | ||||
|                         UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
|                         String employeeId = widget.data['employeeId']; | ||||
|                         GeneralResponseModel response = await _userProvider.sendForgetPasswordOtp( | ||||
|                           context: context, | ||||
|                           employeeId: employeeId, | ||||
|                         ); | ||||
|                         print('Response of send OTP: ${response.toJson()}'); | ||||
| 
 | ||||
|                         // Restart the timer | ||||
|                         _startTimer(); | ||||
|                       } | ||||
|                           : null, | ||||
|                       child: Text( | ||||
|                         'Resend', | ||||
|                         style: TextStyle( | ||||
|                           color: _remainingSeconds == 0 ? AppColor.blueStatus(context) : AppColor.neutral40, | ||||
|                           fontWeight: FontWeight.w500, | ||||
|                           fontSize: 16.toScreenWidth, | ||||
|                           decorationColor: AppColor.primary30, | ||||
|                           decoration: _remainingSeconds == 0 ? TextDecoration.underline : null, | ||||
|                         ), | ||||
|                       ), | ||||
|                     ), | ||||
|                     7.width, | ||||
|                     '$minutes:$seconds'.bodyText(context).custom(color: AppColor.neutral10), | ||||
|                   ], | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|           ).center.expanded, | ||||
|           AppFilledButton( | ||||
|             label: context.translation.verify, | ||||
|             maxWidth: true, | ||||
|             onPressed: verifyOtp, | ||||
|           ), | ||||
|         ], | ||||
|       ).paddingOnly(start: 20, end: 20, bottom: 16), | ||||
|     ); | ||||
|   } | ||||
|   void verifyOtp() async{ | ||||
|     if (otp.isNotEmpty) { | ||||
|       UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
|       GeneralResponseModel generalResponseModel = await _userProvider.forgetPasswordValidateOtp( | ||||
|         context: context, | ||||
|         employeeId:widget.data['employeeId'], | ||||
|         otp: otp, | ||||
|       ); | ||||
|       if (generalResponseModel.isSuccess==true) { | ||||
|         Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => ResetPasswordView())); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,121 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:fluttertoast/fluttertoast.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:test_sa/extensions/context_extension.dart'; | ||||
| import 'package:test_sa/extensions/int_extensions.dart'; | ||||
| import 'package:test_sa/extensions/text_extensions.dart'; | ||||
| import 'package:test_sa/extensions/widget_extensions.dart'; | ||||
| import 'package:test_sa/models/new_models/general_response_model.dart'; | ||||
| import 'package:test_sa/models/new_models/update_password.dart'; | ||||
| import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; | ||||
| import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; | ||||
| import 'package:test_sa/new_views/pages/login_page.dart'; | ||||
| 
 | ||||
| import '../../controllers/providers/api/user_provider.dart'; | ||||
| import '../../controllers/validator/validator.dart'; | ||||
| 
 | ||||
| class ResetPasswordView extends StatefulWidget { | ||||
|   static const String routeName = "/resetPassword"; | ||||
| 
 | ||||
|   ResetPasswordView({Key? key}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   State<ResetPasswordView> createState() => _ResetPasswordViewState(); | ||||
| } | ||||
| 
 | ||||
| class _ResetPasswordViewState extends State<ResetPasswordView> { | ||||
|   bool _passwordVisible = false; | ||||
|   bool _confirmPasswordVisible = false; | ||||
| 
 | ||||
|   String newPassword = ""; | ||||
|   String confirmPassword = ""; | ||||
| 
 | ||||
|   final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Form( | ||||
|       key: _formKey, | ||||
|       child: Scaffold( | ||||
|         body: Column( | ||||
|           children: [ | ||||
|             SingleChildScrollView( | ||||
|               child: Column( | ||||
|                 mainAxisAlignment: MainAxisAlignment.center, | ||||
|                 crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                 children: [ | ||||
|                   context.translation.resetPassword.heading2(context).custom(color: AppColor.white936, fontWeight: FontWeight.w500), | ||||
|                   8.height, | ||||
|                   context.translation.pleaseEnterTheNewPassword.bodyText2(context).custom(color: AppColor.neutral120, fontWeight: FontWeight.w500), | ||||
|                   32.height, | ||||
|                   AppTextFormField( | ||||
|                     initialValue: "", | ||||
|                     showBorder: true, | ||||
|                     validator: (value) => Validator.hasValue(value) ? null : context.translation.requiredField, | ||||
|                     labelText: context.translation.password, | ||||
|                     obscureText: !_passwordVisible, | ||||
|                     suffixIcon: Icon( | ||||
|                       // Based on passwordVisible state choose the icon | ||||
|                       _passwordVisible ? Icons.visibility : Icons.visibility_off, | ||||
|                       color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, | ||||
|                     ).paddingOnly(end: 12).onPress(() { | ||||
|                       setState(() { | ||||
|                         _passwordVisible = !_passwordVisible; | ||||
|                       }); | ||||
|                     }), | ||||
|                     onSaved: (value) { | ||||
|                       newPassword = value; | ||||
|                     }, | ||||
|                   ), | ||||
|                   16.height, | ||||
|                   AppTextFormField( | ||||
|                     initialValue: "", | ||||
|                     labelText: context.translation.confirmPassword, | ||||
|                     obscureText: !_confirmPasswordVisible, | ||||
|                     showBorder: true, | ||||
|                     validator: (value) => Validator.isValidPassword(value!) | ||||
|                         ? null | ||||
|                         : value.isEmpty | ||||
|                             ? context.translation.requiredField | ||||
|                             : context.translation.passwordLengthMessage, | ||||
|                     onSaved: (value) { | ||||
|                       confirmPassword = value; | ||||
|                     }, | ||||
|                     suffixIcon: Icon( | ||||
|                       _confirmPasswordVisible ? Icons.visibility : Icons.visibility_off, | ||||
|                       color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, | ||||
|                     ).paddingOnly(end: 12).onPress(() { | ||||
|                       setState(() { | ||||
|                         _confirmPasswordVisible = !_confirmPasswordVisible; | ||||
|                       }); | ||||
|                     }), | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ).center.expanded, | ||||
|             AppFilledButton(label: context.translation.resetPassword, maxWidth: true, onPressed: () => _resetPassword(context)), | ||||
|           ], | ||||
|         ).paddingOnly(start: 16, end: 16, bottom: 24, top: 24), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Future<void> _resetPassword(BuildContext context) async { | ||||
|     if (!_formKey.currentState!.validate()) return; | ||||
|     _formKey.currentState?.save(); | ||||
|     if (newPassword != confirmPassword) { | ||||
|       Fluttertoast.showToast(msg: 'Password not matched try again'); | ||||
|     } else { | ||||
|       UserProvider userProvider = Provider.of<UserProvider>(context,listen: false); | ||||
|       UpdatePasswordModel updatePasswordModel = | ||||
|           UpdatePasswordModel(password: newPassword, confirmPassword: confirmPassword, userId: userProvider.verifyOtpModel.userId, token: userProvider.verifyOtpModel.token); | ||||
|       GeneralResponseModel generalResponseModel = await userProvider.updateNewPassword(context: context, updatePasswordModel: updatePasswordModel); | ||||
|       if (generalResponseModel.isSuccess==true) { | ||||
|         newPassword = ''; | ||||
|         confirmPassword = ''; | ||||
|         Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,99 @@ | ||||
| import 'package:flutter/animation.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:test_sa/extensions/int_extensions.dart'; | ||||
| import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| 
 | ||||
| 
 | ||||
| class CircularAnimatedContainer extends StatefulWidget { | ||||
|   Widget child; | ||||
| 
 | ||||
|   CircularAnimatedContainer({Key? key, required this.child}) : super(key: key); | ||||
|   @override | ||||
|   _CircularAnimatedContainerState createState() => _CircularAnimatedContainerState(); | ||||
| } | ||||
| 
 | ||||
| class _CircularAnimatedContainerState extends State<CircularAnimatedContainer> | ||||
|     with SingleTickerProviderStateMixin { | ||||
|   AnimationController ?_controller; | ||||
|   Animation<double>? _animation; | ||||
| 
 | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _controller = AnimationController( | ||||
|       duration: const Duration(seconds: 2), | ||||
|       vsync: this, | ||||
|     )..repeat(); | ||||
| 
 | ||||
|     _animation = CurvedAnimation( | ||||
|       parent: _controller!, | ||||
|       curve: Curves.easeInOut, // Applies the ease-in-out effect | ||||
|     ); | ||||
|     // Repeats animation | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void dispose() { | ||||
|     _controller!.dispose(); | ||||
|     super.dispose(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Center( | ||||
|       child: Stack( | ||||
|         alignment: Alignment.center, | ||||
|         children: [ | ||||
|           widget.child, | ||||
|           AnimatedBuilder( | ||||
|             animation: _animation!, | ||||
|             builder: (context, child) { | ||||
|               return CustomPaint( | ||||
|                 painter: CircularProgressPainter( | ||||
|                     progress: _animation!.value), | ||||
|                 size: Size(100.toScreenHeight, 100.toScreenWidth), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class CircularProgressPainter extends CustomPainter { | ||||
|   final double progress; | ||||
| 
 | ||||
|   CircularProgressPainter({ required this.progress}); | ||||
|   @override | ||||
|   void paint(Canvas canvas, Size size) { | ||||
| 
 | ||||
| 
 | ||||
|     final Paint paint = Paint() | ||||
|       ..color = AppColor.primary10 | ||||
|       ..style = PaintingStyle.stroke | ||||
|       ..strokeWidth = 3 | ||||
|       ..strokeCap = StrokeCap.round; | ||||
| 
 | ||||
|     final center = Offset(size.width / 2, size.height / 2); | ||||
|     final radius = size.width / 2.05; | ||||
|     final double startAngle = 2.5 * 3.141592653589793 * progress; | ||||
|     final double sweepAngle = 2 * 3.141592653589793 * progress; | ||||
|     // const double startAngle = -90 * (3.141592653589793 / 180); | ||||
|     // final double sweepAngle = 2.05 * 3.141592653589793 * progress; | ||||
| 
 | ||||
|     canvas.drawArc( | ||||
|       Rect.fromCircle(center: center, radius: radius), | ||||
|       startAngle, | ||||
|       sweepAngle, | ||||
|       false, | ||||
|       paint, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   bool shouldRepaint(covariant CustomPainter oldDelegate) { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,61 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:test_sa/extensions/int_extensions.dart'; | ||||
| import 'package:test_sa/extensions/text_extensions.dart'; | ||||
| import 'package:test_sa/extensions/widget_extensions.dart'; | ||||
| import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; | ||||
| 
 | ||||
| class ConfirmDialog extends StatelessWidget { | ||||
|   final String ?title; | ||||
|   final String ?message; | ||||
|   final String ?okTitle; | ||||
|   final VoidCallback ?onTap; | ||||
|   final VoidCallback ?onCloseTap; | ||||
| 
 | ||||
|   const ConfirmDialog({Key ?key, this.title, this.message, this.okTitle, this.onTap, this.onCloseTap}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Dialog( | ||||
|       backgroundColor: Colors.white, | ||||
|       shape: const RoundedRectangleBorder(), | ||||
|       insetPadding: const EdgeInsets.only(left: 21, right: 21), | ||||
|       child: Padding( | ||||
|         padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28), | ||||
|         child: Column( | ||||
|           crossAxisAlignment: CrossAxisAlignment.start, | ||||
|           mainAxisSize: MainAxisSize.min, | ||||
|           children: [ | ||||
|             Row( | ||||
|               crossAxisAlignment: CrossAxisAlignment.start, | ||||
|               children: [ | ||||
|                 Expanded( | ||||
|                   child: Text( | ||||
|                     title ?? "Confirm", | ||||
|                     style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black87, height: 35 / 24, letterSpacing: -0.96), | ||||
|                   ).paddingOnly(top: 16), | ||||
|                 ), | ||||
|                 IconButton( | ||||
|                   padding: EdgeInsets.zero, | ||||
|                   icon: const Icon(Icons.close), | ||||
|                   color: Colors.black87, | ||||
|                   constraints: const BoxConstraints(), | ||||
|                   onPressed: () => onCloseTap ?? Navigator.pop(context), | ||||
|                   // onPressed: () => Navigator.pop(context), | ||||
|                 ) | ||||
|               ], | ||||
|             ), | ||||
|             message!=null?message!.heading5(context).custom(color: AppColor.neutral70):const SizedBox(), | ||||
|             28.height, | ||||
|             AppFilledButton( | ||||
|               label: okTitle ?? "OK", | ||||
|               onPressed: onTap ?? () => Navigator.pop(context), | ||||
|               textColor: Colors.white, | ||||
|               //color: Ap.green, | ||||
|             ), | ||||
|           ], | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,203 @@ | ||||
| import 'dart:async'; | ||||
| import 'dart:io'; | ||||
| 
 | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:nfc_manager/nfc_manager.dart'; | ||||
| import 'package:nfc_manager/platform_tags.dart'; | ||||
| 
 | ||||
| void showNfcReader(BuildContext context, { Function(String nfcId) ?onNcfScan}) { | ||||
|   showModalBottomSheet( | ||||
|     context: context, | ||||
|     enableDrag: false, | ||||
|     isDismissible: false, | ||||
|     shape: const RoundedRectangleBorder( | ||||
|       borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), | ||||
|     ), | ||||
|     backgroundColor: Colors.white, | ||||
|     builder: (context) { | ||||
|       return NfcLayout( | ||||
|         onNcfScan: onNcfScan, | ||||
|       ); | ||||
|     }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| class NfcLayout extends StatefulWidget { | ||||
|   Function(String nfcId) ?onNcfScan; | ||||
| 
 | ||||
|   NfcLayout({this.onNcfScan}); | ||||
| 
 | ||||
|   @override | ||||
|   _NfcLayoutState createState() => _NfcLayoutState(); | ||||
| } | ||||
| 
 | ||||
| class _NfcLayoutState extends State<NfcLayout> { | ||||
|   bool _reading = false; | ||||
|   Widget? mainWidget; | ||||
|   String? nfcId; | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
| 
 | ||||
|     NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { | ||||
|       var f; | ||||
|       if (Platform.isAndroid) { | ||||
|         f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); | ||||
|       } else { | ||||
|         f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); | ||||
|       } | ||||
|       String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); | ||||
|       nfcId = identifier; | ||||
| 
 | ||||
|       setState(() { | ||||
|         _reading = true; | ||||
|         mainWidget = doneNfc(); | ||||
|       }); | ||||
| 
 | ||||
|       Future.delayed(const Duration(seconds: 1), () { | ||||
|         NfcManager.instance.stopSession(); | ||||
|         Navigator.pop(context); | ||||
|         // if (Platform.isAndroid) { | ||||
|         //   Navigator.pop(context); | ||||
|         // } else { | ||||
|         //   Navigator.pop(context); | ||||
|         //   Navigator.pop(context); | ||||
|         // } | ||||
|         widget.onNcfScan!(nfcId!); | ||||
|       }); | ||||
|     }).catchError((err) { | ||||
|       print(err); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     (mainWidget == null && !_reading) ? mainWidget = scanNfc() : mainWidget = doneNfc(); | ||||
|     return AnimatedSwitcher(duration: Duration(milliseconds: 500), child: mainWidget); | ||||
|   } | ||||
| 
 | ||||
|   Widget scanNfc() { | ||||
|     return Container( | ||||
|       key: ValueKey(1), | ||||
|       child: Column( | ||||
|         mainAxisSize: MainAxisSize.min, | ||||
|         children: <Widget>[ | ||||
|           SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|           const Text( | ||||
|             "Ready To Scan", | ||||
|             style: TextStyle( | ||||
|               fontWeight: FontWeight.bold, | ||||
|               fontSize: 24, | ||||
|             ), | ||||
|           ), | ||||
|           SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
| 
 | ||||
|           Image.asset( | ||||
|             "assets/images/ic_nfc.png", | ||||
|             height: MediaQuery.of(context).size.width / 3, | ||||
|             width: double.infinity, | ||||
|           ), | ||||
|           const SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|           const Text( | ||||
|             "Approach an NFC Tag", | ||||
|             style: TextStyle( | ||||
|               fontSize: 18, | ||||
|             ), | ||||
|           ), | ||||
|           const SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|           ButtonTheme( | ||||
|             minWidth: MediaQuery.of(context).size.width / 1.2, | ||||
|             height: 45.0, | ||||
|             buttonColor: Colors.grey[300], | ||||
|             shape: RoundedRectangleBorder( | ||||
|               borderRadius: BorderRadius.circular(6), | ||||
|             ), | ||||
|             child: TextButton( | ||||
|               onPressed: () { | ||||
|                 NfcManager.instance.stopSession(); | ||||
|                 Navigator.pop(context); | ||||
|               }, | ||||
|               // elevation: 0, | ||||
|               child: const Text("CANCEL"), | ||||
|             ), | ||||
|           ), | ||||
|           SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Widget doneNfc() { | ||||
|     return Container( | ||||
|       key: ValueKey(2), | ||||
|       child: Column( | ||||
|         mainAxisSize: MainAxisSize.min, | ||||
|         children: <Widget>[ | ||||
|           SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|           Text( | ||||
|             "Successfully Scanned", | ||||
|             style: TextStyle( | ||||
|               fontWeight: FontWeight.bold, | ||||
|               fontSize: 24, | ||||
|             ), | ||||
|           ), | ||||
|           SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|           Image.asset( | ||||
|             // "assets/icons/nfc/ic_done.png", | ||||
|              "assets/images/ic_done.png", | ||||
|             height: MediaQuery.of(context).size.width / 3, | ||||
|             width: double.infinity, | ||||
|           ), | ||||
|           SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|           Text( | ||||
|             "Approach an NFC Tag", | ||||
|             style: TextStyle( | ||||
|               fontSize: 18, | ||||
|             ), | ||||
|           ), | ||||
|           SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|           ButtonTheme( | ||||
|             minWidth: MediaQuery.of(context).size.width / 1.2, | ||||
|             height: 45.0, | ||||
|             buttonColor: Colors.grey[300], | ||||
|             shape: RoundedRectangleBorder( | ||||
|               borderRadius: BorderRadius.circular(6), | ||||
|             ), | ||||
|             child: TextButton( | ||||
|               // onPressed: () { | ||||
|               //   _stream?.cancel(); | ||||
|               //   widget.onNcfScan(nfcId); | ||||
|               //   Navigator.pop(context); | ||||
|               // }, | ||||
|               onPressed: null, | ||||
|               // elevation: 0, | ||||
|               child: Text("DONE"), | ||||
|             ), | ||||
|           ), | ||||
|           SizedBox( | ||||
|             height: 30, | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,76 @@ | ||||
| import 'dart:io'; | ||||
| 
 | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:just_audio/just_audio.dart'; | ||||
| import 'package:lottie/lottie.dart'; | ||||
| 
 | ||||
| class SuccessDialog extends StatefulWidget { | ||||
|   bool isFromDashboard; | ||||
| 
 | ||||
|   SuccessDialog(this.isFromDashboard); | ||||
| 
 | ||||
|   @override | ||||
|   State<SuccessDialog> createState() => _SuccessDialogState(); | ||||
| } | ||||
| 
 | ||||
| class _SuccessDialogState extends State<SuccessDialog> with TickerProviderStateMixin { | ||||
|    AnimationController? _controller; | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     _controller = AnimationController(vsync: this); | ||||
| 
 | ||||
|     super.initState(); | ||||
|   } | ||||
| 
 | ||||
|   Future<void> playSuccessSound() async { | ||||
|     AudioPlayer player = AudioPlayer(); | ||||
|     String audioAsset = ""; | ||||
|     if (Platform.isAndroid) { | ||||
|       audioAsset = "assets/audio/success_tone_android.mp3"; | ||||
|     } else { | ||||
|       audioAsset = "assets/audio/success_tone_ios.caf"; | ||||
|     } | ||||
|     await player.setAsset(audioAsset); | ||||
|     await player.load(); | ||||
|     player.play(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     double size = MediaQuery.of(context).size.width / 1.8; | ||||
|     return Column( | ||||
|       crossAxisAlignment: CrossAxisAlignment.center, | ||||
|       mainAxisAlignment: MainAxisAlignment.center, | ||||
|       mainAxisSize: MainAxisSize.min, | ||||
|       children: [ | ||||
|         Container( | ||||
|           width: size, | ||||
|           height: size, | ||||
|           child: Card( | ||||
|             shape: RoundedRectangleBorder( | ||||
|               borderRadius: BorderRadius.circular(25.0), | ||||
|             ), | ||||
|             child: Lottie.asset( | ||||
|               //TODO replace with original lottie file... | ||||
|               'assets/lottie/done.json', | ||||
|               repeat: false, | ||||
|               reverse: false, | ||||
|               controller: _controller, | ||||
|               frameRate: FrameRate(60.0), | ||||
|               onLoaded: (LottieComposition v) async { | ||||
|                 await playSuccessSound(); | ||||
|                 _controller | ||||
|                   !..duration = v.duration | ||||
|                   ..forward().whenComplete(() async { | ||||
|                     Navigator.pop(context); | ||||
|                     if (widget.isFromDashboard) Navigator.pop(context); | ||||
|                   }); | ||||
|               }, | ||||
|             ), | ||||
|           ), | ||||
|         ), | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,18 @@ | ||||
| enum SwipeTypeEnum { | ||||
|   NFC, // 1 | ||||
|   QR, // 2 | ||||
|   Wifi, // 3 | ||||
| } | ||||
| 
 | ||||
| extension EnumExtensionsSwipeType on  SwipeTypeEnum { | ||||
|   int getIntFromSwipeTypeEnum() { | ||||
|     switch (this) { | ||||
|       case SwipeTypeEnum.NFC: | ||||
|         return 1; | ||||
|       case SwipeTypeEnum.QR: | ||||
|         return 2; | ||||
|       case SwipeTypeEnum.Wifi: | ||||
|         return 3; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,821 @@ | ||||
| // import 'dart:async'; | ||||
| // import 'dart:developer'; | ||||
| // import 'dart:io'; | ||||
| // | ||||
| // import 'package:flutter/material.dart'; | ||||
| // import 'package:geolocator/geolocator.dart'; | ||||
| // import 'package:huawei_location/huawei_location.dart'; | ||||
| // import 'package:nfc_manager/nfc_manager.dart'; | ||||
| // import 'package:permission_handler/permission_handler.dart'; | ||||
| // import 'package:provider/provider.dart'; | ||||
| // import 'package:test_sa/controllers/providers/api/user_provider.dart'; | ||||
| // import 'package:test_sa/extensions/int_extensions.dart'; | ||||
| // import 'package:test_sa/extensions/text_extensions.dart'; | ||||
| // import 'package:test_sa/extensions/widget_extensions.dart'; | ||||
| // import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| // import 'package:test_sa/new_views/pages/land_page/nfc/nfc_reader_sheet.dart'; | ||||
| // import 'package:test_sa/new_views/swipe_module/dialoge/confirm_dialog.dart'; | ||||
| // import 'package:test_sa/new_views/swipe_module/dialoge/qr_scanner_dialog.dart'; | ||||
| // import 'package:test_sa/new_views/swipe_module/dialoge/success_dialog.dart'; | ||||
| // import 'package:test_sa/new_views/swipe_module/enums/swipe_type.dart'; | ||||
| // import 'package:test_sa/new_views/swipe_module/models/swipe_model.dart'; | ||||
| // import 'package:test_sa/new_views/swipe_module/swipe_success_view.dart'; | ||||
| // import 'package:test_sa/new_views/swipe_module/utils/location_utils.dart'; | ||||
| // import 'package:test_sa/new_views/swipe_module/utils/swipe_general_utils.dart'; | ||||
| // import 'package:wifi_iot/wifi_iot.dart'; | ||||
| // todo @sikander delete this file after compelte | ||||
| // class MarkAttendanceWidget extends StatefulWidget { | ||||
| //   double topPadding; | ||||
| //   bool isFromDashboard; | ||||
| // | ||||
| //   MarkAttendanceWidget({Key key, this.topPadding = 0, this.isFromDashboard = false}) : super(key: key); | ||||
| // | ||||
| //   // todo MarkAttendanceWidget(this.model, {Key? key, this.topPadding = 0, this.isFromDashboard = false}) : super(key: key); | ||||
| // | ||||
| //   @override | ||||
| //   _MarkAttendanceWidgetState createState() { | ||||
| //     return _MarkAttendanceWidgetState(); | ||||
| //   } | ||||
| // } | ||||
| // | ||||
| // class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> { | ||||
| //   bool isNfcEnabled = false, isQrEnabled = false, isWifiEnabled = false; | ||||
| //   UserProvider _userProvider; | ||||
| // | ||||
| //   int _locationUpdateCbId = 0; | ||||
| // | ||||
| //   @override | ||||
| //   void initState() { | ||||
| //     super.initState(); | ||||
| //     checkAttendanceAvailability(); | ||||
| //   } | ||||
| // | ||||
| //   void checkAttendanceAvailability() async { | ||||
| //     _userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
| //     bool isAvailable = await NfcManager.instance.isAvailable(); | ||||
| //     log('backend enabled values are nfc ${_userProvider.user.enableNFC} qr ${_userProvider.user.enableQR} wifi ${_userProvider.user.enableWifi}'); | ||||
| //     setState(() { | ||||
| //       if (isAvailable && _userProvider.user.enableNFC) isNfcEnabled = true; | ||||
| //       if (_userProvider.user.enableQR) isQrEnabled = true; | ||||
| //       if (_userProvider.user.enableWifi) isWifiEnabled = true; | ||||
| //     }); | ||||
| //   } | ||||
| // | ||||
| //   void checkHuaweiLocationPermission(SwipeTypeEnum attendanceType, BuildContext context) async { | ||||
| //     // Permission_Handler permissionHandler = PermissionHandler(); | ||||
| //     LocationUtilities.isEnabled((bool isEnabled) async { | ||||
| //       if (isEnabled) { | ||||
| //         LocationUtilities.havePermission((bool permission) async { | ||||
| //           if (permission) { | ||||
| //             getHuaweiCurrentLocation(attendanceType, context); | ||||
| //           } else { | ||||
| //             bool has = await requestPermissions(); | ||||
| //             if (has) { | ||||
| //               getHuaweiCurrentLocation(attendanceType, context); | ||||
| //             } else { | ||||
| //               showDialog( | ||||
| //                 context: context, | ||||
| //                 builder: (BuildContext cxt) => ConfirmDialog( | ||||
| //                   message: "You need to give location permission to mark attendance", | ||||
| //                   onTap: () { | ||||
| //                     Navigator.pop(context); | ||||
| //                   }, | ||||
| //                 ), | ||||
| //               ); | ||||
| //             } | ||||
| //           } | ||||
| //         }); | ||||
| //       } else { | ||||
| //         showDialog( | ||||
| //           context: context, | ||||
| //           builder: (BuildContext cxt) => ConfirmDialog( | ||||
| //             message: "You need to enable location services to mark attendance", | ||||
| //             onTap: () async { | ||||
| //               Navigator.pop(context); | ||||
| //               await Geolocator.openLocationSettings(); | ||||
| //             }, | ||||
| //           ), | ||||
| //         ); | ||||
| //       } | ||||
| //     }); | ||||
| // | ||||
| //     // if (await permissionHandler.hasLocationPermission()) { | ||||
| //     //   getHuaweiCurrentLocation(attendanceType); | ||||
| //     // } else { | ||||
| //     //   bool has = await requestPermissions(); | ||||
| //     //   if (has) { | ||||
| //     //     getHuaweiCurrentLocation(attendanceType); | ||||
| //     //   } else { | ||||
| //     //     showDialog( | ||||
| //     //       context: context, | ||||
| //     //       builder: (BuildContext cxt) => ConfirmDialog( | ||||
| //     //         message: "You need to give location permission to mark attendance", | ||||
| //     //         onTap: () { | ||||
| //     //           Navigator.pop(context); | ||||
| //     //         }, | ||||
| //     //       ), | ||||
| //     //     ); | ||||
| //     //   } | ||||
| //     // } | ||||
| //   } | ||||
| // | ||||
| //   Future<bool> requestPermissions() async { | ||||
| //     var result = await [ | ||||
| //       Permission.location, | ||||
| //     ].request(); | ||||
| //     return (result[Permission.location] == PermissionStatus.granted || result[Permission.locationAlways] == PermissionStatus.granted); | ||||
| //   } | ||||
| // | ||||
| //   @override | ||||
| //   void dispose() { | ||||
| //     super.dispose(); | ||||
| //     // Stop Session | ||||
| //     NfcManager.instance.stopSession(); | ||||
| //   } | ||||
| // | ||||
| //   @override | ||||
| //   Widget build(BuildContext context) { | ||||
| //     return Container( | ||||
| //       padding: EdgeInsets.only(left: 21, right: 21, bottom: 21, top: widget.topPadding), | ||||
| //       decoration: const BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), | ||||
| //       width: double.infinity, | ||||
| //       child: Column( | ||||
| //         crossAxisAlignment: CrossAxisAlignment.start, | ||||
| //         mainAxisSize: MainAxisSize.min, | ||||
| //         children: [ | ||||
| //           20.height, | ||||
| //           'click me '.heading5(context), | ||||
| //           // LocaleKeys.markAttendance.tr().toSectionHeading(), | ||||
| //           // LocaleKeys.selectMethodOfAttendance.tr().toText11(color: const Color(0xff535353)), | ||||
| //           GridView( | ||||
| //             physics: const NeverScrollableScrollPhysics(), | ||||
| //             shrinkWrap: true, | ||||
| //             padding: const EdgeInsets.only(bottom: 0, top: 21), | ||||
| //             gridDelegate: | ||||
| //                 SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), | ||||
| //             children: availableAttendanceMethodList(context: context), | ||||
| //           ) | ||||
| //         ], | ||||
| //       ), | ||||
| //     ); | ||||
| //   } | ||||
| // | ||||
| //   void handleSwipe({ | ||||
| //     SwipeTypeEnum swipeType, | ||||
| //     @required bool isEnable, | ||||
| //     @required BuildContext context, | ||||
| //   }) { | ||||
| //     // if (AppState().getIsHuawei) { | ||||
| //     if (false) { | ||||
| //       checkHuaweiLocationPermission(swipeType, context); | ||||
| //     } else { | ||||
| //       LocationUtilities.isEnabled((bool isEnabled) { | ||||
| //         if (isEnabled) { | ||||
| //           LocationUtilities.havePermission((bool permission) { | ||||
| //             if (permission) { | ||||
| //               SwipeGeneralUtils.showLoading(context); | ||||
| //               LocationUtilities.getCurrentLocation( | ||||
| //                 (Position position, bool isMocked) { | ||||
| //                   if (isMocked) { | ||||
| //                     SwipeGeneralUtils.hideLoading(context); | ||||
| //                     SwipeGeneralUtils.markFakeAttendance(swipeType.name, position.latitude.toString() ?? "", position.longitude.toString() ?? "", context); | ||||
| //                   } else { | ||||
| //                     SwipeGeneralUtils.hideLoading(context); | ||||
| //                     //todo performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); | ||||
| //                     handleSwipeOperation(swipeType: swipeType, lat: position.latitude, lang: position.longitude); | ||||
| //                   } | ||||
| //                 }, | ||||
| //                 () { | ||||
| //                   SwipeGeneralUtils.hideLoading(context); | ||||
| //                   SwipeGeneralUtils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working."); | ||||
| //                 }, | ||||
| //                 context, | ||||
| //               ); | ||||
| //             } else { | ||||
| //               showDialog( | ||||
| //                 context: context, | ||||
| //                 builder: (BuildContext cxt) => ConfirmDialog( | ||||
| //                   message: "You need to give location permission to mark attendance", | ||||
| //                   onTap: () async { | ||||
| //                     Navigator.pop(context); | ||||
| //                     await Geolocator.openAppSettings(); | ||||
| //                   }, | ||||
| //                 ), | ||||
| //               ); | ||||
| //             } | ||||
| //           }); | ||||
| //         } else { | ||||
| //           showDialog( | ||||
| //             context: context, | ||||
| //             builder: (BuildContext cxt) => ConfirmDialog( | ||||
| //               message: "You need to enable location services to mark attendance", | ||||
| //               onTap: () async { | ||||
| //                 Navigator.pop(context); | ||||
| //                 await Geolocator.openLocationSettings(); | ||||
| //               }, | ||||
| //             ), | ||||
| //           ); | ||||
| //         } | ||||
| //       }); | ||||
| //     } | ||||
| //   } | ||||
| // | ||||
| //   void handleSwipeOperation({@required SwipeTypeEnum swipeType, double lat, double lang, BuildContext context}) { | ||||
| //     switch (swipeType) { | ||||
| //       case SwipeTypeEnum.NFC: | ||||
| //         handleNfcAttendance(latitude: lat, longitude: lang, context: context); | ||||
| //         return; | ||||
| //       case SwipeTypeEnum.QR: | ||||
| //         performQrCodeAttendance(latitude: lat, longitude: lang, context: context); | ||||
| //         return; | ||||
| //       case SwipeTypeEnum.Wifi: | ||||
| //         //TODO need to implement. | ||||
| //         return; | ||||
| //     } | ||||
| //   } | ||||
| // | ||||
| //   void getHuaweiCurrentLocation(SwipeTypeEnum attendanceType, BuildContext context) async { | ||||
| //     try { | ||||
| //       SwipeGeneralUtils.showLoading(context); | ||||
| //       FusedLocationProviderClient locationService = FusedLocationProviderClient()..initFusedLocationService(); | ||||
| //       LocationRequest locationRequest = LocationRequest(); | ||||
| //       locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY; | ||||
| //       locationRequest.interval = 500; | ||||
| //       List<LocationRequest> locationRequestList = <LocationRequest>[locationRequest]; | ||||
| //       LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList); | ||||
| // | ||||
| //       StreamSubscription<Location> _streamSubscription; | ||||
| //       int requestCode = (await (locationService.requestLocationUpdates(locationRequest))); | ||||
| // | ||||
| //       _streamSubscription = locationService.onLocationData.listen( | ||||
| //         (Location location) async { | ||||
| //           SwipeGeneralUtils.hideLoading(context); | ||||
| //           await locationService.removeLocationUpdates(requestCode); | ||||
| //           handleSwipeOperation(swipeType: attendanceType); | ||||
| //           requestCode = 0; | ||||
| //         }, | ||||
| //       ); | ||||
| // | ||||
| //       // locationService.checkLocationSettings(locationSettingsRequest).then((settings) async { | ||||
| //       //   await locationService.getLastLocation().then((value) { | ||||
| //       //     if (value.latitude == null || value.longitude == null) { | ||||
| //       //       showDialog( | ||||
| //       //         context: context, | ||||
| //       //         builder: (BuildContext cxt) => ConfirmDialog( | ||||
| //       //           message: "Unable to get your location, Please check your location settings & try again.", | ||||
| //       //           onTap: () { | ||||
| //       //             Navigator.pop(context); | ||||
| //       //           }, | ||||
| //       //         ), | ||||
| //       //       ); | ||||
| //       //     } else { | ||||
| //       //       if (attendanceType == "QR") { | ||||
| //       //         performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); | ||||
| //       //       } | ||||
| //       //       if (attendanceType == "WIFI") { | ||||
| //       //         performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); | ||||
| //       //       } | ||||
| //       //       if (attendanceType == "NFC") { | ||||
| //       //         performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); | ||||
| //       //       } | ||||
| //       //     } | ||||
| //       //   }).catchError((error) { | ||||
| //       //     log("HUAWEI LOCATION getLastLocation ERROR!!!!!"); | ||||
| //       //     log(error); | ||||
| //       //   }); | ||||
| //       // }).catchError((error) { | ||||
| //       //   log("HUAWEI LOCATION checkLocationSettings ERROR!!!!!"); | ||||
| //       //   log(error); | ||||
| //       //   if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") { | ||||
| //       //     // Location service not enabled. | ||||
| //       //   } | ||||
| //       // }); | ||||
| //     } catch (error) { | ||||
| //       log("HUAWEI LOCATION ERROR!!!!!"); | ||||
| //       log('$error'); | ||||
| //       SwipeGeneralUtils.hideLoading(context); | ||||
| //       // SwipeGeneralUtils.handleException(error, context, null); | ||||
| //     } | ||||
| //   } | ||||
| // | ||||
| //   Future<void> handleNfcAttendance({double latitude = 0, double longitude = 0, BuildContext context}) async { | ||||
| //     final userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
| // | ||||
| //     if (Platform.isIOS) { | ||||
| //       SwipeGeneralUtils.readNFc(onRead: (String nfcId) async { | ||||
| //         await _processNfcAttendance(userProvider, nfcId, latitude, longitude, context); | ||||
| //       }); | ||||
| //     } else { | ||||
| //       showNfcReader(context, onNcfScan: (String nfcId) async { | ||||
| //         await _processNfcAttendance(userProvider, nfcId ?? '', latitude, longitude, context); | ||||
| //       }); | ||||
| //     } | ||||
| //   } | ||||
| // | ||||
| //   Future<void> _processNfcAttendance( | ||||
| //     UserProvider userProvider, | ||||
| //     String nfcId, | ||||
| //     double latitude, | ||||
| //     double longitude, | ||||
| //     BuildContext context, | ||||
| //   ) async { | ||||
| //     SwipeGeneralUtils.showLoading(context); | ||||
| //     try { | ||||
| //       // final swipeModel = Swipe( | ||||
| //       //   swipeTypeValue: SwipeTypeEnum.NFC.getIntFromSwipeTypeEnum(), | ||||
| //       //   value: nfcId, | ||||
| //       //   latitude: latitude, | ||||
| //       //   longitude: longitude, | ||||
| //       // ); | ||||
| //       //Test model... | ||||
| //       final swipeModel = Swipe(swipeTypeValue: SwipeTypeEnum.NFC.getIntFromSwipeTypeEnum(), value: '123', latitude: 24.70865415364271, longitude: 46.66600861881879); | ||||
| //       final swipeResponse = await userProvider.makeSwipe(model: swipeModel); | ||||
| //       if (swipeResponse.isSuccess) { | ||||
| //         if (Platform.isIOS) await Future.delayed(const Duration(seconds: 3)); | ||||
| //         SwipeGeneralUtils.hideLoading(context); | ||||
| //         Navigator.pushNamed(context, SwipeSuccessView.routeName); | ||||
| //       } else { | ||||
| //         SwipeGeneralUtils.hideLoading(context); | ||||
| //         SwipeGeneralUtils.showErrorDialog(message: swipeResponse.message ?? "Unexpected error occurred", context: context); | ||||
| //       } | ||||
| //     } catch (errSwipeGeneralUtilsor) { | ||||
| //       SwipeGeneralUtils.hideLoading(context); | ||||
| //       // Uncomment below line for error handling if needed | ||||
| //       // SwipeGeneralUtils.handleException(error, context, null); | ||||
| //     } | ||||
| //   } | ||||
| // | ||||
| //   Future<bool> closeWifiRequest() async { | ||||
| //     if (Platform.isAndroid) { | ||||
| //       await WiFiForIoTPlugin.forceWifiUsage(false); | ||||
| //     } | ||||
| //     return await WiFiForIoTPlugin.disconnect(); | ||||
| //   } | ||||
| // | ||||
| //   Future<void> performQrCodeAttendance({double latitude, double longitude, BuildContext context}) async { | ||||
| //     UserProvider userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
| //     var qrCodeValue = await Navigator.of(context).push( | ||||
| //       MaterialPageRoute( | ||||
| //         builder: (BuildContext context) => QrScannerDialog(), | ||||
| //       ), | ||||
| //     ); | ||||
| //     if (qrCodeValue != null) { | ||||
| //       SwipeGeneralUtils.showLoading(context); | ||||
| //       try { | ||||
| //         //test model.. | ||||
| //         final swipeModel = Swipe( | ||||
| //           swipeTypeValue: SwipeTypeEnum.QR.getIntFromSwipeTypeEnum(), | ||||
| //           value: '2323', | ||||
| //           latitude: 24.70865415364271, | ||||
| //           longitude: 46.66600861881879, | ||||
| //         ); | ||||
| //         final swipeResponse = await userProvider.makeSwipe(model: swipeModel); | ||||
| //         if (swipeResponse.isSuccess) { | ||||
| //           SwipeGeneralUtils.hideLoading(context); | ||||
| //           SwipeGeneralUtils.showMDialog(context, backgroundColor: Colors.transparent, isDismissable: true, child: SuccessDialog(widget.isFromDashboard)); | ||||
| //         } else { | ||||
| //           SwipeGeneralUtils.hideLoading(context); | ||||
| //           showDialog( | ||||
| //             barrierDismissible: true, | ||||
| //             context: context, | ||||
| //             builder: (cxt) => ConfirmDialog( | ||||
| //               message: swipeResponse.message ?? "", | ||||
| //               onTap: () { | ||||
| //                 Navigator.pop(context); | ||||
| //               }, | ||||
| //               onCloseTap: () {} | ||||
| //             ), | ||||
| //           ); | ||||
| //         } | ||||
| //       } catch (ex) { | ||||
| //         SwipeGeneralUtils.hideLoading(context); | ||||
| //       } | ||||
| //     } | ||||
| //   } | ||||
| // | ||||
| //   List<Widget> availableAttendanceMethodList({@required BuildContext context}) { | ||||
| //     List<Widget> availableMethods = []; | ||||
| //     if (isNfcEnabled) { | ||||
| //       availableMethods.add(attendanceMethod(SwipeTypeEnum.NFC.name, 'nfc_icon', isNfcEnabled, () { | ||||
| //         handleSwipe(swipeType: SwipeTypeEnum.NFC, isEnable: isNfcEnabled, context: context); | ||||
| //       })); | ||||
| //     } | ||||
| //     if (isQrEnabled) { | ||||
| //       availableMethods.add(attendanceMethod(SwipeTypeEnum.QR.name, 'wifi_icon', isQrEnabled, () { | ||||
| //         handleSwipe(swipeType: SwipeTypeEnum.QR, isEnable: isQrEnabled, context: context); | ||||
| //       })); | ||||
| //     } | ||||
| //     if (isWifiEnabled) { | ||||
| //       availableMethods.add(attendanceMethod(SwipeTypeEnum.Wifi.name, 'wifi_icon', isWifiEnabled, () { | ||||
| //         handleSwipe(swipeType: SwipeTypeEnum.Wifi, isEnable: isWifiEnabled, context: context); | ||||
| //       })); | ||||
| //     } | ||||
| //     return availableMethods; | ||||
| //   } | ||||
| // | ||||
| //   Widget attendanceMethod(String title, String icon, bool isEnabled, VoidCallback onPress) { | ||||
| //     return Container( | ||||
| //       padding: EdgeInsets.all(12), | ||||
| //       decoration: BoxDecoration( | ||||
| //         color: Colors.white, | ||||
| //         borderRadius: BorderRadius.circular(18), | ||||
| //         border: Border.all(color: AppColor.white40, width: 2), | ||||
| //       ), | ||||
| //       child: Column( | ||||
| //         crossAxisAlignment: CrossAxisAlignment.start, | ||||
| //         mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
| //         children: [ | ||||
| //           icon.toSvgAsset(), | ||||
| //           title.heading5(context).custom(color: AppColor.neutral50), | ||||
| //           // Text( | ||||
| //           //   title, | ||||
| //           //   style: TextStyle(fontSize: 12, fontWeight: FontWeight.w500), | ||||
| //           // ), | ||||
| //         ], | ||||
| //       ), | ||||
| //     ).onPress( | ||||
| //       () { | ||||
| //         log('isEnabled is ${!isEnabled}'); | ||||
| //         if (!isEnabled) return; | ||||
| //         onPress(); | ||||
| //       }, | ||||
| //     ); | ||||
| //     // return Container( | ||||
| //     //   decoration: BoxDecoration( | ||||
| //     //     borderRadius: BorderRadius.circular(15), | ||||
| //     //     color: isEnabled ? null : Colors.grey.withOpacity(.5), | ||||
| //     //     gradient: isEnabled | ||||
| //     //         ? const LinearGradient( | ||||
| //     //             transform: GradientRotation(.64), | ||||
| //     //             begin: Alignment.topRight, | ||||
| //     //             end: Alignment.bottomLeft, | ||||
| //     //             colors: [ | ||||
| //     //               //ToDo set Colors according to design provided by designer... | ||||
| //     //               Colors.blue, | ||||
| //     //               Colors.green, | ||||
| //     //               // AppColor.gradiantEndColor, | ||||
| //     //               // MyColors.gradiantStartColor, | ||||
| //     //             ], | ||||
| //     //           ) | ||||
| //     //         : null, | ||||
| //     //   ), | ||||
| //     //   clipBehavior: Clip.antiAlias, | ||||
| //     //   padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14), | ||||
| //     //   child: Column( | ||||
| //     //     crossAxisAlignment: CrossAxisAlignment.start, | ||||
| //     //     children: [ | ||||
| //     //       //  SvgPicture.asset(image, color: Colors.white, alignment: Alignment.topLeft).expanded, | ||||
| //     //       Icon(iconData, color: isEnabled ? AppColor.black35 : Colors.grey), | ||||
| //     //       title.heading6(context), | ||||
| //     //       // title.toText17(isBold: true, color: Colors.white), | ||||
| //     //     ], | ||||
| //     //   ), | ||||
| //     // ).onPress( | ||||
| //     //   () { | ||||
| //     //     log('isEnabled is ${!isEnabled}'); | ||||
| //     //     if (!isEnabled) return; | ||||
| //     //     onPress(); | ||||
| //     //   }, | ||||
| //     // ); | ||||
| //   } | ||||
| // } | ||||
| // | ||||
| // //  Widget customListItem({required String icon, required String heading, required String subHeading, required VoidCallback onTap}) { | ||||
| // //     return GestureDetector( | ||||
| // //       onTap: onTap, // Handles the tap | ||||
| // //       child: Card( | ||||
| // //         shape: RoundedRectangleBorder( | ||||
| // //           borderRadius: BorderRadius.circular(14), // Circular border radius | ||||
| // //         ), | ||||
| // //         color: Colors.white, | ||||
| // //         child: Row( | ||||
| // //           crossAxisAlignment: CrossAxisAlignment.start, // Align items at the top | ||||
| // //           children: [ | ||||
| // //             // Icon Section | ||||
| // //             icon | ||||
| // //                 .toSvgAsset( | ||||
| // //                   width: 32, | ||||
| // //                   color: AppColor.neutral120, | ||||
| // //                   height: 29, | ||||
| // //                 ) | ||||
| // //                 .paddingOnly(top: 8), | ||||
| // //             14.width, | ||||
| // //             Expanded( | ||||
| // //               child: Column( | ||||
| // //                 crossAxisAlignment: CrossAxisAlignment.start, | ||||
| // //                 children: [ | ||||
| // //                   Text( | ||||
| // //                     heading, | ||||
| // //                     style: AppTextStyles.heading6.copyWith(color: AppColor.neutral50), | ||||
| // //                   ), | ||||
| // //                   7.height, | ||||
| // //                   Text( | ||||
| // //                     subHeading, | ||||
| // //                     style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120), | ||||
| // //                   ), | ||||
| // //                 ], | ||||
| // //               ).paddingOnly(end: 50), | ||||
| // //             ), | ||||
| // //           ], | ||||
| // //         ).paddingAll(12), | ||||
| // //       ), | ||||
| // //     ); | ||||
| // //   } | ||||
| // | ||||
| // //qr older code... | ||||
| // | ||||
| // //nfc older code widget | ||||
| // | ||||
| // // // if (AppState().getIsHuawei) { | ||||
| // //                  if (false) { | ||||
| // //                    checkHuaweiLocationPermission(SwipeTypeEnum.NFC); | ||||
| // //                  } else { | ||||
| // //                    LocationUtilities.isEnabled((bool isEnabled) { | ||||
| // //                      if (isEnabled) { | ||||
| // //                        LocationUtilities.havePermission((bool permission) { | ||||
| // //                          if (permission) { | ||||
| // //                            SwipeGeneralUtils.showLoading(context); | ||||
| // //                            LocationUtilities.getCurrentLocation( | ||||
| // //                                  (Position position, bool isMocked) { | ||||
| // //                                if (isMocked) { | ||||
| // //                                  SwipeGeneralUtils.hideLoading(context); | ||||
| // //                                  SwipeGeneralUtils.markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? "",context); | ||||
| // //                                } else { | ||||
| // //                                  SwipeGeneralUtils.hideLoading(context); | ||||
| // //                                  //todo performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); | ||||
| // //                                } | ||||
| // //                              }, | ||||
| // //                                  () { | ||||
| // //                                SwipeGeneralUtils.hideLoading(context); | ||||
| // //                                SwipeGeneralUtils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working."); | ||||
| // //                              }, | ||||
| // //                              context, | ||||
| // //                            ); | ||||
| // //                          } else { | ||||
| // //                            showDialog( | ||||
| // //                              context: context, | ||||
| // //                              builder: (BuildContext cxt) => ConfirmDialog( | ||||
| // //                                message: "You need to give location permission to mark attendance", | ||||
| // //                                onTap: () async { | ||||
| // //                                  Navigator.pop(context); | ||||
| // //                                  await Geolocator.openAppSettings(); | ||||
| // //                                }, | ||||
| // //                              ), | ||||
| // //                            ); | ||||
| // //                          } | ||||
| // //                        }); | ||||
| // //                      } else { | ||||
| // //                        showDialog( | ||||
| // //                          context: context, | ||||
| // //                          builder: (BuildContext cxt) => ConfirmDialog( | ||||
| // //                            message: "You need to enable location services to mark attendance", | ||||
| // //                            onTap: () async { | ||||
| // //                              Navigator.pop(context); | ||||
| // //                              await Geolocator.openLocationSettings(); | ||||
| // //                            }, | ||||
| // //                          ), | ||||
| // //                        ); | ||||
| // //                      } | ||||
| // //                    }); | ||||
| // //                  } | ||||
| // | ||||
| // //older code.... | ||||
| // // Future<void> performNfcAttendance({double lat = 0, double lng = 0}) async { | ||||
| // //   UserProvider userProvider = Provider.of<UserProvider>(context,listen:false); | ||||
| // //   if (Platform.isIOS) { | ||||
| // //     SwipeGeneralUtils.readNFc(onRead: (String nfcId) async { | ||||
| // //       SwipeGeneralUtils.showLoading(context); | ||||
| // //       try { | ||||
| // //         SwipeModel swipeResponse = await userProvider.makeSwipe(model: Swipe(swipeTypeValue: SwipeTypeEnum.NFC.getIntFromSwipeTypeEnum(), value: '', latitude: lat, longitude: lng)); | ||||
| // //         if (swipeResponse.responseCode != 1) { | ||||
| // //           SwipeGeneralUtils.hideLoading(context); | ||||
| // //           showDialog( | ||||
| // //             context: context, | ||||
| // //             builder: (BuildContext cxt) => ConfirmDialog( | ||||
| // //               message: swipeResponse.message ?? "Unexpected error occurred", | ||||
| // //               onTap: () { | ||||
| // //                 Navigator.pop(context); | ||||
| // //               }, | ||||
| // //             ), | ||||
| // //           ); | ||||
| // //         } else { | ||||
| // //           bool status = swipeResponse.data; | ||||
| // //           if (Platform.isIOS) await Future.delayed(const Duration(seconds: 3)); | ||||
| // //           SwipeGeneralUtils.hideLoading(context); | ||||
| // //           SwipeGeneralUtils.showMDialog( | ||||
| // //             context, | ||||
| // //             backgroundColor: Colors.transparent, | ||||
| // //             isDismissable: true, | ||||
| // //             child: SuccessDialog(widget.isFromDashboard), | ||||
| // //           ); | ||||
| // //         } | ||||
| // //       } catch (ex) { | ||||
| // //         SwipeGeneralUtils.hideLoading(context); | ||||
| // //         // SwipeGeneralUtils.handleException(ex, context, null); | ||||
| // //       } | ||||
| // //     }); | ||||
| // //   } else { | ||||
| // //     showNfcReader(context, onNcfScan: (String nfcId) async { | ||||
| // //       SwipeGeneralUtils.showLoading(context); | ||||
| // //       try { | ||||
| // //         SwipeModel swipeResponse = await userProvider.makeSwipe(model: Swipe(swipeTypeValue: SwipeTypeEnum.NFC.getIntFromSwipeTypeEnum(), value: nfcId??'', latitude: lat, longitude: lng)); | ||||
| // //         log('api response i got is ${swipeResponse.toJson()}'); | ||||
| // //         if (swipeResponse.responseCode != 1) { | ||||
| // //           SwipeGeneralUtils.hideLoading(context); | ||||
| // //           showDialog( | ||||
| // //             context: context, | ||||
| // //             builder: (BuildContext cxt) => ConfirmDialog( | ||||
| // //               message: swipeResponse.message ?? "Unexpected error occurred", | ||||
| // //               onTap: () { | ||||
| // //                 Navigator.pop(context); | ||||
| // //               }, | ||||
| // //             ), | ||||
| // //           ); | ||||
| // //         } else { | ||||
| // //           bool status = swipeResponse.data; //use this status to get transactions. | ||||
| // //           if (Platform.isIOS) await Future.delayed(const Duration(seconds: 3)); | ||||
| // //           SwipeGeneralUtils.hideLoading(context); | ||||
| // //           SwipeGeneralUtils.showMDialog( | ||||
| // //             context, | ||||
| // //             backgroundColor: Colors.transparent, | ||||
| // //             isDismissable: true, | ||||
| // //             child: SuccessDialog(widget.isFromDashboard), | ||||
| // //           ); | ||||
| // //         } | ||||
| // //       } catch (ex) { | ||||
| // //         SwipeGeneralUtils.hideLoading(context); | ||||
| // //         // SwipeGeneralUtils.handleException(ex, context, null); | ||||
| // //       } | ||||
| // //       // SwipeGeneralUtils.showLoading(context); | ||||
| // //       // try { | ||||
| // //       //   GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "", isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng); | ||||
| // //       //   if (g?.messageStatus != 1) { | ||||
| // //       //     SwipeGeneralUtils.hideLoading(context); | ||||
| // //       //     showDialog( | ||||
| // //       //       context: context, | ||||
| // //       //       builder: (BuildContext cxt) => ConfirmDialog( | ||||
| // //       //         message: g?.errorEndUserMessage ?? "Unexpected error occurred", | ||||
| // //       //         onTap: () { | ||||
| // //       //           Navigator.pop(context); | ||||
| // //       //         }, | ||||
| // //       //       ), | ||||
| // //       //     ); | ||||
| // //       //   } else { | ||||
| // //       //     bool status = await model.fetchAttendanceTracking(context); | ||||
| // //       //     SwipeGeneralUtils.hideLoading(context); | ||||
| // //       //     showMDialog( | ||||
| // //       //       context, | ||||
| // //       //       backgroundColor: Colors.transparent, | ||||
| // //       //       isDismissable: false, | ||||
| // //       //       child: SuccessDialog(widget.isFromDashboard), | ||||
| // //       //     ); | ||||
| // //       //   } | ||||
| // //       // } catch (ex) { | ||||
| // //       //   log(ex); | ||||
| // //       //   SwipeGeneralUtils.hideLoading(context); | ||||
| // //       //   // SwipeGeneralUtils.handleException(ex, context, (String msg) { | ||||
| // //       //   //   SwipeGeneralUtils.confirmDialog(context, msg); | ||||
| // //       //   // }); | ||||
| // //       // } | ||||
| // //     }); | ||||
| // //   } | ||||
| // // } | ||||
| // | ||||
| // // | ||||
| // // Future<bool> checkSession() async { | ||||
| // //   try { | ||||
| // //     SwipeGeneralUtils.showLoading(context); | ||||
| // //     await DashboardApiClient().getOpenMissingSwipes(); | ||||
| // //     SwipeGeneralUtils.hideLoading(context); | ||||
| // //     return true; | ||||
| // //   } catch (ex) { | ||||
| // //     SwipeGeneralUtils.hideLoading(context); | ||||
| // //     SwipeGeneralUtils.handleException(ex, context, null); | ||||
| // //     return false; | ||||
| // //   } | ||||
| // // } | ||||
| // | ||||
| // //TODO need to confirm .... | ||||
| // Future<void> performWifiAttendance({double? latitude, double? lng}) async { | ||||
| //   // if (Platform.isAndroid) { | ||||
| //   //   if (!(await checkSession())) { | ||||
| //   //     return; | ||||
| //   //   } | ||||
| //   // } | ||||
| //   SwipeGeneralUtils.showLoading(context); | ||||
| //   bool isConnected = await WiFiForIoTPlugin.connect(AppState().getMohemmWifiSSID ?? "", | ||||
| //       password: AppState().getMohemmWifiPassword ?? "", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false); | ||||
| // | ||||
| //   if (Platform.isIOS) { | ||||
| //     if (await WiFiForIoTPlugin.getSSID() == AppState().getMohemmWifiSSID) { | ||||
| //       isConnected = true; | ||||
| //     } else { | ||||
| //       isConnected = false; | ||||
| //     } | ||||
| //   } | ||||
| // | ||||
| //   if (isConnected && AppState().isAuthenticated) { | ||||
| //     await WiFiForIoTPlugin.forceWifiUsage(true); | ||||
| //     await Future.delayed(const Duration(seconds: 6)); | ||||
| //     try { | ||||
| //       GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 3, nfcValue: "", isGpsRequired: isWifiLocationEnabled, lat: lat, long: lng); | ||||
| //       bool status = await model.fetchAttendanceTracking(context); | ||||
| //       SwipeGeneralUtils.hideLoading(context); | ||||
| //       await closeWifiRequest(); | ||||
| //       if (g?.messageStatus == 2) { | ||||
| //         showDialog( | ||||
| //           barrierDismissible: true, | ||||
| //           context: context, | ||||
| //           builder: (cxt) => ConfirmDialog( | ||||
| //             message: g?.errorEndUserMessage ?? "", | ||||
| //             onTap: () { | ||||
| //               Navigator.pop(context); | ||||
| //             }, | ||||
| //             onCloseTap: () {}, | ||||
| //           ), | ||||
| //         ); | ||||
| //       } else { | ||||
| //         showMDialog( | ||||
| //           context, | ||||
| //           backgroundColor: Colors.transparent, | ||||
| //           isDismissable: false, | ||||
| //           child: SuccessDialog(widget.isFromDashboard), | ||||
| //         ); | ||||
| //       } | ||||
| //     } catch (ex) { | ||||
| //       await closeWifiRequest(); | ||||
| //       SwipeGeneralUtils.hideLoading(context); | ||||
| //       SwipeGeneralUtils.handleException(ex, context, null); | ||||
| //     } | ||||
| //   } else { | ||||
| //     if (AppState().isAuthenticated) { | ||||
| //       SwipeGeneralUtils.hideLoading(context); | ||||
| //       SwipeGeneralUtils.confirmDialog(context, "LocaleKeys.comeNearHMGWifi.tr()"); | ||||
| //     } else { | ||||
| //       await closeWifiRequest(); | ||||
| //     } | ||||
| //   } | ||||
| // } | ||||
| // | ||||
| // // older grid widget.. | ||||
| // //       attendanceMethod(SwipeTypeEnum.NFC.name, Icons.nfc, isNfcEnabled, () { | ||||
| // //                 handleSwipe(swipeType: SwipeTypeEnum.NFC, isEnable: isNfcEnabled); | ||||
| // //               }), | ||||
| // //               attendanceMethod(SwipeTypeEnum.QR.name, Icons.qr_code_2, isQrEnabled, () async { | ||||
| // //                 handleSwipe(swipeType: SwipeTypeEnum.QR, isEnable: true); | ||||
| // //               }), | ||||
| // //               //if (isWifiEnabled) //todo | ||||
| // //               attendanceMethod(SwipeTypeEnum.Wifi.name, Icons.wifi, isWifiEnabled, () { | ||||
| // //                 // if (AppState().getIsHuawei) { | ||||
| // //                 if (false) { | ||||
| // //                   checkHuaweiLocationPermission(SwipeTypeEnum.Wifi); | ||||
| // //                 } else { | ||||
| // //                   LocationUtilities.isEnabled((bool isEnabled) { | ||||
| // //                     if (isEnabled) { | ||||
| // //                       LocationUtilities.havePermission((bool permission) { | ||||
| // //                         if (permission) { | ||||
| // //                           SwipeGeneralUtils.showLoading(context); | ||||
| // //                           LocationUtilities.getCurrentLocation( | ||||
| // //                             (Position position, bool isMocked) { | ||||
| // //                               if (isMocked) { | ||||
| // //                                 SwipeGeneralUtils.hideLoading(context); | ||||
| // //                                 SwipeGeneralUtils.markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? "", context); | ||||
| // //                               } else { | ||||
| // //                                 SwipeGeneralUtils.hideLoading(context); | ||||
| // //                                 //todo performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); | ||||
| // //                               } | ||||
| // //                             }, | ||||
| // //                             () { | ||||
| // //                               SwipeGeneralUtils.hideLoading(context); | ||||
| // //                               SwipeGeneralUtils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working."); | ||||
| // //                             }, | ||||
| // //                             context, | ||||
| // //                           ); | ||||
| // //                         } else { | ||||
| // //                           showDialog( | ||||
| // //                             context: context, | ||||
| // //                             builder: (BuildContext cxt) => ConfirmDialog( | ||||
| // //                               message: "You need to give location permission to mark attendance", | ||||
| // //                               onTap: () async { | ||||
| // //                                 Navigator.pop(context); | ||||
| // //                                 await Geolocator.openAppSettings(); | ||||
| // //                               }, | ||||
| // //                             ), | ||||
| // //                           ); | ||||
| // //                         } | ||||
| // //                       }); | ||||
| // //                     } else { | ||||
| // //                       showDialog( | ||||
| // //                         context: context, | ||||
| // //                         builder: (BuildContext cxt) => ConfirmDialog( | ||||
| // //                           message: "You need to enable location services to mark attendance", | ||||
| // //                           onTap: () async { | ||||
| // //                             Navigator.pop(context); | ||||
| // //                             await Geolocator.openLocationSettings(); | ||||
| // //                           }, | ||||
| // //                         ), | ||||
| // //                       ); | ||||
| // //                     } | ||||
| // //                   }); | ||||
| // //                 } | ||||
| // //               }), | ||||
| @ -0,0 +1,68 @@ | ||||
| 
 | ||||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| class SwipeModel { | ||||
|   final bool? data; | ||||
|   final String? message; | ||||
|   final String ?title; | ||||
|   final String ?innerMessage; | ||||
|   final int ?responseCode; | ||||
|   final bool ?isSuccess; | ||||
| 
 | ||||
|   SwipeModel({ | ||||
|      this.data, | ||||
|     this.message, | ||||
|     this.title, | ||||
|     this.innerMessage, | ||||
|      this.responseCode, | ||||
|     this.isSuccess, | ||||
|   }); | ||||
| 
 | ||||
|   factory SwipeModel.fromJson(Map<String, dynamic> json) { | ||||
|     return SwipeModel( | ||||
|       data: json['data'], | ||||
|       message: json['message'] , | ||||
|       title: json['title'] , | ||||
|       innerMessage: json['innerMessage'] , | ||||
|       responseCode: json['responseCode'], | ||||
|       isSuccess: json['isSuccess'] , | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return { | ||||
|       'data': data, | ||||
|       'message': message, | ||||
|       'title': title, | ||||
|       'innerMessage': innerMessage, | ||||
|       'responseCode': responseCode, | ||||
|       'isSuccess': isSuccess, | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| class Swipe { | ||||
|   final int ?swipeTypeValue; | ||||
|   final String? value; | ||||
|   final double? latitude; | ||||
|   final double? longitude; | ||||
| 
 | ||||
|   Swipe({ | ||||
|      this.swipeTypeValue, | ||||
|     this.value, | ||||
|    this.latitude, | ||||
|     this.longitude, | ||||
|   }); | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return { | ||||
|       'swipeTypeValue': swipeTypeValue, | ||||
|       'value': value, | ||||
|       'latitude': latitude, | ||||
|       'longitude': longitude, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @ -0,0 +1,47 @@ | ||||
| class SwipeHistory { | ||||
|   final int ?id; | ||||
|   final String? swipeTypeName; | ||||
|   final String? userName; | ||||
|   final String ?siteName; | ||||
|   final String ?pointName; | ||||
|   final String  ?swipeTime; | ||||
|   final bool ?isSuccess; | ||||
|   final String? errorMessage; | ||||
| 
 | ||||
|   SwipeHistory({ | ||||
|      this.id, | ||||
|      this.swipeTypeName, | ||||
|      this.userName, | ||||
|      this.siteName, | ||||
|      this.pointName, | ||||
|      this.swipeTime, | ||||
|      this.isSuccess, | ||||
|      this.errorMessage, | ||||
|   }); | ||||
| 
 | ||||
|   factory SwipeHistory.fromJson(Map<String, dynamic> json) { | ||||
|     return SwipeHistory( | ||||
|       id: json['id'], | ||||
|       swipeTypeName: json['swipeTypeName'], | ||||
|       userName: json['userName'], | ||||
|       siteName: json['siteName'], | ||||
|       pointName: json['pointName'], | ||||
|       swipeTime: json['swipeTime']!=null? DateTime.parse(json['swipeTime']).toIso8601String():'', | ||||
|       isSuccess: json['isSuccess'], | ||||
|       errorMessage: json['errorMessage'], | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return { | ||||
|       'id': id, | ||||
|       'swipeTypeName': swipeTypeName, | ||||
|       'userName': userName, | ||||
|       'siteName': siteName, | ||||
|       'pointName': pointName, | ||||
|       'swipeTime': swipeTime, | ||||
|       'isSuccess': isSuccess, | ||||
|       'errorMessage': errorMessage, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,47 @@ | ||||
| class SwipeTransaction { | ||||
|   final int ?id; | ||||
|   final String? swipeTypeName; | ||||
|   final String ?userName; | ||||
|   final String? siteName; | ||||
|   final String? pointName; | ||||
|   final DateTime? swipeTime; | ||||
|   final bool? isSuccess; | ||||
|   final String? errorMessage; | ||||
| 
 | ||||
|   SwipeTransaction({ | ||||
|      this.id, | ||||
|      this.swipeTypeName, | ||||
|      this.userName, | ||||
|      this.siteName, | ||||
|      this.pointName, | ||||
|      this.swipeTime, | ||||
|      this.isSuccess, | ||||
|      this.errorMessage, | ||||
|   }); | ||||
| 
 | ||||
|   factory SwipeTransaction.fromJson(Map<String, dynamic> json) { | ||||
|     return SwipeTransaction( | ||||
|       id: json['id'] as int, | ||||
|       swipeTypeName: json['swipeTypeName'] , | ||||
|       userName: json['userName'] , | ||||
|       siteName: json['siteName'] , | ||||
|       pointName: json['pointName'] , | ||||
|       swipeTime: DateTime.parse(json['swipeTime']), | ||||
|       isSuccess: json['isSuccess'] , | ||||
|       errorMessage: json['errorMessage'] , | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Map<String, dynamic> toJson() { | ||||
|   //   return { | ||||
|   //     'id': id, | ||||
|   //     'swipeTypeName': swipeTypeName, | ||||
|   //     'userName': userName, | ||||
|   //     'siteName': siteName, | ||||
|   //     'pointName': pointName, | ||||
|   //     'swipeTime': swipeTime.toIso8601String(), | ||||
|   //     'isSuccess': isSuccess, | ||||
|   //     'errorMessage': errorMessage, | ||||
|   //   }; | ||||
|   // } | ||||
| } | ||||
| @ -0,0 +1,84 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:nfc_manager/nfc_manager.dart'; | ||||
| import 'package:test_sa/extensions/context_extension.dart'; | ||||
| import 'package:test_sa/extensions/text_extensions.dart'; | ||||
| import 'package:test_sa/extensions/widget_extensions.dart'; | ||||
| import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| 
 | ||||
| class NonHmgEmployeeSwipeView extends StatefulWidget { | ||||
|   NonHmgEmployeeSwipeView({Key? key}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   _NonHmgEmployeeSwipeViewState createState() { | ||||
|     return _NonHmgEmployeeSwipeViewState(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class _NonHmgEmployeeSwipeViewState extends State<NonHmgEmployeeSwipeView> { | ||||
|   bool isNfcEnabled = false; | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     checkForNfcAndLocationPermission(); | ||||
|   } | ||||
| 
 | ||||
|   void checkForNfcAndLocationPermission() async { | ||||
|     isNfcEnabled = await NfcManager.instance.isAvailable(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void dispose() { | ||||
|     super.dispose(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Container( | ||||
|       padding: const EdgeInsets.all(16), | ||||
|       margin: const EdgeInsets.only(top: 21), | ||||
|       decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: Colors.white, border: Border.all(color: AppColor.white936.withOpacity(.05), width: 1)), | ||||
|       width: double.infinity, | ||||
|       child: Column( | ||||
|         crossAxisAlignment: CrossAxisAlignment.start, | ||||
|         mainAxisSize: MainAxisSize.min, | ||||
|         children: [ | ||||
|           Text( | ||||
|             "Mark Attendance", | ||||
|             style: AppTextStyles.heading5.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), | ||||
|           ), | ||||
|           GridView( | ||||
|             physics: const NeverScrollableScrollPhysics(), | ||||
|             shrinkWrap: true, | ||||
|             padding: const EdgeInsets.only(bottom: 0, top: 16), | ||||
|             gridDelegate: | ||||
|             SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 16, mainAxisSpacing: 16), | ||||
|             children: <Widget>[ | ||||
|               gridItem("Nfc", Icons.nfc, isNfcEnabled).onPress(isNfcEnabled ? () {} : null), | ||||
|               gridItem("Qr Scan", Icons.qr_code, true).onPress(() {}), | ||||
|             ], | ||||
|           ) | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Widget gridItem(String label, IconData iconData, bool enable) { | ||||
|     return Container( | ||||
|       padding: const EdgeInsets.all(16), | ||||
|       decoration: BoxDecoration(borderRadius: BorderRadius.circular(25), color: AppColor.white30, border: Border.all(color: AppColor.white936.withOpacity(.03), width: 1)), | ||||
|       alignment: Alignment.center, | ||||
|       child: Column( | ||||
|         //mainAxisSize: MainAxisSize.min, | ||||
|         mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||||
|         children: [ | ||||
|           Icon(iconData, color: enable ? AppColor.black35 : Colors.grey), | ||||
|           Text( | ||||
|             label, | ||||
|             style: AppTextStyles.heading6.copyWith(color: enable ? AppColor.black35 : Colors.grey), | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,189 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:test_sa/controllers/providers/api/user_provider.dart'; | ||||
| import 'package:test_sa/extensions/context_extension.dart'; | ||||
| import 'package:test_sa/extensions/int_extensions.dart'; | ||||
| import 'package:test_sa/extensions/string_extensions.dart'; | ||||
| import 'package:test_sa/extensions/text_extensions.dart'; | ||||
| import 'package:test_sa/extensions/widget_extensions.dart'; | ||||
| import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; | ||||
| import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; | ||||
| import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; | ||||
| import 'package:test_sa/views/widgets/loaders/lazy_loading.dart'; | ||||
| import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; | ||||
| 
 | ||||
| 
 | ||||
| import 'models/swipe_transaction_history.dart'; | ||||
| 
 | ||||
| class SwipeHistoryView extends StatefulWidget { | ||||
|   static const routeName = '/swipe_list_view'; | ||||
| 
 | ||||
|   const SwipeHistoryView({Key? key}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   State<SwipeHistoryView> createState() => _SwipeHistoryViewState(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| class _SwipeHistoryViewState extends State<SwipeHistoryView> { | ||||
|   DateTime dateFrom = DateTime.now(); | ||||
|   DateTime dateTo = DateTime.now(); | ||||
|   UserProvider? _userProvider; | ||||
|   @override | ||||
|   void initState() { | ||||
|     getSwipeHistory(); | ||||
|     super.initState(); | ||||
|   } | ||||
| 
 | ||||
|   void  getSwipeHistory () { | ||||
|     _userProvider = Provider.of<UserProvider>(context,listen:false); | ||||
|     WidgetsBinding.instance.addPostFrameCallback((_) async { | ||||
|       await  _userProvider!.getSwipeTransactionHistory(userId: _userProvider!.user!.userID!,dateFrom: dateFrom,dateTo: dateTo); | ||||
|     }); | ||||
|   } | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return  Scaffold( | ||||
|       appBar: const DefaultAppBar(title: 'Swipe History',), | ||||
|       body: Column( | ||||
|         crossAxisAlignment:CrossAxisAlignment.start, | ||||
|         children: [ | ||||
| 
 | ||||
|           8.height, | ||||
|           Row( | ||||
|             children: [ | ||||
|               ADatePicker( | ||||
|                 label: context.translation.from, | ||||
|                 date: dateFrom, | ||||
|                 from: DateTime(DateTime.now().year - 5, DateTime.now().month, DateTime.now().day), | ||||
|                 formatDateWithTime: true, | ||||
|                 onDatePicker: (selectedDate) { | ||||
|                   if (selectedDate != null) { | ||||
|                     showTimePicker( | ||||
|                       context: context, | ||||
|                       initialTime: TimeOfDay.now(), | ||||
|                     ).then((selectedTime) { | ||||
|                       // Handle the selected date and time here. | ||||
|                       if (selectedTime != null) { | ||||
|                         DateTime selectedDateTime = DateTime( | ||||
|                           selectedDate.year, | ||||
|                           selectedDate.month, | ||||
|                           selectedDate.day, | ||||
|                           selectedTime.hour, | ||||
|                           selectedTime.minute, | ||||
|                         ); | ||||
|                         if (selectedDateTime != null) { | ||||
|                           setState(() { | ||||
|                             dateFrom = selectedDateTime; | ||||
|                           }); | ||||
|                         } | ||||
|                       } | ||||
|                     }); | ||||
|                   } | ||||
|                 }, | ||||
|               ).expanded, | ||||
|               8.width, | ||||
|               ADatePicker( | ||||
|                 label: context.translation.to, | ||||
|                 date: dateTo, | ||||
|                 from: DateTime(DateTime.now().year - 5, DateTime.now().month, DateTime.now().day), | ||||
|                 formatDateWithTime: true, | ||||
|                 onDatePicker: (selectedDate) { | ||||
|                   if (selectedDate != null) { | ||||
|                     showTimePicker( | ||||
|                       context: context, | ||||
|                       initialTime: TimeOfDay.now(), | ||||
|                     ).then((selectedTime) { | ||||
|                       // Handle the selected date and time here. | ||||
|                       if (selectedTime != null) { | ||||
|                         DateTime selectedDateTime = DateTime( | ||||
|                           selectedDate.year, | ||||
|                           selectedDate.month, | ||||
|                           selectedDate.day, | ||||
|                           selectedTime.hour, | ||||
|                           selectedTime.minute, | ||||
|                         ); | ||||
|                         if (selectedDateTime != null) { | ||||
|                           setState(() { | ||||
|                            dateTo = selectedDateTime; | ||||
| 
 | ||||
|                           }); | ||||
| 
 | ||||
|                         } | ||||
|                       } | ||||
|                     }); | ||||
|                   } | ||||
|                 }, | ||||
|               ).expanded, | ||||
|             ], | ||||
|           ), | ||||
|           12.height, | ||||
| 
 | ||||
|           AppFilledButton(label: context.translation.search, maxWidth: false, onPressed: getSwipeHistory), | ||||
|           8.height, | ||||
|           const Divider(thickness: 2,color:AppColor.white60 ,), | ||||
| 
 | ||||
|           Consumer<UserProvider>( | ||||
|             builder: (context, snapshot,child) { | ||||
|               return SwipeHistoryList(snapshot.swipeHistory ?? [], snapshot.isLoading).expanded; | ||||
|             } | ||||
|           ), | ||||
| 
 | ||||
| 
 | ||||
|         ], | ||||
|       ).paddingAll(20), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class SwipeHistoryList extends StatelessWidget { | ||||
|   List<SwipeHistory> list; | ||||
|   bool isLoading; | ||||
| 
 | ||||
|   SwipeHistoryList(this.list, this.isLoading, {Key ?key}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return (list.isEmpty && !isLoading) | ||||
|         ? NoDataFound(message: context.translation.noDataFound).center | ||||
|         : ListView.separated( | ||||
|         padding:  EdgeInsets.only(top: 12.toScreenHeight), | ||||
|         itemBuilder: (cxt, index) { | ||||
|           if (isLoading) return const SizedBox().toRequestShimmer(cxt, isLoading); | ||||
|           return SwipeHistoryCard(list[index]); | ||||
|         }, | ||||
|         separatorBuilder: (cxt, index) => 12.height, | ||||
|         itemCount: isLoading ? 6 : list.length); | ||||
|   } | ||||
| } | ||||
| class SwipeHistoryCard extends StatelessWidget { | ||||
|   final SwipeHistory swipeHistory; | ||||
|   final bool showShadow; | ||||
|   const SwipeHistoryCard(this.swipeHistory, {Key? key, this.showShadow = true}) : super(key: key); | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Column( | ||||
|       mainAxisSize: MainAxisSize.min, | ||||
|       crossAxisAlignment: CrossAxisAlignment.start, | ||||
|       children: [ | ||||
|         Row( | ||||
|           crossAxisAlignment: CrossAxisAlignment.start, | ||||
|           children: [ | ||||
|             Text(swipeHistory.swipeTime!.toServiceRequestDetailsFormat, textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50)), | ||||
|           ], | ||||
|         ), | ||||
|         8.height, | ||||
|         '${context.translation.swipeTypeName}: ${swipeHistory.swipeTypeName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), | ||||
|         '${context.translation.userName}:  ${swipeHistory.userName}'.bodyText(context), | ||||
|         '${context.translation.siteName}: ${swipeHistory.siteName}'.bodyText(context), | ||||
|         '${context.translation.pointName}: ${swipeHistory.pointName}'.bodyText(context), | ||||
|         8.height, | ||||
|       ], | ||||
|     ).toShadowContainer(context, showShadow: showShadow); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @ -0,0 +1,60 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:test_sa/extensions/context_extension.dart'; | ||||
| import 'package:test_sa/extensions/int_extensions.dart'; | ||||
| import 'package:test_sa/extensions/text_extensions.dart'; | ||||
| import 'package:test_sa/extensions/widget_extensions.dart'; | ||||
| import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; | ||||
| 
 | ||||
| class SwipeSuccessView extends StatelessWidget { | ||||
|   static const routeName = '/swipe_success_view'; | ||||
|   const SwipeSuccessView({Key ?key}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return  Scaffold( | ||||
|       body: Column( | ||||
|         children: [ | ||||
|           Column( | ||||
|             mainAxisAlignment: MainAxisAlignment.center, | ||||
|             crossAxisAlignment:CrossAxisAlignment.center, | ||||
|             children: [ | ||||
|               'swipe_success'.toSvgAsset(), | ||||
|               17.height, | ||||
|               context.translation.successful.heading4(context).custom(color: AppColor.white936), | ||||
|               8.height, | ||||
|               context.translation.youHaveSuccessfullyMarkedYourAttendance.bodyText2(context).custom(color: AppColor.neutral120), | ||||
|             ], | ||||
|           ).expanded, | ||||
|           AppFilledButton( | ||||
|             label: 'Close', | ||||
|             maxWidth: true, | ||||
|             onPressed:(){ | ||||
|               Navigator.pop(context); | ||||
|             }, | ||||
|           ), | ||||
|         ], | ||||
|       ).paddingOnly(start: 20, end: 20, bottom: 16), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // ClipOval( | ||||
| //   child: Container( | ||||
| //      color: Colors.grey.withOpacity(0.2), | ||||
| //     padding: const EdgeInsets.all(10), | ||||
| //     child: ClipOval( | ||||
| //       child: Container( | ||||
| //         color: AppColor.white.withOpacity(0.2), | ||||
| //         padding: const EdgeInsets.all(10), | ||||
| //         child: ClipOval( | ||||
| //           child: Container( | ||||
| //             color: AppColor.white, | ||||
| //             child: 'success_swipe'.toSvgAsset().paddingAll(50), | ||||
| //           ), | ||||
| //         ).paddingAll(20), | ||||
| //       ), | ||||
| //     ), | ||||
| //   ), | ||||
| // ) | ||||
| @ -0,0 +1,67 @@ | ||||
| import 'dart:async'; | ||||
| 
 | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:geolocator/geolocator.dart'; | ||||
| import 'package:permission_handler/permission_handler.dart'; | ||||
| 
 | ||||
| class LocationUtilities { | ||||
|   static void havePermission(Function(bool) callback) { | ||||
|     Geolocator.checkPermission().then((value) async { | ||||
|       if (value == LocationPermission.denied || value == LocationPermission.deniedForever) { | ||||
|         value = await Geolocator.requestPermission(); | ||||
|         callback(![LocationPermission.denied, LocationPermission.deniedForever].contains(value)); | ||||
|       } else { | ||||
|         callback(true); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   static void isEnabled(Function(bool) callback) { | ||||
|     Geolocator.isLocationServiceEnabled().then((value) => callback(value)); | ||||
|   } | ||||
| 
 | ||||
|   static bool _listeningSettingChange = true; | ||||
| 
 | ||||
|   static void listenGPS({bool change = true, Function(bool) ?onChange}) async { | ||||
|     _listeningSettingChange = change; | ||||
|     if (change == false) return; | ||||
| 
 | ||||
|     Future.doWhile(() async { | ||||
|       await Future.delayed(const Duration(milliseconds: 1000)); | ||||
|       var enable = await Geolocator.isLocationServiceEnabled(); | ||||
|       onChange!(enable); | ||||
|       return _listeningSettingChange; | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   static void locationFun(Function(bool) completion, BuildContext context) { | ||||
|     Permission.location.isGranted.then((isGranted) { | ||||
|       if (!isGranted) { | ||||
|         Permission.location.request().then((granted) { | ||||
|           completion(granted == PermissionStatus.granted); | ||||
|         }); | ||||
|       } | ||||
|       completion(isGranted); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   static void getCurrentLocation(Function(Position position, bool isMocked) callback, Function errorCallBack, BuildContext context) { | ||||
|     void done(Position position) { | ||||
|       //AppStorage.sp.saveLocation(position); | ||||
|       bool isMocked = position.isMocked; | ||||
|       callback(position, isMocked); | ||||
|     } | ||||
| 
 | ||||
|     locationFun((granted) { | ||||
|       if (granted) { | ||||
|         Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.medium, timeLimit: const Duration(seconds: 5)).then((value) { | ||||
|           done(value); | ||||
|         }).catchError((err) { | ||||
|           errorCallBack(); | ||||
|         }); | ||||
|       } else { | ||||
|         // AppPermissions | ||||
|       } | ||||
|     }, context); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,530 @@ | ||||
| import 'dart:async'; | ||||
| import 'dart:convert'; | ||||
| import 'dart:developer'; | ||||
| import 'dart:io'; | ||||
| 
 | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:geolocator/geolocator.dart'; | ||||
| import 'package:google_api_availability/google_api_availability.dart'; | ||||
| import 'package:huawei_location/huawei_location.dart'; | ||||
| import 'package:intl/intl.dart'; | ||||
| import 'package:nfc_manager/nfc_manager.dart'; | ||||
| import 'package:nfc_manager/platform_tags.dart'; | ||||
| import 'package:permission_handler/permission_handler.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:test_sa/controllers/providers/api/user_provider.dart'; | ||||
| import 'package:test_sa/extensions/context_extension.dart'; | ||||
| import 'package:test_sa/extensions/int_extensions.dart'; | ||||
| import 'package:test_sa/extensions/text_extensions.dart'; | ||||
| import 'package:test_sa/extensions/widget_extensions.dart'; | ||||
| import 'package:test_sa/main.dart'; | ||||
| import 'package:test_sa/new_views/app_style/app_color.dart'; | ||||
| import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; | ||||
| import 'package:test_sa/new_views/swipe_module/dialoge/confirm_dialog.dart'; | ||||
| import 'package:test_sa/new_views/swipe_module/dialoge/nfc_reader_sheet.dart'; | ||||
| import 'package:test_sa/new_views/swipe_module/enums/swipe_type.dart'; | ||||
| import 'package:test_sa/new_views/swipe_module/models/swipe_model.dart'; | ||||
| import 'package:test_sa/new_views/swipe_module/swipe_success_view.dart'; | ||||
| import 'package:test_sa/new_views/swipe_module/utils/location_utils.dart'; | ||||
| import 'package:test_sa/views/widgets/qr/scan_qr.dart'; | ||||
| import 'package:wifi_iot/wifi_iot.dart'; | ||||
| 
 | ||||
| class SwipeGeneralUtils { | ||||
|   SwipeGeneralUtils._(); | ||||
| 
 | ||||
|   static SwipeGeneralUtils instance = SwipeGeneralUtils._(); | ||||
|   static bool _isLoadingVisible = false; | ||||
| 
 | ||||
|   static bool get isLoading => _isLoadingVisible; | ||||
| 
 | ||||
|   void markFakeAttendance(dynamic sourceName, String lat, String long, @required BuildContext context) async { | ||||
|     showLoading(context); | ||||
|     try { | ||||
|       hideLoading(navigatorKey.currentState!.overlay!.context); | ||||
|       confirmDialog(navigatorKey.currentState!.overlay!.context, "Fake Location)"); | ||||
|     } catch (ex) { | ||||
|       log('$ex'); | ||||
|       hideLoading(context); | ||||
|       //handleException(ex, context, null); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void showLoading(BuildContext context) { | ||||
|     WidgetsBinding.instance.addPostFrameCallback((_) { | ||||
|       _isLoadingVisible = true; | ||||
|       showDialog( | ||||
|         context: context, | ||||
|         barrierColor: Colors.black.withOpacity(0.5), | ||||
|         useRootNavigator: false, | ||||
|         builder: (BuildContext context) => const AppLazyLoading(), | ||||
|       ).then((value) { | ||||
|         _isLoadingVisible = false; | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   void hideLoading(BuildContext context) { | ||||
|     if (_isLoadingVisible) { | ||||
|       _isLoadingVisible = false; | ||||
|       Navigator.of(context).pop(); | ||||
|     } | ||||
|     _isLoadingVisible = false; | ||||
|   } | ||||
| 
 | ||||
|   static Future<String> getStringFromPrefs(String key) async { | ||||
|     SharedPreferences prefs = await SharedPreferences.getInstance(); | ||||
|     return prefs.getString(key) ?? ""; | ||||
|   } | ||||
| 
 | ||||
|   void confirmDialog(cxt, String message, {VoidCallback? onTap}) { | ||||
|     showDialog( | ||||
|       context: cxt, | ||||
|       builder: (BuildContext cxt) => ConfirmDialog(message: message, onTap: onTap), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   void showErrorDialog({String ?message, required BuildContext context}) { | ||||
|     showDialog( | ||||
|       context: context, | ||||
|       builder: (context) => ConfirmDialog(message: message, title: 'Error', onTap: () => Navigator.pop(context)), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   void showMDialog(context, {Widget ?child, Color? backgroundColor, bool isDismissable = true, bool isBusniessCard = false}) async { | ||||
|     return showDialog( | ||||
|       context: context, | ||||
|       barrierDismissible: isDismissable, | ||||
|       builder: (context) { | ||||
|         return Dialog( | ||||
|           shape: isBusniessCard | ||||
|               ? const RoundedRectangleBorder( | ||||
|                   borderRadius: BorderRadius.all( | ||||
|                     Radius.circular(15.0), | ||||
|                   ), | ||||
|                 ) | ||||
|               : null, | ||||
|           backgroundColor: backgroundColor, | ||||
|           child: child, | ||||
|         ); | ||||
|       }, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Widget attendanceTypeCard(String title, String icon, bool isEnabled, VoidCallback onPress, BuildContext context) { | ||||
|     return Container( | ||||
|       padding: const EdgeInsets.all(12), | ||||
|       decoration: BoxDecoration( | ||||
|         color: isEnabled ? Colors.white : AppColor.white70, | ||||
|         borderRadius: BorderRadius.circular(18), | ||||
|         border: Border.all(color: AppColor.white70, width: 2), | ||||
|       ), | ||||
|       child: Column( | ||||
|         crossAxisAlignment: CrossAxisAlignment.start, | ||||
|         mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|         children: [ | ||||
|           icon.toSvgAsset(color: isEnabled ? null : Colors.grey.withOpacity(0.5)), | ||||
|           title.heading5(context).custom(color: isEnabled ? AppColor.neutral50 : Colors.grey.withOpacity(0.5)), | ||||
|         ], | ||||
|       ), | ||||
|     ).onPress( | ||||
|       () { | ||||
|         if (!isEnabled) return; | ||||
|         onPress(); | ||||
|       }, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   //huawei permission part.... | ||||
|   void getHuaweiCurrentLocation({SwipeTypeEnum ?attendanceType, required BuildContext context}) async { | ||||
|     try { | ||||
|       showLoading(context); | ||||
|       FusedLocationProviderClient locationService = FusedLocationProviderClient()..initFusedLocationService(); | ||||
|       LocationRequest locationRequest = LocationRequest(); | ||||
|       locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY; | ||||
|       locationRequest.interval = 500; | ||||
|       List<LocationRequest> locationRequestList = <LocationRequest>[locationRequest]; | ||||
|       LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList); | ||||
| 
 | ||||
|       StreamSubscription<Location> _streamSubscription; | ||||
|       int requestCode = (await (locationService.requestLocationUpdates(locationRequest)))!; | ||||
|       _streamSubscription = locationService.onLocationData!.listen( | ||||
|         (Location location) async { | ||||
|           hideLoading(context); | ||||
|           await locationService.removeLocationUpdates(requestCode); | ||||
|           handleSwipeOperation(swipeType: attendanceType!, context: context, lat: location.latitude??0, long: location.longitude??0); | ||||
|           requestCode = 0; | ||||
|           //TODO cancel this stream when listening done.. | ||||
|           // _streamSubscription.cancel(); | ||||
|         }, | ||||
|       ); | ||||
|     } catch (error) { | ||||
|       log("HUAWEI LOCATION ERROR!!!!!"); | ||||
|       log('$error'); | ||||
|       hideLoading(context); | ||||
|       // handleException(error, context, null); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<bool> requestPermissions() async { | ||||
|     var result = await [ | ||||
|       Permission.location, | ||||
|     ].request(); | ||||
|     return (result[Permission.location] == PermissionStatus.granted || result[Permission.locationAlways] == PermissionStatus.granted); | ||||
|   } | ||||
| 
 | ||||
|   void checkHuaweiLocationPermission({required SwipeTypeEnum attendanceType,required  BuildContext context}) async { | ||||
|     // Permission_Handler permissionHandler = PermissionHandler(); | ||||
|     LocationUtilities.isEnabled((bool isEnabled) async { | ||||
|       if (isEnabled) { | ||||
|         LocationUtilities.havePermission((bool permission) async { | ||||
|           if (permission) { | ||||
|             getHuaweiCurrentLocation(attendanceType: attendanceType, context: context); | ||||
|           } else { | ||||
|             bool has = await requestPermissions(); | ||||
|             if (has) { | ||||
|               getHuaweiCurrentLocation(attendanceType: attendanceType, context: context); | ||||
|             } else { | ||||
|               showDialog( | ||||
|                 context: context, | ||||
|                 builder: (BuildContext cxt) => ConfirmDialog( | ||||
|                   message: "You need to give location permission to mark attendance", | ||||
|                   onTap: () { | ||||
|                     Navigator.pop(context); | ||||
|                   }, | ||||
|                 ), | ||||
|               ); | ||||
|             } | ||||
|           } | ||||
|         }); | ||||
|       } else { | ||||
|         showDialog( | ||||
|           context: context, | ||||
|           builder: (BuildContext cxt) => ConfirmDialog( | ||||
|             message: "You need to enable location services to mark attendance", | ||||
|             onTap: () async { | ||||
|               Navigator.pop(context); | ||||
|               await Geolocator.openLocationSettings(); | ||||
|             }, | ||||
|           ), | ||||
|         ); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     // if (await permissionHandler.hasLocationPermission()) { | ||||
|     //   getHuaweiCurrentLocation(attendanceType); | ||||
|     // } else { | ||||
|     //   bool has = await requestPermissions(); | ||||
|     //   if (has) { | ||||
|     //     getHuaweiCurrentLocation(attendanceType); | ||||
|     //   } else { | ||||
|     //     showDialog( | ||||
|     //       context: context, | ||||
|     //       builder: (BuildContext cxt) => ConfirmDialog( | ||||
|     //         message: "You need to give location permission to mark attendance", | ||||
|     //         onTap: () { | ||||
|     //           Navigator.pop(context); | ||||
|     //         }, | ||||
|     //       ), | ||||
|     //     ); | ||||
|     //   } | ||||
|     // } | ||||
|   } | ||||
| 
 | ||||
|   void handleSwipeOperation({required SwipeTypeEnum swipeType,required double lat,required double long,required  BuildContext context}) { | ||||
|     switch (swipeType) { | ||||
|       case SwipeTypeEnum.NFC: | ||||
|         handleNfcAttendance(latitude: lat, longitude: long, context: context); | ||||
|         return; | ||||
|       case SwipeTypeEnum.QR: | ||||
|         performQrCodeAttendance(latitude: lat, longitude: long, context: context); | ||||
|         return; | ||||
|       case SwipeTypeEnum.Wifi: | ||||
|         performWifiAttendance(latitude: lat, long: long, context: context); | ||||
|         return; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   String formatTimeOnly(DateTime dateTime) { | ||||
|     return DateFormat.Hms().format(dateTime); | ||||
|   } | ||||
| 
 | ||||
|   Future<void> performQrCodeAttendance({double ?latitude, double? longitude,required  BuildContext context}) async { | ||||
|     UserProvider userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
| 
 | ||||
|     String qrCodeValue = await Navigator.of(context).push( | ||||
|       MaterialPageRoute(builder: (_) => ScanQr()), | ||||
|     ) as String; | ||||
| 
 | ||||
|     if (qrCodeValue != null) { | ||||
|       showLoading(context); | ||||
|       try { | ||||
|         final swipeModel = Swipe( | ||||
|           swipeTypeValue: SwipeTypeEnum.QR.getIntFromSwipeTypeEnum(), | ||||
|           value: qrCodeValue, | ||||
|           latitude: latitude, | ||||
|           longitude: longitude, | ||||
|         ); | ||||
| 
 | ||||
|         await userProvider.makeSwipe(model: swipeModel).then((swipeResponse) { | ||||
|           if (swipeResponse.isSuccess==true) { | ||||
|             hideLoading(context); | ||||
|             Navigator.pushNamed(context, SwipeSuccessView.routeName); | ||||
|           } else { | ||||
|             hideLoading(context); | ||||
|             showDialog( | ||||
|               barrierDismissible: true, | ||||
|               context: context, | ||||
|               builder: (cxt) => ConfirmDialog( | ||||
|                 message: swipeResponse.message ?? "", | ||||
|                 onTap: () { | ||||
|                   Navigator.pop(context); | ||||
|                 }, | ||||
|                 onCloseTap: () {}, | ||||
|               ), | ||||
|             ); | ||||
|           } | ||||
|         }); | ||||
|       } catch (ex) { | ||||
|         log('$ex'); | ||||
|         hideLoading(context); | ||||
|         //this need to confirm where it comes.. | ||||
|         // handleException(ex, context, null); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> handleNfcAttendance({double ?latitude = 0, double? longitude = 0,required  BuildContext context}) async { | ||||
|     // UserProvider _userProvider = Provider.of<UserProvider>(context,listen:false); | ||||
| 
 | ||||
|     if (Platform.isIOS) { | ||||
|       readNFc(onRead: (String nfcId) async { | ||||
|         await _processNfcAttendance(nfcId, latitude, longitude, context); | ||||
|       }); | ||||
|     } else { | ||||
|       showNfcReader(context, onNcfScan: (String nfcId) async { | ||||
|         await _processNfcAttendance(nfcId ?? '', latitude, longitude, context); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> _processNfcAttendance( | ||||
|     String nfcId, | ||||
|     double ?latitude, | ||||
|     double ?longitude, | ||||
|     BuildContext context, | ||||
|   ) async { | ||||
|     showLoading(context); | ||||
|     try { | ||||
|       final swipeModel = Swipe(swipeTypeValue: SwipeTypeEnum.NFC.getIntFromSwipeTypeEnum(), value: nfcId, latitude: latitude, longitude: longitude); | ||||
|       UserProvider userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
| 
 | ||||
|       final swipeResponse = await userProvider.makeSwipe(model: swipeModel); | ||||
| 
 | ||||
|       if (swipeResponse.isSuccess==true) { | ||||
|         hideLoading(context); | ||||
|         Navigator.pushNamed(context, SwipeSuccessView.routeName); | ||||
|       } else { | ||||
|         hideLoading(context); | ||||
|         showErrorDialog(message: swipeResponse.message ?? "Unexpected error occurred", context: context); | ||||
|       } | ||||
|     } catch (errSwipeGeneralUtilsor) { | ||||
|       hideLoading(context); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void handleSwipe({required SwipeTypeEnum swipeType, required bool isEnable, required BuildContext context}) async { | ||||
|     if (Platform.isAndroid && !(await isGoogleServicesAvailable())) { | ||||
|       checkHuaweiLocationPermission(attendanceType: swipeType, context: context); | ||||
|     } else { | ||||
|       LocationUtilities.isEnabled((bool isEnabled) { | ||||
|         if (isEnabled) { | ||||
|           LocationUtilities.havePermission((bool permission) { | ||||
|             if (permission) { | ||||
|               showLoading(context); | ||||
|               LocationUtilities.getCurrentLocation( | ||||
|                 (Position position, bool isMocked) { | ||||
|                   if (isMocked) { | ||||
|                     hideLoading(context); | ||||
|                     markFakeAttendance(swipeType.name, position.latitude.toString() ?? "", position.longitude.toString() ?? "", context); | ||||
|                   } else { | ||||
|                     hideLoading(context); | ||||
|                     handleSwipeOperation(swipeType: swipeType, lat: position.latitude, long: position.longitude, context: context); | ||||
|                   } | ||||
|                 }, | ||||
|                 () { | ||||
|                   hideLoading(context); | ||||
|                   confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working."); | ||||
|                 }, | ||||
|                 context, | ||||
|               ); | ||||
|             } else { | ||||
|               showInfoDialog( | ||||
|                   message: "You need to give location permission to mark attendance", | ||||
|                   onTap: () async { | ||||
|                     await Geolocator.openAppSettings(); | ||||
|                   }); | ||||
|             } | ||||
|           }); | ||||
|         } else { | ||||
|           showInfoDialog( | ||||
|               message: "You need to enable location services to mark attendance", | ||||
|               onTap: () async { | ||||
|                 await Geolocator.openLocationSettings(); | ||||
|               }); | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void showInfoDialog({required String message, VoidCallback? onTap}) { | ||||
|     showDialog( | ||||
|       context: navigatorKey.currentState!.overlay!.context, | ||||
|       builder: (BuildContext cxt) => ConfirmDialog( | ||||
|         message: message, | ||||
|         onTap: () async { | ||||
|           Navigator.pop(navigatorKey.currentState!.overlay!.context); | ||||
|           onTap!(); | ||||
|         }, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   List<Widget> availableAttendanceMethodList({required BuildContext context, required UserProvider userProvider, required bool isNfcSupported}) { | ||||
|     List<Widget> availableMethods = []; | ||||
|     if (userProvider.user!.enableNFC!) { | ||||
|       availableMethods.add(attendanceTypeCard(SwipeTypeEnum.NFC.name, 'nfc_icon', isNfcSupported, () { | ||||
|         Navigator.pop(context); | ||||
|         handleSwipe(swipeType: SwipeTypeEnum.NFC, isEnable: userProvider.user!.enableNFC!, context: navigatorKey.currentState!.overlay!.context); | ||||
|       }, context)); | ||||
|     } | ||||
|     if (userProvider.user!.enableQR!) { | ||||
|       availableMethods.add(attendanceTypeCard(SwipeTypeEnum.QR.name, 'qr', userProvider.user!.enableQR!, () { | ||||
|         Navigator.pop(context); | ||||
|         handleSwipe(swipeType: SwipeTypeEnum.QR, isEnable: userProvider.user!.enableQR!, context: navigatorKey.currentState!.overlay!.context); | ||||
|       }, context)); | ||||
|     } | ||||
|     if (kDebugMode) { | ||||
|       userProvider.user!.enableWifi!= true; | ||||
|     } | ||||
| 
 | ||||
|     if (userProvider.user!.enableWifi!) { | ||||
|       availableMethods.add(attendanceTypeCard(SwipeTypeEnum.Wifi.name, 'wifi_icon', userProvider.user!.enableWifi!, () { | ||||
|         Navigator.pop(context); | ||||
|         handleSwipe(swipeType: SwipeTypeEnum.Wifi, isEnable: userProvider.user!.enableWifi!, context: navigatorKey.currentState!.overlay!.context); | ||||
|       }, context)); | ||||
|     } | ||||
|     return availableMethods; | ||||
|   } | ||||
| 
 | ||||
|   void showSwipeTypeBottomSheetSheet({required bool isNfcSupported}) { | ||||
|     BuildContext context = navigatorKey.currentState!.overlay!.context; | ||||
|     UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
| 
 | ||||
|     showModalBottomSheet( | ||||
|       context: context, | ||||
|       shape: const RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.vertical( | ||||
|           top: Radius.circular(20), | ||||
|         ), | ||||
|       ), | ||||
|       clipBehavior: Clip.antiAliasWithSaveLayer, | ||||
|       builder: (BuildContext context) => Column( | ||||
|         mainAxisSize: MainAxisSize.min, | ||||
|         crossAxisAlignment: CrossAxisAlignment.start, | ||||
|         children: [ | ||||
|           context.translation.markAttendance.heading4(context).custom(color: AppColor.white936), | ||||
|           8.height, | ||||
|           context.translation.selectMethodToMarkAttendance.bodyText2(context).custom(color: AppColor.neutral120), | ||||
|           12.height, | ||||
|           GridView( | ||||
|               padding: const EdgeInsets.all(0), | ||||
|               shrinkWrap: true, | ||||
|               physics: const NeverScrollableScrollPhysics(), | ||||
|               gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1, crossAxisSpacing: 12, mainAxisSpacing: 12), | ||||
|               children: availableAttendanceMethodList(context: context, userProvider: _userProvider, isNfcSupported: isNfcSupported)), | ||||
|         ], | ||||
|       ).paddingAll(16), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   void readNFc({Function(String) ?onRead}) { | ||||
|     NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { | ||||
|       MifareUltralight f; | ||||
|       if (Platform.isAndroid) { | ||||
|         f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); | ||||
|       } else { | ||||
|         f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); | ||||
|       } | ||||
|       String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); | ||||
|       NfcManager.instance.stopSession(); | ||||
|       onRead!(identifier); | ||||
|     }).catchError((err) { | ||||
|       print(err); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   //HUAWEI DECISION MAKING | ||||
|   Future<bool> isGoogleServicesAvailable() async { | ||||
|     GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability(); | ||||
|     String status = availability.toString().split('.').last; | ||||
|     if (status == "success") { | ||||
|       return true; | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   Future<void> performWifiAttendance({required double latitude, required double long, required BuildContext context}) async { | ||||
|     String ssId = String.fromCharCodes(base64Decode("SE1HLU1PSEVNTQ==")); | ||||
|     String password = String.fromCharCodes(base64Decode("TTBoZW1tQDEyMTI=")); | ||||
|     showLoading(context); | ||||
|     bool isConnected = await WiFiForIoTPlugin.connect(ssId, password: password, joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false); | ||||
| 
 | ||||
|     if (Platform.isIOS) { | ||||
|       if (await WiFiForIoTPlugin.getSSID() == ssId) { | ||||
|         isConnected = true; | ||||
|       } else { | ||||
|         isConnected = false; | ||||
|       } | ||||
|     } | ||||
|     UserProvider userProvider = Provider.of<UserProvider>(context, listen: false); | ||||
| 
 | ||||
|     if (isConnected) { | ||||
|       await WiFiForIoTPlugin.forceWifiUsage(true); | ||||
|       await Future.delayed(const Duration(seconds: 6)); | ||||
|       try { | ||||
|         final swipeModel = Swipe(swipeTypeValue: SwipeTypeEnum.Wifi.getIntFromSwipeTypeEnum(), value: '', latitude: latitude, longitude: long); | ||||
| 
 | ||||
|         final swipeResponse = await userProvider.makeSwipe(model: swipeModel); | ||||
|         await closeWifiRequest(); | ||||
|         if (swipeResponse.isSuccess==true) { | ||||
|           hideLoading(context); | ||||
|           Navigator.pushNamed(context, SwipeSuccessView.routeName); | ||||
|         } else { | ||||
|           hideLoading(context); | ||||
|           await Future.delayed(const Duration(milliseconds: 250)); | ||||
|           showErrorDialog(message: swipeResponse.message ?? "Unexpected error occurred", context: context); | ||||
|         } | ||||
|       } catch (errSwipeGeneralUtilsor) { | ||||
|         hideLoading(context); | ||||
|         await closeWifiRequest(); | ||||
|       } | ||||
|     } else { | ||||
|       // if (userProvider.) { | ||||
|       hideLoading(context); | ||||
|       confirmDialog(context, "Come Near HMG Wifi"); | ||||
|       // } else { | ||||
|       //   await closeWifiRequest(); | ||||
|       // } | ||||
|       await closeWifiRequest(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<bool> closeWifiRequest() async { | ||||
|     if (Platform.isAndroid) { | ||||
|       await WiFiForIoTPlugin.forceWifiUsage(false); | ||||
|     } | ||||
|     return await WiFiForIoTPlugin.disconnect(); | ||||
|   } | ||||
| } | ||||