| @@ -0,0 +1,5 @@ | |||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M17.7084 7.625C15.7834 4.6 12.9667 2.85834 10 2.85834C8.51669 2.85834 7.07502 3.29167 5.75835 4.1C4.44169 4.91667 3.25835 6.10834 2.29169 7.625C1.45835 8.93334 1.45835 11.0583 2.29169 12.3667C4.21669 15.4 7.03335 17.1333 10 17.1333C11.4834 17.1333 12.925 16.7 14.2417 15.8917C15.5584 15.075 16.7417 13.8833 17.7084 12.3667C18.5417 11.0667 18.5417 8.93334 17.7084 7.625ZM10 13.3667C8.13335 13.3667 6.63335 11.8583 6.63335 10C6.63335 8.14167 8.13335 6.63334 10 6.63334C11.8667 6.63334 13.3667 8.14167 13.3667 10C13.3667 11.8583 11.8667 13.3667 10 13.3667Z" fill="#6E7987"/> | |||
| <path d="M10 7.61664C8.69167 7.61664 7.625 8.6833 7.625 9.99997C7.625 11.3083 8.69167 12.375 10 12.375C11.3083 12.375 12.3833 11.3083 12.3833 9.99997C12.3833 8.69164 11.3083 7.61664 10 7.61664Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,8 @@ | |||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M17.725 7.64992C17.4834 7.26659 17.225 6.90825 16.9584 6.57492C16.65 6.18325 16.0667 6.14992 15.7167 6.49992L13.2167 8.99992C13.4 9.54992 13.4334 10.1833 13.2667 10.8416C12.975 12.0166 12.025 12.9666 10.85 13.2583C10.1917 13.4249 9.55837 13.3916 9.00837 13.2083C9.00837 13.2083 7.81671 14.3999 6.95837 15.2583C6.54171 15.6749 6.67504 16.4083 7.23337 16.6249C8.12504 16.9666 9.05004 17.1416 10 17.1416C11.4834 17.1416 12.925 16.7083 14.2417 15.8999C15.5834 15.0666 16.7917 13.8416 17.7667 12.2833C18.5584 11.0249 18.5167 8.90825 17.725 7.64992Z" fill="#6E7987"/> | |||
| <path d="M11.6834 8.3167L8.3167 11.6834C7.8917 11.25 7.6167 10.65 7.6167 10C7.6167 8.6917 8.68337 7.6167 10 7.6167C10.65 7.6167 11.25 7.8917 11.6834 8.3167Z" fill="#6E7987"/> | |||
| <path d="M15.2082 4.79173L12.3832 7.61673C11.7748 7.00006 10.9332 6.6334 9.99984 6.6334C8.13317 6.6334 6.63317 8.14173 6.63317 10.0001C6.63317 10.9334 7.00817 11.7751 7.6165 12.3834L4.79984 15.2084H4.7915C3.8665 14.4584 3.0165 13.5001 2.2915 12.3667C1.45817 11.0584 1.45817 8.9334 2.2915 7.62506C3.25817 6.1084 4.4415 4.91673 5.75817 4.10007C7.07484 3.30007 8.5165 2.8584 9.99984 2.8584C11.8582 2.8584 13.6582 3.54173 15.2082 4.79173Z" fill="#6E7987"/> | |||
| <path d="M12.3834 10.0001C12.3834 11.3084 11.3167 12.3834 10.0001 12.3834C9.95007 12.3834 9.9084 12.3834 9.8584 12.3667L12.3667 9.8584C12.3834 9.9084 12.3834 9.95007 12.3834 10.0001Z" fill="#6E7987"/> | |||
| <path d="M18.1417 1.8584C17.8917 1.6084 17.4834 1.6084 17.2334 1.8584L1.8584 17.2417C1.6084 17.4917 1.6084 17.9001 1.8584 18.1501C1.9834 18.2667 2.14173 18.3334 2.3084 18.3334C2.47507 18.3334 2.6334 18.2667 2.7584 18.1417L18.1417 2.7584C18.4001 2.5084 18.4001 2.1084 18.1417 1.8584Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,4 @@ | |||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M12.0002 0.333496C5.57183 0.333496 0.333496 5.57183 0.333496 12.0002C0.333496 18.4285 5.57183 23.6668 12.0002 23.6668C18.4285 23.6668 23.6668 18.4285 23.6668 12.0002C23.6668 5.57183 18.4285 0.333496 12.0002 0.333496ZM16.6668 12.8752H12.8752V16.6668C12.8752 17.1452 12.4785 17.5418 12.0002 17.5418C11.5218 17.5418 11.1252 17.1452 11.1252 16.6668V12.8752H7.3335C6.85516 12.8752 6.4585 12.4785 6.4585 12.0002C6.4585 11.5218 6.85516 11.1252 7.3335 11.1252H11.1252V7.3335C11.1252 6.85516 11.5218 6.4585 12.0002 6.4585C12.4785 6.4585 12.8752 6.85516 12.8752 7.3335V11.1252H16.6668C17.1452 11.1252 17.5418 11.5218 17.5418 12.0002C17.5418 12.4785 17.1452 12.8752 16.6668 12.8752Z" fill="white"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M12 2C6.49 2 2 6.49 2 12C2 17.51 6.49 22 12 22C17.51 22 22 17.51 22 12C22 6.49 17.51 2 12 2ZM16 12.75H12.75V16C12.75 16.41 12.41 16.75 12 16.75C11.59 16.75 11.25 16.41 11.25 16V12.75H8C7.59 12.75 7.25 12.41 7.25 12C7.25 11.59 7.59 11.25 8 11.25H11.25V8C11.25 7.59 11.59 7.25 12 7.25C12.41 7.25 12.75 7.59 12.75 8V11.25H16C16.41 11.25 16.75 11.59 16.75 12C16.75 12.41 16.41 12.75 16 12.75Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,9 @@ | |||
| <svg width="41" height="40" viewBox="0 0 41 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <rect x="0.25" width="40" height="40" rx="20" fill="#EAF6EB"/> | |||
| <path opacity="0.2" d="M28.5005 14.75H12.0005C11.5863 14.75 11.2505 15.0858 11.2505 15.5V27.5C11.2505 27.9142 11.5863 28.25 12.0005 28.25H28.5005C28.9147 28.25 29.2505 27.9142 29.2505 27.5V15.5C29.2505 15.0858 28.9147 14.75 28.5005 14.75Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M20.25 18.125C20.6642 18.125 21 18.4608 21 18.875V24.125C21 24.5392 20.6642 24.875 20.25 24.875C19.8358 24.875 19.5 24.5392 19.5 24.125V18.875C19.5 18.4608 19.8358 18.125 20.25 18.125Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M16.875 21.5C16.875 21.0858 17.2108 20.75 17.625 20.75H22.875C23.2892 20.75 23.625 21.0858 23.625 21.5C23.625 21.9142 23.2892 22.25 22.875 22.25H17.625C17.2108 22.25 16.875 21.9142 16.875 21.5Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M10.5005 15.5C10.5005 14.6716 11.1721 14 12.0005 14H28.5005C29.3289 14 30.0005 14.6716 30.0005 15.5V27.5C30.0005 28.3284 29.3289 29 28.5005 29H12.0005C11.1721 29 10.5005 28.3284 10.5005 27.5V15.5ZM28.5005 15.5H12.0005V27.5H28.5005V15.5Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M16.409 11.659C16.831 11.2371 17.4033 11 18 11H22.5C23.0967 11 23.669 11.2371 24.091 11.659C24.5129 12.081 24.75 12.6533 24.75 13.25V14.75C24.75 15.1642 24.4142 15.5 24 15.5C23.5858 15.5 23.25 15.1642 23.25 14.75V13.25C23.25 13.0511 23.171 12.8603 23.0303 12.7197C22.8897 12.579 22.6989 12.5 22.5 12.5H18C17.8011 12.5 17.6103 12.579 17.4697 12.7197C17.329 12.8603 17.25 13.0511 17.25 13.25V14.75C17.25 15.1642 16.9142 15.5 16.5 15.5C16.0858 15.5 15.75 15.1642 15.75 14.75V13.25C15.75 12.6533 15.9871 12.081 16.409 11.659Z" fill="#60BA69"/> | |||
| </svg> | |||
| @@ -0,0 +1,4 @@ | |||
| <svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M10.7935 1.83325H5.20683C2.78016 1.83325 1.3335 3.27992 1.3335 5.70658V11.2866C1.3335 13.7199 2.78016 15.1666 5.20683 15.1666H10.7868C13.2135 15.1666 14.6602 13.7199 14.6602 11.2933V5.70658C14.6668 3.27992 13.2202 1.83325 10.7935 1.83325ZM10.6668 8.99992H8.50016V11.1666C8.50016 11.4399 8.2735 11.6666 8.00016 11.6666C7.72683 11.6666 7.50016 11.4399 7.50016 11.1666V8.99992H5.3335C5.06016 8.99992 4.8335 8.77325 4.8335 8.49992C4.8335 8.22658 5.06016 7.99992 5.3335 7.99992H7.50016V5.83325C7.50016 5.55992 7.72683 5.33325 8.00016 5.33325C8.2735 5.33325 8.50016 5.55992 8.50016 5.83325V7.99992H10.6668C10.9402 7.99992 11.1668 8.22658 11.1668 8.49992C11.1668 8.77325 10.9402 8.99992 10.6668 8.99992Z" fill="#60BA69"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.36642 6.60934C2.56168 6.41408 2.87826 6.41408 3.07352 6.60934L7.42019 10.956C7.73826 11.2741 8.26168 11.2741 8.57975 10.956L12.9264 6.60934C13.1217 6.41408 13.4383 6.41408 13.6335 6.60934C13.8288 6.8046 13.8288 7.12118 13.6335 7.31644L9.28686 11.6631C8.57826 12.3717 7.42168 12.3717 6.71308 11.6631L2.36642 7.31644C2.17116 7.12118 2.17116 6.8046 2.36642 6.60934Z" fill="#2D3748"/> | |||
| </svg> | |||
| @@ -0,0 +1,4 @@ | |||
| <svg width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M8.9465 0.453369H4.79316H1.05317C0.413166 0.453369 0.0931657 1.2267 0.546499 1.68004L3.99983 5.13337C4.55317 5.6867 5.45317 5.6867 6.0065 5.13337L7.31983 3.82004L9.45983 1.68004C9.9065 1.2267 9.5865 0.453369 8.9465 0.453369Z" fill="#718096"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M15.7071 3.79289C16.0976 4.18342 16.0976 4.81658 15.7071 5.20711L8.91421 12L15.7071 18.7929C16.0976 19.1834 16.0976 19.8166 15.7071 20.2071C15.3166 20.5976 14.6834 20.5976 14.2929 20.2071L6.79289 12.7071C6.40237 12.3166 6.40237 11.6834 6.79289 11.2929L14.2929 3.79289C14.6834 3.40237 15.3166 3.40237 15.7071 3.79289Z" fill="#001133"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M5.96667 2.72027L10.3133 7.06694C10.8267 7.58027 10.8267 8.42027 10.3133 8.93361L5.96667 13.2803" stroke="#949EA8" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> | |||
| </svg> | |||
| @@ -0,0 +1,6 @@ | |||
| <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M5.64404 9.75C5.6428 8.86051 5.81762 7.97957 6.15843 7.15796C6.49924 6.33635 6.9993 5.59031 7.62977 4.96286C8.26025 4.33541 9.00868 3.83895 9.83193 3.5021C10.6552 3.16525 11.5369 2.99467 12.4264 3.00019C16.1379 3.02778 19.1067 6.11282 19.1067 9.83474V10.5C19.1067 13.8577 19.8092 15.8062 20.4279 16.8711C20.4946 16.9849 20.5301 17.1142 20.5308 17.2461C20.5315 17.378 20.4974 17.5077 20.4319 17.6222C20.3665 17.7367 20.2721 17.8319 20.1581 17.8982C20.0441 17.9646 19.9147 17.9997 19.7828 18H4.96722C4.83534 17.9997 4.70587 17.9645 4.59189 17.8982C4.4779 17.8318 4.38344 17.7366 4.31801 17.6221C4.25259 17.5076 4.21852 17.3778 4.21925 17.2459C4.21998 17.1141 4.25548 16.9847 4.32216 16.8709C4.94122 15.806 5.64404 13.8575 5.64404 10.5L5.64404 9.75Z" fill="#6E7987"/> | |||
| <path d="M5.64404 9.75C5.6428 8.86051 5.81762 7.97957 6.15843 7.15796C6.49924 6.33635 6.9993 5.59031 7.62977 4.96286C8.26025 4.33541 9.00868 3.83895 9.83193 3.5021C10.6552 3.16525 11.5369 2.99467 12.4264 3.00019C16.138 3.02778 19.1067 6.11282 19.1067 9.83474V10.5C19.1067 13.8577 19.8092 15.8062 20.4279 16.8711C20.4946 16.9849 20.5301 17.1142 20.5308 17.2461C20.5315 17.378 20.4974 17.5077 20.4319 17.6222C20.3665 17.7367 20.2721 17.8319 20.1581 17.8982C20.0441 17.9646 19.9147 17.9997 19.7828 18H4.96722C4.83534 17.9997 4.70587 17.9645 4.59189 17.8982C4.4779 17.8318 4.38344 17.7366 4.31801 17.6221C4.25259 17.5076 4.21852 17.3778 4.21925 17.2459C4.21998 17.1141 4.25548 16.9847 4.32216 16.8709C4.94122 15.806 5.64404 13.8575 5.64404 10.5L5.64404 9.75Z" stroke="#6E7987" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M9.375 18V18.75C9.375 19.5456 9.69107 20.3087 10.2537 20.8713C10.8163 21.4339 11.5794 21.75 12.375 21.75C13.1706 21.75 13.9337 21.4339 14.4963 20.8713C15.0589 20.3087 15.375 19.5456 15.375 18.75V18" stroke="#6E7987" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M16.25 2.49976H14.375V1.87476C14.375 1.709 14.3092 1.55002 14.1919 1.43281C14.0747 1.3156 13.9158 1.24976 13.75 1.24976C13.5842 1.24976 13.4253 1.3156 13.3081 1.43281C13.1908 1.55002 13.125 1.709 13.125 1.87476V2.49976H6.875V1.87476C6.875 1.709 6.80915 1.55002 6.69194 1.43281C6.57473 1.3156 6.41576 1.24976 6.25 1.24976C6.08424 1.24976 5.92527 1.3156 5.80806 1.43281C5.69085 1.55002 5.625 1.709 5.625 1.87476V2.49976H3.75C3.41858 2.50008 3.10083 2.63188 2.86648 2.86623C2.63213 3.10058 2.50033 3.41834 2.5 3.74976V16.2498C2.50033 16.5812 2.63213 16.8989 2.86648 17.1333C3.10083 17.3676 3.41858 17.4994 3.75 17.4998H16.25C16.5814 17.4994 16.8992 17.3676 17.1335 17.1333C17.3679 16.8989 17.4997 16.5812 17.5 16.2498V3.74976C17.4997 3.41834 17.3679 3.10058 17.1335 2.86623C16.8992 2.63188 16.5814 2.50008 16.25 2.49976ZM16.25 6.24976H3.75V3.74976H5.625V4.37476C5.625 4.54052 5.69085 4.69949 5.80806 4.8167C5.92527 4.93391 6.08424 4.99976 6.25 4.99976C6.41576 4.99976 6.57473 4.93391 6.69194 4.8167C6.80915 4.69949 6.875 4.54052 6.875 4.37476V3.74976H13.125V4.37476C13.125 4.54052 13.1908 4.69949 13.3081 4.8167C13.4253 4.93391 13.5842 4.99976 13.75 4.99976C13.9158 4.99976 14.0747 4.93391 14.1919 4.8167C14.3092 4.69949 14.375 4.54052 14.375 4.37476V3.74976H16.25V6.24976Z" fill="#718096"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="14" height="12" viewBox="0 0 14 12" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M12 1.5H10.2672L9.41565 0.222656C9.36999 0.154165 9.30813 0.0980054 9.23556 0.0591636C9.16299 0.0203217 9.08195 -9.29689e-07 8.99963 0H4.99963C4.91732 -8.74614e-07 4.83628 0.0203217 4.76371 0.0591636C4.69113 0.0980054 4.62927 0.154165 4.58362 0.222656L3.73206 1.5H2C1.60231 1.50045 1.22105 1.65864 0.939842 1.93984C0.658636 2.22105 0.500455 2.60231 0.5 3V10C0.500455 10.3977 0.658636 10.779 0.939842 11.0602C1.22105 11.3414 1.60231 11.4995 2 11.5H12C12.3977 11.4995 12.779 11.3414 13.0602 11.0602C13.3414 10.779 13.4995 10.3977 13.5 10V3C13.4995 2.60231 13.3414 2.22105 13.0602 1.93984C12.779 1.65864 12.3977 1.50045 12 1.5V1.5ZM9.25 6.25C9.25 6.69501 9.11804 7.13002 8.87081 7.50003C8.62357 7.87004 8.27217 8.15843 7.86104 8.32873C7.4499 8.49903 6.9975 8.54358 6.56105 8.45677C6.12459 8.36995 5.72368 8.15566 5.40901 7.84099C5.09434 7.52632 4.88005 7.12541 4.79323 6.68895C4.70642 6.2525 4.75097 5.8001 4.92127 5.38896C5.09157 4.97783 5.37996 4.62643 5.74997 4.37919C6.11998 4.13196 6.55499 4 7 4C7.59653 4.00067 8.16844 4.23794 8.59025 4.65975C9.01206 5.08156 9.24933 5.65347 9.25 6.25Z" fill="white"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M26 7H22.5344L20.8313 4.44531C20.74 4.30833 20.6163 4.19601 20.4711 4.11833C20.326 4.04064 20.1639 4 19.9993 4H11.9993C11.8346 4 11.6726 4.04064 11.5274 4.11833C11.3823 4.19601 11.2585 4.30833 11.1672 4.44531L9.46411 7H6C5.20463 7.00091 4.4421 7.31727 3.87968 7.87968C3.31727 8.4421 3.00091 9.20463 3 10V24C3.00091 24.7954 3.31727 25.5579 3.87968 26.1203C4.4421 26.6827 5.20463 26.9991 6 27H26C26.7954 26.9991 27.5579 26.6827 28.1203 26.1203C28.6827 25.5579 28.9991 24.7954 29 24V10C28.9991 9.20463 28.6827 8.4421 28.1203 7.87968C27.5579 7.31727 26.7954 7.00091 26 7ZM20.5 16.5C20.5 17.39 20.2361 18.26 19.7416 19.0001C19.2471 19.7401 18.5443 20.3169 17.7221 20.6575C16.8998 20.9981 15.995 21.0872 15.1221 20.9135C14.2492 20.7399 13.4474 20.3113 12.818 19.682C12.1887 19.0526 11.7601 18.2508 11.5865 17.3779C11.4128 16.505 11.5019 15.6002 11.8425 14.7779C12.1831 13.9557 12.7599 13.2529 13.4999 12.7584C14.24 12.2639 15.11 12 16 12C17.1931 12.0013 18.3369 12.4759 19.1805 13.3195C20.0241 14.1631 20.4987 15.3069 20.5 16.5Z" fill="black"/> | |||
| </svg> | |||
| @@ -0,0 +1,9 @@ | |||
| <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M3.93311 3.30806L17.317 16.6919C17.3751 16.634 17.4212 16.5651 17.4526 16.4892C17.484 16.4134 17.5002 16.3321 17.5 16.25V3.75C17.5 3.58424 17.4342 3.42527 17.317 3.30806C17.1998 3.19085 17.0408 3.125 16.875 3.125H4.37505C4.29295 3.12489 4.21165 3.14101 4.13581 3.17243C4.05996 3.20384 3.99108 3.24994 3.93311 3.30806L3.93311 3.30806Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M8.75 16.875C8.75 16.5298 9.02982 16.25 9.375 16.25H11.875C12.2202 16.25 12.5 16.5298 12.5 16.875C12.5 17.2202 12.2202 17.5 11.875 17.5H9.375C9.02982 17.5 8.75 17.2202 8.75 16.875Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M3.75 8.125C4.09518 8.125 4.375 8.40482 4.375 8.75V11.25C4.375 11.5952 4.09518 11.875 3.75 11.875C3.40482 11.875 3.125 11.5952 3.125 11.25V8.75C3.125 8.40482 3.40482 8.125 3.75 8.125Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M3.75 13.75C4.09518 13.75 4.375 14.0298 4.375 14.375V16.25H6.25C6.59518 16.25 6.875 16.5299 6.875 16.875C6.875 17.2202 6.59518 17.5 6.25 17.5H4.375C4.04348 17.5 3.72554 17.3683 3.49112 17.1339C3.2567 16.8995 3.125 16.5815 3.125 16.25V14.375C3.125 14.0298 3.40482 13.75 3.75 13.75Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M3.49112 2.86612C3.72554 2.6317 4.04348 2.5 4.375 2.5H16.875C17.2065 2.5 17.5245 2.6317 17.7589 2.86612C17.9933 3.10054 18.125 3.41848 18.125 3.75V16.25C18.125 16.5815 17.9933 16.8995 17.7589 17.1339C17.5245 17.3683 17.2065 17.5 16.875 17.5H15C14.6548 17.5 14.375 17.2202 14.375 16.875C14.375 16.5298 14.6548 16.25 15 16.25H16.875V3.75L4.375 3.75L4.375 5.62497C4.375 5.97015 4.09518 6.24997 3.75 6.24997C3.40482 6.24997 3.125 5.97015 3.125 5.62497V3.75C3.125 3.41848 3.2567 3.10054 3.49112 2.86612Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M3.49116 2.86568C3.73524 2.6216 4.13097 2.6216 4.37505 2.86568L17.7589 16.2496C18.003 16.4936 18.003 16.8894 17.7589 17.1334C17.5148 17.3775 17.1191 17.3775 16.875 17.1334L3.49116 3.74956C3.24709 3.50548 3.24709 3.10975 3.49116 2.86568Z" fill="#60BA69"/> | |||
| </svg> | |||
| @@ -0,0 +1,10 @@ | |||
| <svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <g clip-path="url(#clip0_26_1517)"> | |||
| <rect x="0.5" y="0.976562" width="15" height="15" rx="3.5" fill="white" stroke="#C9CED9"/> | |||
| </g> | |||
| <defs> | |||
| <clipPath id="clip0_26_1517"> | |||
| <rect y="0.476562" width="16" height="16" rx="2" fill="white"/> | |||
| </clipPath> | |||
| </defs> | |||
| </svg> | |||
| @@ -0,0 +1,12 @@ | |||
| <svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <rect y="0.476562" width="16" height="16" rx="4" fill="white"/> | |||
| <g clip-path="url(#clip0_26_2080)"> | |||
| <rect y="0.476562" width="16" height="16" rx="2" fill="#2E96FF"/> | |||
| <path d="M6.60533 12.6983L6.58771 12.7159L3.18787 9.31608L4.62054 7.88341L6.60539 9.86825L11.3794 5.09424L12.8121 6.52691L6.62301 12.716L6.60533 12.6983Z" fill="white"/> | |||
| </g> | |||
| <defs> | |||
| <clipPath id="clip0_26_2080"> | |||
| <rect y="0.476562" width="16" height="16" rx="4" fill="white"/> | |||
| </clipPath> | |||
| </defs> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M10 1.875C8.39303 1.875 6.82214 2.35152 5.486 3.24431C4.14985 4.1371 3.10844 5.40605 2.49348 6.8907C1.87852 8.37535 1.71762 10.009 2.03112 11.5851C2.34463 13.1612 3.11846 14.6089 4.25476 15.7452C5.39106 16.8815 6.8388 17.6554 8.4149 17.9689C9.99099 18.2824 11.6247 18.1215 13.1093 17.5065C14.594 16.8916 15.8629 15.8502 16.7557 14.514C17.6485 13.1779 18.125 11.607 18.125 10C18.1225 7.84588 17.2657 5.7807 15.7425 4.25751C14.2193 2.73431 12.1541 1.87749 10 1.875ZM12.9419 12.0581C13 12.1161 13.0462 12.185 13.0776 12.2609C13.1091 12.3367 13.1254 12.418 13.1254 12.5001C13.1255 12.5823 13.1093 12.6636 13.0779 12.7395C13.0465 12.8153 13.0004 12.8843 12.9424 12.9424C12.8843 13.0004 12.8154 13.0465 12.7395 13.0779C12.6636 13.1093 12.5823 13.1254 12.5001 13.1254C12.418 13.1254 12.3367 13.1091 12.2609 13.0776C12.185 13.0462 12.1161 13 12.0581 12.9419L10 10.8838L7.9419 12.9419C7.82466 13.0589 7.66577 13.1246 7.50014 13.1245C7.33451 13.1244 7.1757 13.0585 7.05858 12.9414C6.94146 12.8243 6.87563 12.6655 6.87554 12.4999C6.87545 12.3342 6.94112 12.1753 7.05811 12.0581L9.11621 10L7.05811 7.94189C6.94112 7.82465 6.87545 7.66576 6.87554 7.50014C6.87563 7.33451 6.94146 7.17569 7.05858 7.05858C7.1757 6.94146 7.33451 6.87563 7.50014 6.87554C7.66577 6.87545 7.82466 6.94111 7.9419 7.05811L10 9.11621L12.0581 7.05811C12.1754 6.94111 12.3342 6.87545 12.4999 6.87554C12.6655 6.87563 12.8243 6.94146 12.9414 7.05858C13.0585 7.17569 13.1244 7.33451 13.1245 7.50014C13.1246 7.66576 13.0589 7.82465 12.9419 7.94189L10.8838 10L12.9419 12.0581Z" fill="#F65555"/> | |||
| </svg> | |||
| @@ -0,0 +1,8 @@ | |||
| <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M20.0001 5C20.6506 5.86473 21.0016 6.91789 21 8V9H11V8C10.9984 6.91789 11.3494 5.86473 11.9999 5H7C6.86868 5 6.73864 5.02586 6.61731 5.07611C6.49598 5.12637 6.38574 5.20003 6.29288 5.29288C6.20003 5.38574 6.12637 5.49598 6.07611 5.61731C6.02586 5.73864 6 5.86868 6 6V27C6 27.1313 6.02586 27.2614 6.07611 27.3827C6.12637 27.504 6.20003 27.6143 6.29288 27.7071C6.38574 27.8 6.49598 27.8736 6.61731 27.9239C6.73864 27.9741 6.86868 28 7 28H25C25.1313 28 25.2614 27.9741 25.3827 27.9239C25.504 27.8736 25.6143 27.8 25.7071 27.7071C25.8 27.6143 25.8736 27.504 25.9239 27.3827C25.9741 27.2614 26 27.1313 26 27V6C26 5.86868 25.9741 5.73864 25.9239 5.61731C25.8736 5.49598 25.8 5.38574 25.7071 5.29288C25.6143 5.20003 25.504 5.12637 25.3827 5.07611C25.2614 5.02586 25.1313 5 25 5H20.0001Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M11 19C11 18.4477 11.4477 18 12 18H20C20.5523 18 21 18.4477 21 19C21 19.5523 20.5523 20 20 20H12C11.4477 20 11 19.5523 11 19Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M11 15C11 14.4477 11.4477 14 12 14H20C20.5523 14 21 14.4477 21 15C21 15.5523 20.5523 16 20 16H12C11.4477 16 11 15.5523 11 15Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M5.58579 4.58579C5.96086 4.21071 6.46957 4 7 4H11.9997C12.552 4 12.9997 4.44772 12.9997 5C12.9997 5.55228 12.552 6 11.9997 6L7 6L7 27H25V6H20.0002C19.448 6 19.0002 5.55228 19.0002 5C19.0002 4.44772 19.448 4 20.0002 4H25C25.5304 4 26.0391 4.21071 26.4142 4.58579C26.7893 4.96086 27 5.46957 27 6V27C27 27.5304 26.7893 28.0391 26.4142 28.4142C26.0391 28.7893 25.5304 29 25 29H7C6.46957 29 5.96086 28.7893 5.58579 28.4142C5.21071 28.0391 5 27.5304 5 27V6C5 5.46957 5.21071 4.96086 5.58579 4.58579Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M16 4C14.9391 4 13.9217 4.42143 13.1716 5.17157C12.4214 5.92172 12 6.93913 12 8H20C20 6.93913 19.5786 5.92172 18.8284 5.17157C18.0783 4.42143 17.0609 4 16 4ZM11.7574 3.75736C12.8826 2.63214 14.4087 2 16 2C17.5913 2 19.1174 2.63214 20.2426 3.75736C21.3679 4.88258 22 6.4087 22 8V9C22 9.55228 21.5523 10 21 10H11C10.4477 10 10 9.55228 10 9V8C10 6.4087 10.6321 4.88258 11.7574 3.75736Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,6 @@ | |||
| <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M5.87498 15.0003C2.12498 8.75031 7.12498 2.50031 17.75 3.12531C18.375 13.7503 12.125 18.7503 5.87498 15.0003Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M13.8169 7.05806C14.061 7.30214 14.061 7.69786 13.8169 7.94194L4.44194 17.3169C4.19786 17.561 3.80214 17.561 3.55806 17.3169C3.31398 17.0729 3.31398 16.6771 3.55806 16.4331L12.9331 7.05806C13.1771 6.81398 13.5729 6.81398 13.8169 7.05806Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M6.33142 14.5438C9.19769 16.2027 11.9575 15.8647 13.9647 13.9959C15.9703 12.1287 17.3307 8.63166 17.1527 3.72246C12.2435 3.54455 8.74655 4.90491 6.87929 6.91048C5.01053 8.91768 4.67248 11.6775 6.33142 14.5438ZM5.96443 6.05871C8.24561 3.60855 12.3658 2.18242 17.7867 2.5013C18.103 2.51991 18.3553 2.77223 18.3739 3.08852C18.6928 8.50944 17.2667 12.6296 14.8165 14.9108C12.3239 17.2315 8.889 17.5375 5.55343 15.5362C5.46546 15.4834 5.39183 15.4097 5.33905 15.3218C3.33771 11.9862 3.64374 8.5513 5.96443 6.05871Z" fill="#60BA69"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <circle cx="5" cy="5" r="4.5" fill="#F65555" stroke="white"/> | |||
| </svg> | |||
| @@ -0,0 +1,6 @@ | |||
| <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M14.6718 9.04643L15.0536 9.42825C15.1697 9.54432 15.2618 9.68212 15.3246 9.83378C15.3874 9.98543 15.4198 10.148 15.4198 10.3121C15.4198 10.4763 15.3874 10.6388 15.3246 10.7905C15.2618 10.9421 15.1697 11.0799 15.0536 11.196L14.5045 11.7452C14.3873 11.8624 14.2283 11.9282 14.0625 11.9282C13.8968 11.9282 13.7378 11.8624 13.6206 11.7452L8.87947 7.00407C8.76226 6.88686 8.69641 6.72789 8.69641 6.56213C8.69641 6.39637 8.76226 6.2374 8.87947 6.12019L9.42864 5.57101C9.54472 5.45494 9.68252 5.36287 9.83417 5.30005C9.98583 5.23723 10.1484 5.2049 10.3125 5.2049C10.4767 5.2049 10.6392 5.23723 10.7909 5.30005C10.9425 5.36287 11.0803 5.45494 11.1964 5.57101L11.5782 5.95283L13.7336 3.79751C14.5764 2.95468 15.9496 2.90305 16.8153 3.72246C17.0278 3.92336 17.1978 4.16483 17.3154 4.43259C17.433 4.70035 17.4957 4.98897 17.4998 5.28139C17.5039 5.5738 17.4494 5.86407 17.3393 6.13503C17.2293 6.40599 17.0661 6.65214 16.8593 6.85893L14.6718 9.04643Z" fill="#60BA69"/> | |||
| <path d="M14.6718 9.04643L15.0536 9.42825C15.1697 9.54432 15.2618 9.68212 15.3246 9.83378C15.3874 9.98543 15.4198 10.148 15.4198 10.3121C15.4198 10.4763 15.3874 10.6388 15.3246 10.7905C15.2618 10.9421 15.1697 11.0799 15.0536 11.196L14.5045 11.7452C14.3873 11.8624 14.2283 11.9282 14.0625 11.9282C13.8968 11.9282 13.7378 11.8624 13.6206 11.7452L8.87947 7.00407C8.76226 6.88686 8.69641 6.72789 8.69641 6.56213C8.69641 6.39637 8.76226 6.2374 8.87947 6.12019L9.42864 5.57101C9.54472 5.45494 9.68252 5.36287 9.83417 5.30005C9.98583 5.23723 10.1484 5.2049 10.3125 5.2049C10.4767 5.2049 10.6392 5.23723 10.7909 5.30005C10.9425 5.36287 11.0803 5.45494 11.1964 5.57101L11.5782 5.95283L13.7336 3.79751C14.5764 2.95468 15.9496 2.90305 16.8153 3.72246C17.0278 3.92336 17.1978 4.16483 17.3154 4.43259C17.433 4.70035 17.4957 4.98897 17.4998 5.28139C17.5039 5.5738 17.4494 5.86407 17.3393 6.13503C17.2293 6.40599 17.0661 6.65214 16.8593 6.85893L14.6718 9.04643Z" stroke="#60BA69" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M13.0177 11.143L8.64275 15.518C8.33252 15.8284 7.946 16.0517 7.52206 16.1654C7.09812 16.2791 6.65172 16.2791 6.22778 16.1654L4.39948 16.9635C4.28435 17.0138 4.15674 17.0282 4.0333 17.0049C3.90985 16.9815 3.79631 16.9215 3.70748 16.8327V16.8327C3.6437 16.7689 3.60062 16.6874 3.58386 16.5988C3.5671 16.5101 3.57744 16.4185 3.61353 16.3359L4.45978 14.3974C4.34612 13.9735 4.34611 13.5271 4.45976 13.1031C4.57342 12.6792 4.79673 12.2926 5.10721 11.9824L9.48221 7.60742" stroke="#60BA69" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/> | |||
| </svg> | |||
| @@ -0,0 +1,6 @@ | |||
| <svg width="41" height="40" viewBox="0 0 41 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <rect x="0.75" width="40" height="40" rx="20" fill="#EAF6EB"/> | |||
| <path opacity="0.2" d="M25.606 18.8561L26.0642 19.3143C26.2035 19.4536 26.314 19.619 26.3894 19.8009C26.4648 19.9829 26.5036 20.178 26.5036 20.375C26.5036 20.572 26.4648 20.767 26.3894 20.949C26.314 21.131 26.2035 21.2963 26.0642 21.4356L25.4052 22.0946C25.2646 22.2353 25.0738 22.3143 24.8749 22.3143C24.676 22.3143 24.4852 22.2353 24.3446 22.0946L18.6552 16.4053C18.5146 16.2646 18.4355 16.0739 18.4355 15.875C18.4355 15.6761 18.5146 15.4853 18.6552 15.3446L19.3142 14.6856C19.4535 14.5463 19.6189 14.4359 19.8009 14.3605C19.9828 14.2851 20.1779 14.2463 20.3749 14.2463C20.5719 14.2463 20.7669 14.2851 20.9489 14.3605C21.1309 14.4359 21.2963 14.5463 21.4355 14.6856L21.8937 15.1438L24.4801 12.5574C25.4915 11.546 27.1394 11.4841 28.1782 12.4674C28.4332 12.7084 28.6373 12.9982 28.7784 13.3195C28.9195 13.6408 28.9947 13.9872 28.9996 14.3381C29.0046 14.689 28.9391 15.0373 28.8071 15.3624C28.6751 15.6876 28.4792 15.983 28.231 16.2311L25.606 18.8561Z" fill="#60BA69"/> | |||
| <path d="M25.606 18.8561L26.0642 19.3143C26.2035 19.4536 26.314 19.619 26.3894 19.8009C26.4648 19.9829 26.5036 20.178 26.5036 20.375C26.5036 20.572 26.4648 20.767 26.3894 20.949C26.314 21.131 26.2035 21.2963 26.0642 21.4356L25.4052 22.0946C25.2646 22.2353 25.0738 22.3143 24.8749 22.3143C24.676 22.3143 24.4852 22.2353 24.3446 22.0946L18.6552 16.4053C18.5146 16.2646 18.4355 16.0739 18.4355 15.875C18.4355 15.6761 18.5146 15.4853 18.6552 15.3446L19.3142 14.6856C19.4535 14.5463 19.6189 14.4359 19.8009 14.3605C19.9828 14.2851 20.1779 14.2463 20.3749 14.2463C20.5719 14.2463 20.7669 14.2851 20.9489 14.3605C21.1309 14.4359 21.2963 14.5463 21.4355 14.6856L21.8937 15.1438L24.4801 12.5574C25.4915 11.546 27.1394 11.4841 28.1782 12.4674C28.4332 12.7084 28.6373 12.9982 28.7784 13.3195C28.9195 13.6408 28.9947 13.9872 28.9996 14.3381C29.0046 14.689 28.9391 15.0373 28.8071 15.3624C28.6751 15.6876 28.4792 15.983 28.231 16.2311L25.606 18.8561Z" stroke="#60BA69" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M23.6215 21.3713L18.3715 26.6213C17.9993 26.9939 17.5354 27.2619 17.0267 27.3982C16.518 27.5346 15.9823 27.5346 15.4736 27.3982L13.2796 28.356C13.1415 28.4163 12.9883 28.4336 12.8402 28.4056C12.6921 28.3776 12.5558 28.3056 12.4492 28.199V28.199C12.3727 28.1224 12.321 28.0246 12.3009 27.9183C12.2808 27.8119 12.2932 27.702 12.3365 27.6028L13.352 25.2766C13.2156 24.7679 13.2156 24.2322 13.352 23.7235C13.4883 23.2148 13.7563 22.7509 14.1289 22.3787L19.3789 17.1287" stroke="#60BA69" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/> | |||
| </svg> | |||
| @@ -0,0 +1,4 @@ | |||
| <svg width="18" height="17" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.28809 0.8125H15.7124C16.0151 0.8125 16.3113 0.900427 16.565 1.06559C16.8186 1.23076 17.0189 1.46606 17.1413 1.74289C17.2638 2.01971 17.3032 2.32615 17.2548 2.62496C17.2064 2.92376 17.0722 3.20207 16.8686 3.42605L11.8127 8.98744V13.2905C11.8127 13.5477 11.7492 13.801 11.6279 14.0278C11.5065 14.2546 11.331 14.4479 11.117 14.5906L8.61696 16.2573C8.38165 16.4141 8.10817 16.5042 7.82569 16.5179C7.5432 16.5315 7.26231 16.4682 7.01296 16.3348C6.76362 16.2013 6.55516 16.0027 6.40983 15.7601C6.2645 15.5175 6.18774 15.24 6.18774 14.9572V8.98744L1.13193 3.42605C0.92831 3.20207 0.794134 2.92376 0.745709 2.62496C0.697285 2.32615 0.736699 2.01971 0.859158 1.74289C0.981618 1.46606 1.18185 1.23076 1.43552 1.06559C1.6892 0.900427 1.98538 0.8125 2.28809 0.8125ZM2.99451 2.6875L7.6564 7.81558C7.91786 8.10319 8.06274 8.47793 8.06274 8.86663V14.3733L9.93774 13.1233V8.86663C9.93774 8.47793 10.0826 8.10319 10.3441 7.81558L15.006 2.6875H2.99451Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,5 @@ | |||
| <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M20.8795 10.2768L13.379 3.45793C13.2409 3.33242 13.061 3.26287 12.8745 3.26288C12.6879 3.26288 12.508 3.33244 12.3699 3.45797L4.87045 10.2769C4.79314 10.3471 4.73137 10.4328 4.6891 10.5284C4.64683 10.6239 4.625 10.7273 4.625 10.8318V19.5C4.625 19.6989 4.70402 19.8897 4.84467 20.0304C4.98532 20.171 5.17609 20.25 5.375 20.25H20.375C20.5739 20.25 20.7647 20.171 20.9053 20.0304C21.046 19.8897 21.125 19.6989 21.125 19.5V10.8318C21.125 10.7273 21.1032 10.624 21.0609 10.5284C21.0186 10.4328 20.9568 10.3471 20.8795 10.2768Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M11.8654 2.90306C12.1415 2.65201 12.5013 2.51289 12.8744 2.51288C13.2476 2.51287 13.6074 2.65196 13.8835 2.90299L21.384 9.7219C21.5387 9.86249 21.6622 10.0338 21.7468 10.225C21.8313 10.4161 21.875 10.6228 21.875 10.8318V19.5C21.875 19.8978 21.717 20.2794 21.4357 20.5607C21.1544 20.842 20.7728 21 20.375 21H5.375C4.97718 21 4.59565 20.842 4.31434 20.5607C4.03304 20.2794 3.875 19.8978 3.875 19.5V10.8318C3.875 10.6228 3.91867 10.4161 4.0032 10.225C4.08774 10.0339 4.21128 9.86253 4.3659 9.72194L11.8654 2.90306ZM20.375 10.8318L12.8745 4.01288L5.375 10.8318V19.5H20.375V10.8318Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,5 @@ | |||
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M11.0601 4.94004L4.2068 11.7934C3.8868 12.1134 3.34013 12.04 3.1468 11.6334C2.80013 10.92 2.60013 10.1134 2.60013 9.26671C2.5868 5.58671 6.32013 2.44004 7.5868 1.47337C7.83347 1.28671 8.1668 1.28671 8.4068 1.47337C8.9868 1.91337 10.0735 2.82671 11.0935 4.02671C11.3201 4.29337 11.3068 4.69337 11.0601 4.94004Z" fill="white"/> | |||
| <path opacity="0.4" d="M13.4001 9.27339C13.4001 12.2467 10.9801 14.6667 8.00014 14.6667C6.80681 14.6667 5.69347 14.2801 4.79347 13.6134C4.46681 13.3734 4.44014 12.8934 4.72681 12.6067L11.4401 5.89339C11.7535 5.58005 12.2801 5.64672 12.4935 6.03339C13.0401 7.04005 13.4068 8.13339 13.4001 9.27339Z" fill="white"/> | |||
| </svg> | |||
| @@ -0,0 +1,7 @@ | |||
| <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M8.87476 6.75V20.25H4.37549C4.17658 20.25 3.98581 20.171 3.84516 20.0303C3.70451 19.8897 3.62549 19.6989 3.62549 19.5V7.5C3.62549 7.30109 3.70451 7.11032 3.84516 6.96967C3.98581 6.82902 4.17658 6.75 4.37549 6.75H8.87476Z" fill="#6E7987"/> | |||
| <path opacity="0.2" d="M16.376 6.75V20.25H20.8752C21.0742 20.25 21.2649 20.171 21.4056 20.0303C21.5462 19.8897 21.6252 19.6989 21.6252 19.5V7.5C21.6252 7.30109 21.5462 7.11032 21.4056 6.96967C21.2649 6.82902 21.0742 6.75 20.8752 6.75H16.376Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.875 7.5C2.875 6.67157 3.54657 6 4.375 6H20.875C21.7034 6 22.375 6.67157 22.375 7.5V19.5C22.375 20.3284 21.7034 21 20.875 21H4.375C3.54657 21 2.875 20.3284 2.875 19.5V7.5ZM20.875 7.5H4.375V19.5H20.875V7.5Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M8.78401 3.65901C9.20597 3.23705 9.77826 3 10.375 3H14.875C15.4717 3 16.044 3.23705 16.466 3.65901C16.8879 4.08097 17.125 4.65326 17.125 5.25V20.25C17.125 20.6642 16.7892 21 16.375 21C15.9608 21 15.625 20.6642 15.625 20.25V5.25C15.625 5.05109 15.546 4.86032 15.4053 4.71967C15.2647 4.57902 15.0739 4.5 14.875 4.5H10.375C10.1761 4.5 9.98532 4.57902 9.84467 4.71967C9.70402 4.86032 9.625 5.05109 9.625 5.25V20.25C9.625 20.6642 9.28921 21 8.875 21C8.46079 21 8.125 20.6642 8.125 20.25V5.25C8.125 4.65326 8.36205 4.08097 8.78401 3.65901Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,8 @@ | |||
| <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M10.125 17.5C14.2671 17.5 17.625 14.1421 17.625 10C17.625 5.85786 14.2671 2.5 10.125 2.5C5.98286 2.5 2.625 5.85786 2.625 10C2.625 14.1421 5.98286 17.5 10.125 17.5Z" fill="white"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M10.125 3.125C6.32804 3.125 3.25 6.20304 3.25 10C3.25 13.797 6.32804 16.875 10.125 16.875C13.922 16.875 17 13.797 17 10C17 6.20304 13.922 3.125 10.125 3.125ZM2 10C2 5.51269 5.63769 1.875 10.125 1.875C14.6123 1.875 18.25 5.51269 18.25 10C18.25 14.4873 14.6123 18.125 10.125 18.125C5.63769 18.125 2 14.4873 2 10Z" fill="white"/> | |||
| <path d="M13.875 10.9375C14.3928 10.9375 14.8125 10.5178 14.8125 10C14.8125 9.48223 14.3928 9.0625 13.875 9.0625C13.3572 9.0625 12.9375 9.48223 12.9375 10C12.9375 10.5178 13.3572 10.9375 13.875 10.9375Z" fill="white"/> | |||
| <path d="M10.125 10.9375C10.6428 10.9375 11.0625 10.5178 11.0625 10C11.0625 9.48223 10.6428 9.0625 10.125 9.0625C9.60723 9.0625 9.1875 9.48223 9.1875 10C9.1875 10.5178 9.60723 10.9375 10.125 10.9375Z" fill="white"/> | |||
| <path d="M6.375 10.9375C6.89277 10.9375 7.3125 10.5178 7.3125 10C7.3125 9.48223 6.89277 9.0625 6.375 9.0625C5.85723 9.0625 5.4375 9.48223 5.4375 10C5.4375 10.5178 5.85723 10.9375 6.375 10.9375Z" fill="white"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M17.5 5.99118L14.0089 2.50005C13.8928 2.38397 13.755 2.29189 13.6034 2.22907C13.4517 2.16624 13.2892 2.13391 13.125 2.13391C12.9609 2.13391 12.7983 2.16624 12.6467 2.22907C12.495 2.29189 12.3572 2.38397 12.2411 2.50005L10.1832 4.558L10.1831 4.55811L10.183 4.55823L2.86618 11.875C2.74972 11.9908 2.6574 12.1286 2.59454 12.2803C2.53169 12.432 2.49956 12.5947 2.5 12.7589V16.25C2.50038 16.5815 2.6322 16.8992 2.86654 17.1335C3.10088 17.3678 3.4186 17.4997 3.75 17.5H7.24114C7.40536 17.5005 7.56803 17.4684 7.71975 17.4055C7.87146 17.3427 8.00921 17.2504 8.125 17.1339L17.5 7.75891C17.7341 7.5243 17.8655 7.20643 17.8655 6.87504C17.8655 6.54364 17.7341 6.22578 17.5 5.99118ZM15 8.49118L11.5089 5.00005L13.125 3.38391L16.6161 6.87505L15 8.49118Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M19.749 7.25H18.749V4.25C18.749 4.05109 18.67 3.86032 18.5294 3.71967C18.3887 3.57902 18.1979 3.5 17.999 3.5H5.99902C5.80011 3.5 5.60935 3.57902 5.4687 3.71967C5.32804 3.86032 5.24903 4.05109 5.24902 4.25V7.25H4.24904C2.93947 7.25 1.87402 8.25937 1.87402 9.5V17C1.87403 17.1989 1.95304 17.3897 2.0937 17.5303C2.23435 17.671 2.42511 17.75 2.62402 17.75H5.24902V21.125C5.24903 21.3239 5.32804 21.5147 5.4687 21.6553C5.60935 21.796 5.80011 21.875 5.99902 21.875H17.999C18.1979 21.875 18.3887 21.796 18.5294 21.6553C18.67 21.5147 18.749 21.3239 18.749 21.125V17.75H21.374C21.5729 17.75 21.7637 17.671 21.9044 17.5303C22.045 17.3897 22.124 17.1989 22.124 17V9.5C22.124 8.25937 21.0586 7.25 19.749 7.25ZM6.74902 5H17.249V7.25H6.74902V5ZM17.249 20.375H6.74902V15.5H17.249V20.375ZM17.624 12.5C17.4015 12.5 17.184 12.434 16.999 12.3104C16.814 12.1868 16.6698 12.0111 16.5847 11.8055C16.4995 11.6 16.4772 11.3738 16.5206 11.1555C16.564 10.9373 16.6712 10.7368 16.8285 10.5795C16.9859 10.4222 17.1863 10.315 17.4045 10.2716C17.6228 10.2282 17.849 10.2505 18.0545 10.3356C18.2601 10.4208 18.4358 10.565 18.5594 10.75C18.683 10.935 18.749 11.1525 18.749 11.375C18.749 11.5227 18.7199 11.669 18.6634 11.8055C18.6069 11.942 18.524 12.066 18.4195 12.1705C18.3151 12.275 18.191 12.3578 18.0545 12.4144C17.9181 12.4709 17.7718 12.5 17.624 12.5Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,7 @@ | |||
| <svg width="81" height="80" viewBox="0 0 81 80" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M40.501 70C57.0695 70 70.501 56.5685 70.501 40C70.501 23.4315 57.0695 10 40.501 10C23.9324 10 10.501 23.4315 10.501 40C10.501 56.5685 23.9324 70 40.501 70Z" fill="#F7893A"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M40.501 12.5C25.3131 12.5 13.001 24.8122 13.001 40C13.001 55.1878 25.3131 67.5 40.501 67.5C55.6888 67.5 68.001 55.1878 68.001 40C68.001 24.8122 55.6888 12.5 40.501 12.5ZM8.00098 40C8.00098 22.0507 22.5517 7.5 40.501 7.5C58.4502 7.5 73.001 22.0507 73.001 40C73.001 57.9493 58.4502 72.5 40.501 72.5C22.5517 72.5 8.00098 57.9493 8.00098 40Z" fill="#F7893A"/> | |||
| <path d="M40.501 60C42.572 60 44.251 58.3211 44.251 56.25C44.251 54.1789 42.572 52.5 40.501 52.5C38.4299 52.5 36.751 54.1789 36.751 56.25C36.751 58.3211 38.4299 60 40.501 60Z" fill="#F7893A"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M36.1958 23.3577C38.2515 22.5062 40.5135 22.2834 42.6957 22.7175C44.878 23.1516 46.8826 24.2231 48.4559 25.7964C50.0293 27.3697 51.1007 29.3743 51.5348 31.5566C51.9689 33.7389 51.7461 36.0009 50.8946 38.0565C50.0431 40.1122 48.6012 41.8692 46.7511 43.1054C45.6042 43.8718 44.3323 44.4166 43.001 44.7201V45.0013C43.001 46.3821 41.8817 47.5013 40.501 47.5013C39.1203 47.5013 38.001 46.3821 38.001 45.0013V42.5013C38.001 41.8383 38.2644 41.2024 38.7332 40.7336C39.2021 40.2647 39.8379 40.0013 40.501 40.0013C41.7371 40.0013 42.9455 39.6348 43.9733 38.948C45.0011 38.2613 45.8022 37.2852 46.2752 36.1431C46.7483 35.0011 46.872 33.7444 46.6309 32.532C46.3897 31.3197 45.7945 30.206 44.9204 29.3319C44.0463 28.4579 42.9327 27.8626 41.7203 27.6214C40.5079 27.3803 39.2512 27.5041 38.1092 27.9771C36.9672 28.4501 35.991 29.2512 35.3043 30.279C34.6175 31.3068 34.251 32.5152 34.251 33.7513C34.251 35.1321 33.1317 36.2513 31.751 36.2513C30.3703 36.2513 29.251 35.1321 29.251 33.7513C29.251 31.5263 29.9108 29.3512 31.1469 27.5012C32.3831 25.6511 34.1401 24.2092 36.1958 23.3577Z" fill="#F7893A"/> | |||
| </svg> | |||
| @@ -0,0 +1,8 @@ | |||
| <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M3.25005 13.6449C2.86039 11.5361 3.2353 9.35748 4.30747 7.50024C5.37963 5.643 7.07881 4.22884 9.09985 3.51172V10.2675L3.25005 13.6449Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M12.1 2.25C12.5142 2.25 12.85 2.58579 12.85 3V12C12.85 12.4142 12.5142 12.75 12.1 12.75C11.6858 12.75 11.35 12.4142 11.35 12V3C11.35 2.58579 11.6858 2.25 12.1 2.25Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M20.5438 7.12513C20.7509 7.48384 20.628 7.94254 20.2692 8.14964L4.68079 17.1496C4.32207 17.3568 3.86338 17.2338 3.65627 16.8751C3.44916 16.5164 3.57207 16.0577 3.93079 15.8506L19.5192 6.85061C19.878 6.6435 20.3367 6.76641 20.5438 7.12513Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M9.53252 2.89911C9.73152 3.03965 9.84985 3.2681 9.84985 3.51172V10.2675C9.84985 10.5355 9.7069 10.7831 9.47485 10.9171L3.62506 14.2944C3.41408 14.4162 3.15709 14.428 2.93588 14.3259C2.71467 14.2239 2.55681 14.0208 2.51254 13.7812C2.09045 11.4969 2.49656 9.13704 3.65793 7.12527C4.8193 5.1135 6.65986 3.58169 8.84906 2.8049C9.07866 2.72343 9.33352 2.75856 9.53252 2.89911ZM8.34985 4.64988C6.93853 5.37199 5.75726 6.48898 4.957 7.87521C4.15672 9.26148 3.78016 10.8431 3.86063 12.4264L8.34985 9.83453V4.64988Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M11.3499 2.99986C11.35 2.58565 11.6859 2.24992 12.1001 2.25C13.8083 2.25032 15.4864 2.69942 16.9665 3.55234C18.4465 4.40526 19.6765 5.63206 20.5333 7.10989C21.39 8.58772 21.8435 10.2647 21.8482 11.9729C21.853 13.6811 21.4088 15.3606 20.5603 16.8432C19.7118 18.3257 18.4886 19.5594 17.0133 20.4205C15.5381 21.2816 13.8624 21.74 12.1542 21.7498C10.446 21.7596 8.76526 21.3205 7.28018 20.4764C5.79511 19.6322 4.55788 18.4127 3.69238 16.94C3.48251 16.5829 3.60188 16.1233 3.95899 15.9134C4.3161 15.7035 4.77573 15.8229 4.98559 16.18C5.71794 17.4262 6.76483 18.458 8.02143 19.1723C9.27803 19.8866 10.7002 20.2582 12.1456 20.2499C13.591 20.2416 15.0089 19.8537 16.2572 19.125C17.5055 18.3964 18.5405 17.3525 19.2585 16.0981C19.9764 14.8436 20.3522 13.4225 20.3482 11.9771C20.3442 10.5317 19.9605 9.11269 19.2356 7.86222C18.5106 6.61175 17.4699 5.57368 16.2175 4.85198C14.9652 4.13028 13.5452 3.75027 12.0998 3.75C11.6856 3.74992 11.3499 3.41407 11.3499 2.99986Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,5 @@ | |||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M9.0625 3.4375C5.9559 3.4375 3.4375 5.9559 3.4375 9.0625C3.4375 12.1691 5.9559 14.6875 9.0625 14.6875C12.1691 14.6875 14.6875 12.1691 14.6875 9.0625C14.6875 5.9559 12.1691 3.4375 9.0625 3.4375ZM1.5625 9.0625C1.5625 4.92036 4.92036 1.5625 9.0625 1.5625C13.2046 1.5625 16.5625 4.92036 16.5625 9.0625C16.5625 13.2046 13.2046 16.5625 9.0625 16.5625C4.92036 16.5625 1.5625 13.2046 1.5625 9.0625Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M13.0392 13.0402C13.4054 12.6741 13.9989 12.6741 14.3651 13.0402L18.162 16.8371C18.5281 17.2032 18.5281 17.7968 18.162 18.163C17.7959 18.5291 17.2023 18.5291 16.8362 18.163L13.0392 14.366C12.6731 13.9999 12.6731 13.4063 13.0392 13.0402Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,4 @@ | |||
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M13.9835 2.01642C13.8577 1.89079 13.7008 1.80092 13.5288 1.75604C13.3568 1.71117 13.176 1.71292 13.0049 1.76111L1.3594 5.04572C1.16346 5.10098 0.989054 5.21473 0.859493 5.37177C0.729932 5.52881 0.651389 5.72165 0.634363 5.92452C0.617337 6.12739 0.662639 6.33063 0.764213 6.50706C0.865788 6.6835 1.0188 6.82473 1.20279 6.91187L6.07363 9.21912L9.40377 5.88898C9.49755 5.79521 9.62473 5.74253 9.75735 5.74253C9.88997 5.74253 10.0172 5.79521 10.1109 5.88898C10.2047 5.98276 10.2574 6.10994 10.2574 6.24256C10.2574 6.37518 10.2047 6.50236 10.1109 6.59614L6.78079 9.92628L9.08804 14.7971C9.16796 14.9685 9.29525 15.1134 9.45488 15.2148C9.61452 15.3161 9.79982 15.3697 9.98892 15.3691C10.0175 15.3691 10.0464 15.3679 10.0754 15.3655C10.2786 15.3496 10.472 15.2715 10.6293 15.1418C10.7865 15.012 10.9 14.837 10.9542 14.6405L14.2388 2.995C14.2869 2.82391 14.2887 2.64308 14.2438 2.4711C14.1989 2.29912 14.1091 2.14219 13.9835 2.01642Z" fill="white"/> | |||
| </svg> | |||
| @@ -0,0 +1,6 @@ | |||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M5 17H13" stroke="#6E7987" stroke-width="2" stroke-linecap="round"/> | |||
| <path d="M5 12H11" stroke="#6E7987" stroke-width="2" stroke-linecap="round"/> | |||
| <path d="M5 7H9" stroke="#6E7987" stroke-width="2" stroke-linecap="round"/> | |||
| <path d="M19 6L22 9M19 6L16 9M19 6L19 18" stroke="#6E7987" stroke-width="2"/> | |||
| </svg> | |||
| @@ -0,0 +1,5 @@ | |||
| <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.4" d="M27.4802 14.4399C26.4535 13.2133 25.1335 12.4133 23.6002 12.0666C23.2535 10.5199 22.6535 9.18662 21.7735 8.07995C21.7468 8.03995 21.7202 7.99995 21.6935 7.97328C18.7602 4.42662 13.9602 4.43995 10.7202 6.27995C7.94684 7.86662 5.58684 11.2133 6.82684 15.9866C3.98684 16.6799 2.68018 19.1599 2.68018 21.3999C2.68018 23.9066 4.32018 26.7199 7.97351 26.9866H21.7602C21.7735 26.9866 21.8002 26.9866 21.8135 26.9866C23.7068 26.9866 25.5202 26.2799 26.9202 25C30.2668 22.0399 29.8268 17.2133 27.4802 14.4399Z" fill="white"/> | |||
| <path d="M29.0131 11.6534C29.0131 12.8534 28.5865 14.0001 27.8131 14.8801C27.7198 14.7334 27.5998 14.5867 27.4798 14.4401C26.4665 13.2267 25.1331 12.4001 23.5998 12.0667C23.2665 10.5201 22.6531 9.20005 21.7731 8.09339C21.7598 8.05339 21.7198 8.01339 21.6931 7.98672C21.5598 7.82672 21.4131 7.68005 21.2798 7.53339C22.0931 6.97339 23.0265 6.68005 24.0398 6.68005C26.7865 6.68005 29.0131 8.90672 29.0131 11.6534Z" fill="white"/> | |||
| </svg> | |||
| @@ -0,0 +1,15 @@ | |||
| <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M16.625 3.125H14.125C13.7798 3.125 13.5 3.40482 13.5 3.75V6.25C13.5 6.59518 13.7798 6.875 14.125 6.875H16.625C16.9702 6.875 17.25 6.59518 17.25 6.25V3.75C17.25 3.40482 16.9702 3.125 16.625 3.125Z" fill="#60BA69"/> | |||
| <path opacity="0.2" d="M6.625 3.125H4.125C3.77982 3.125 3.5 3.40482 3.5 3.75V6.25C3.5 6.59518 3.77982 6.875 4.125 6.875H6.625C6.97018 6.875 7.25 6.59518 7.25 6.25V3.75C7.25 3.40482 6.97018 3.125 6.625 3.125Z" fill="#60BA69"/> | |||
| <path opacity="0.2" d="M16.625 13.125H14.125C13.7798 13.125 13.5 13.4048 13.5 13.75V16.25C13.5 16.5952 13.7798 16.875 14.125 16.875H16.625C16.9702 16.875 17.25 16.5952 17.25 16.25V13.75C17.25 13.4048 16.9702 13.125 16.625 13.125Z" fill="#60BA69"/> | |||
| <path opacity="0.2" d="M6.625 13.125H4.125C3.77982 13.125 3.5 13.4048 3.5 13.75V16.25C3.5 16.5952 3.77982 16.875 4.125 16.875H6.625C6.97018 16.875 7.25 16.5952 7.25 16.25V13.75C7.25 13.4048 6.97018 13.125 6.625 13.125Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M12.875 3.75C12.875 3.05964 13.4346 2.5 14.125 2.5H16.625C17.3154 2.5 17.875 3.05964 17.875 3.75V6.25C17.875 6.94036 17.3154 7.5 16.625 7.5H14.125C13.4346 7.5 12.875 6.94036 12.875 6.25V3.75ZM16.625 3.75H14.125V6.25H16.625V3.75Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.875 3.75C2.875 3.05964 3.43464 2.5 4.125 2.5H6.625C7.31536 2.5 7.875 3.05964 7.875 3.75V6.25C7.875 6.94036 7.31536 7.5 6.625 7.5H4.125C3.43464 7.5 2.875 6.94036 2.875 6.25V3.75ZM6.625 3.75H4.125V6.25H6.625V3.75Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M12.875 13.75C12.875 13.0596 13.4346 12.5 14.125 12.5H16.625C17.3154 12.5 17.875 13.0596 17.875 13.75V16.25C17.875 16.9404 17.3154 17.5 16.625 17.5H14.125C13.4346 17.5 12.875 16.9404 12.875 16.25V13.75ZM16.625 13.75H14.125V16.25H16.625V13.75Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.875 13.75C2.875 13.0596 3.43464 12.5 4.125 12.5H6.625C7.31536 12.5 7.875 13.0596 7.875 13.75V16.25C7.875 16.9404 7.31536 17.5 6.625 17.5H4.125C3.43464 17.5 2.875 16.9404 2.875 16.25V13.75ZM6.625 13.75H4.125V16.25H6.625V13.75Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M5.375 6.25C5.72018 6.25 6 6.52982 6 6.875V13.125C6 13.4702 5.72018 13.75 5.375 13.75C5.02982 13.75 4.75 13.4702 4.75 13.125V6.875C4.75 6.52982 5.02982 6.25 5.375 6.25Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M6.625 15C6.625 14.6548 6.90482 14.375 7.25 14.375H13.5C13.8452 14.375 14.125 14.6548 14.125 15C14.125 15.3452 13.8452 15.625 13.5 15.625H7.25C6.90482 15.625 6.625 15.3452 6.625 15Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M15.375 6.25C15.7202 6.25 16 6.52982 16 6.875V13.125C16 13.4702 15.7202 13.75 15.375 13.75C15.0298 13.75 14.75 13.4702 14.75 13.125V6.875C14.75 6.52982 15.0298 6.25 15.375 6.25Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M6.625 5C6.625 4.65482 6.90482 4.375 7.25 4.375H13.5C13.8452 4.375 14.125 4.65482 14.125 5C14.125 5.34518 13.8452 5.625 13.5 5.625H7.25C6.90482 5.625 6.625 5.34518 6.625 5Z" fill="#60BA69"/> | |||
| </svg> | |||
| @@ -0,0 +1,8 @@ | |||
| <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M17.2506 5.625H3.50061C3.15543 5.625 2.87561 5.90482 2.87561 6.25V16.25C2.87561 16.5952 3.15543 16.875 3.50061 16.875H17.2506C17.5958 16.875 17.8756 16.5952 17.8756 16.25V6.25C17.8756 5.90482 17.5958 5.625 17.2506 5.625Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M10.375 8.4375C10.7202 8.4375 11 8.71732 11 9.0625V13.4375C11 13.7827 10.7202 14.0625 10.375 14.0625C10.0298 14.0625 9.75 13.7827 9.75 13.4375V9.0625C9.75 8.71732 10.0298 8.4375 10.375 8.4375Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M7.5625 11.25C7.5625 10.9048 7.84232 10.625 8.1875 10.625H12.5625C12.9077 10.625 13.1875 10.9048 13.1875 11.25C13.1875 11.5952 12.9077 11.875 12.5625 11.875H8.1875C7.84232 11.875 7.5625 11.5952 7.5625 11.25Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.25061 6.25C2.25061 5.55964 2.81025 5 3.50061 5H17.2506C17.941 5 18.5006 5.55964 18.5006 6.25V16.25C18.5006 16.9404 17.941 17.5 17.2506 17.5H3.50061C2.81025 17.5 2.25061 16.9404 2.25061 16.25V6.25ZM17.2506 6.25H3.50061V16.25H17.2506V6.25Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M7.17418 3.04917C7.52581 2.69754 8.00272 2.5 8.5 2.5H12.25C12.7473 2.5 13.2242 2.69754 13.5758 3.04917C13.9275 3.40081 14.125 3.87772 14.125 4.375V5.625C14.125 5.97018 13.8452 6.25 13.5 6.25C13.1548 6.25 12.875 5.97018 12.875 5.625V4.375C12.875 4.20924 12.8092 4.05027 12.6919 3.93306C12.5747 3.81585 12.4158 3.75 12.25 3.75H8.5C8.33424 3.75 8.17527 3.81585 8.05806 3.93306C7.94085 4.05027 7.875 4.20924 7.875 4.375V5.625C7.875 5.97018 7.59518 6.25 7.25 6.25C6.90482 6.25 6.625 5.97018 6.625 5.625V4.375C6.625 3.87772 6.82254 3.40081 7.17418 3.04917Z" fill="#60BA69"/> | |||
| </svg> | |||
| @@ -0,0 +1,8 @@ | |||
| <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M7.74999 8.125H3.375V15.625H7.74999V8.125Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.75 4.375C2.75 4.02982 3.02982 3.75 3.375 3.75H18.375C18.7201 3.75 19 4.02982 19 4.375V15C19 15.3315 18.8683 15.6495 18.6339 15.8839C18.3994 16.1183 18.0815 16.25 17.75 16.25H4C3.66848 16.25 3.35054 16.1183 3.11612 15.8839C2.8817 15.6495 2.75 15.3315 2.75 15V4.375ZM4 5V15H17.75V5H4Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.75 8.125C2.75 7.77982 3.02982 7.5 3.375 7.5H18.375C18.7202 7.5 19 7.77982 19 8.125C19 8.47018 18.7202 8.75 18.375 8.75H3.375C3.02982 8.75 2.75 8.47018 2.75 8.125Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M2.75 11.875C2.75 11.5298 3.02982 11.25 3.375 11.25H18.375C18.7202 11.25 19 11.5298 19 11.875C19 12.2202 18.7202 12.5 18.375 12.5H3.375C3.02982 12.5 2.75 12.2202 2.75 11.875Z" fill="#60BA69"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M7.75 7.5C8.09518 7.5 8.375 7.77982 8.375 8.125V15.625C8.375 15.9702 8.09518 16.25 7.75 16.25C7.40482 16.25 7.125 15.9702 7.125 15.625V8.125C7.125 7.77982 7.40482 7.5 7.75 7.5Z" fill="#60BA69"/> | |||
| </svg> | |||
| @@ -0,0 +1,3 @@ | |||
| <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M10.125 2.25H8.25018V1.875C8.24985 1.57673 8.13121 1.29078 7.92031 1.07988C7.7094 0.868972 7.42345 0.750337 7.12518 0.75H4.87518C4.57692 0.750337 4.29097 0.868972 4.08006 1.07988C3.86916 1.29078 3.75052 1.57673 3.75018 1.875V2.25H1.875C1.77554 2.25 1.68016 2.28951 1.60984 2.35984C1.53951 2.43016 1.5 2.52554 1.5 2.625C1.5 2.72446 1.53951 2.81984 1.60984 2.89016C1.68016 2.96049 1.77554 3 1.875 3H2.25V9.75C2.25023 9.94884 2.32932 10.1395 2.46992 10.2801C2.61052 10.4207 2.80116 10.4998 3 10.5H9C9.19884 10.4998 9.38948 10.4207 9.53008 10.2801C9.67068 10.1395 9.74977 9.94884 9.75 9.75V3H10.125C10.2245 3 10.3198 2.96049 10.3902 2.89016C10.4605 2.81984 10.5 2.72446 10.5 2.625C10.5 2.52554 10.4605 2.43016 10.3902 2.35984C10.3198 2.28951 10.2245 2.25 10.125 2.25ZM5.25018 7.875C5.25018 7.97446 5.21067 8.06984 5.14035 8.14017C5.07002 8.21049 4.97464 8.25 4.87518 8.25C4.77573 8.25 4.68034 8.21049 4.61002 8.14017C4.53969 8.06984 4.50018 7.97446 4.50018 7.875V4.875C4.50018 4.77554 4.53969 4.68016 4.61002 4.60984C4.68034 4.53951 4.77573 4.5 4.87518 4.5C4.97464 4.5 5.07002 4.53951 5.14035 4.60984C5.21067 4.68016 5.25018 4.77554 5.25018 4.875V7.875ZM7.50018 7.875C7.50018 7.97446 7.46067 8.06984 7.39035 8.14017C7.32002 8.21049 7.22464 8.25 7.12518 8.25C7.02573 8.25 6.93034 8.21049 6.86002 8.14017C6.78969 8.06984 6.75018 7.97446 6.75018 7.875V4.875C6.75018 4.77554 6.78969 4.68016 6.86002 4.60984C6.93034 4.53951 7.02573 4.5 7.12518 4.5C7.22464 4.5 7.32002 4.53951 7.39035 4.60984C7.46067 4.68016 7.50018 4.77554 7.50018 4.875V7.875ZM7.50018 2.25H4.50018V1.875C4.5003 1.77558 4.53984 1.68026 4.61014 1.60996C4.68045 1.53966 4.77576 1.50011 4.87518 1.5H7.12518C7.2246 1.50011 7.31992 1.53966 7.39022 1.60996C7.46052 1.68026 7.50007 1.77558 7.50018 1.875V2.25Z" fill="#F65555"/> | |||
| </svg> | |||
| @@ -0,0 +1,7 @@ | |||
| <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.2" d="M12.125 3C10.3044 3.00002 8.52667 3.55216 7.02642 4.58354C5.52617 5.61492 4.37399 7.07703 3.72198 8.77684C3.06997 10.4767 2.94879 12.3342 3.37446 14.1044C3.80012 15.8745 4.75259 17.4739 6.10614 18.6914V18.6913C6.67083 17.5804 7.53207 16.6474 8.59442 15.9959C9.65678 15.3444 10.8788 14.9997 12.125 15C11.3833 15 10.6583 14.7801 10.0416 14.368C9.42493 13.956 8.94428 13.3703 8.66045 12.6851C8.37662 11.9998 8.30236 11.2458 8.44706 10.5184C8.59175 9.79098 8.9489 9.1228 9.47335 8.59835C9.9978 8.0739 10.666 7.71675 11.3934 7.57205C12.1208 7.42736 12.8748 7.50162 13.5601 7.78545C14.2453 8.06928 14.831 8.54993 15.243 9.16661C15.6551 9.7833 15.875 10.5083 15.875 11.25C15.875 12.2446 15.4799 13.1984 14.7766 13.9016C14.0734 14.6049 13.1196 15 12.125 15C13.3712 14.9997 14.5932 15.3444 15.6556 15.9959C16.7179 16.6474 17.5792 17.5804 18.1439 18.6913C19.4974 17.4738 20.4499 15.8744 20.8755 14.1043C21.3012 12.3342 21.18 10.4766 20.528 8.77679C19.876 7.07698 18.7238 5.61487 17.2236 4.58351C15.7233 3.55214 13.9456 3 12.125 3Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M12.125 3.75C7.56865 3.75 3.875 7.44365 3.875 12C3.875 16.5563 7.56865 20.25 12.125 20.25C16.6813 20.25 20.375 16.5563 20.375 12C20.375 7.44365 16.6813 3.75 12.125 3.75ZM2.375 12C2.375 6.61522 6.74022 2.25 12.125 2.25C17.5098 2.25 21.875 6.61522 21.875 12C21.875 17.3848 17.5098 21.75 12.125 21.75C6.74022 21.75 2.375 17.3848 2.375 12Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M12.125 8.25C10.4681 8.25 9.125 9.59315 9.125 11.25C9.125 12.9069 10.4681 14.25 12.125 14.25C13.7819 14.25 15.125 12.9069 15.125 11.25C15.125 9.59315 13.7819 8.25 12.125 8.25ZM7.625 11.25C7.625 8.76472 9.63972 6.75 12.125 6.75C14.6103 6.75 16.625 8.76472 16.625 11.25C16.625 13.7353 14.6103 15.75 12.125 15.75C9.63972 15.75 7.625 13.7353 7.625 11.25Z" fill="#6E7987"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M12.1249 15.75C11.0172 15.75 9.93105 16.0565 8.98675 16.6357C8.04245 17.2148 7.27682 18.044 6.77462 19.0313C6.58683 19.4005 6.13531 19.5476 5.7661 19.3598C5.3969 19.172 5.24983 18.7205 5.43762 18.3513C6.06531 17.1172 7.02227 16.0809 8.20254 15.357C9.38282 14.6331 10.7404 14.25 12.1249 14.25C13.5095 14.25 14.8671 14.6331 16.0473 15.357C17.2276 16.0808 18.1846 17.1172 18.8123 18.3513C19.0001 18.7205 18.853 19.172 18.4838 19.3598C18.1146 19.5476 17.6631 19.4005 17.4753 19.0313C16.9731 18.0439 16.2074 17.2148 15.2631 16.6357C14.3188 16.0565 13.2327 15.75 12.1249 15.75Z" fill="#6E7987"/> | |||
| </svg> | |||
| @@ -0,0 +1,8 @@ | |||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M7.09314 13.332C7.09314 12.9869 7.37296 12.707 7.71814 12.707H11.8848C12.23 12.707 12.5098 12.9869 12.5098 13.332C12.5098 13.6772 12.23 13.957 11.8848 13.957H7.71814C7.37296 13.957 7.09314 13.6772 7.09314 13.332Z" fill="#2D3748"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M7.88097 2.44049C7.34694 2.68136 6.84587 3.26994 6.31539 4.49691C6.30752 4.51513 6.29878 4.53295 6.28921 4.55033C6.28845 4.55243 6.28753 4.55504 6.2864 4.55827L6.27631 4.58819C6.27033 4.60612 6.26355 4.62376 6.25598 4.64106L6.20164 4.76526L6.1683 4.84861L5.19587 7.17114C5.37241 7.15095 5.55179 7.14055 5.73338 7.14055H7.69714L9.70873 2.47227C8.86986 2.22688 8.30735 2.24818 7.88097 2.44049ZM7.36704 1.30103C8.35394 0.855902 9.48354 1.02172 10.7734 1.51514C10.9322 1.5759 11.0594 1.69874 11.1256 1.85534C11.1919 2.01195 11.1915 2.18879 11.1245 2.34508L11.0995 2.40342L8.68236 8.01288C8.5836 8.24208 8.35795 8.39055 8.10838 8.39055H5.73338C5.25301 8.39055 4.7941 8.48938 4.37722 8.66602C4.14322 8.76517 3.87248 8.71276 3.69239 8.53344C3.5123 8.35413 3.45872 8.08361 3.55687 7.84919L5.01327 4.37046L5.04475 4.29177C5.04722 4.28559 5.04978 4.27946 5.05245 4.27337L5.09909 4.16676C5.11331 4.1243 5.13974 4.04997 5.17995 3.97338C5.7386 2.68926 6.39756 1.7383 7.36704 1.30103Z" fill="#2D3748"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M9.97554 1.85256C10.1036 1.55378 10.4393 1.40304 10.7476 1.50583C10.8506 1.54015 10.9929 1.60158 11.0808 1.63952C11.1114 1.65272 11.1353 1.66308 11.1488 1.66846L11.1591 1.67259L12.9993 2.44705C14.0508 2.88319 14.8832 3.37263 15.4159 4.02658C15.5101 4.13985 15.5993 4.25977 15.6801 4.40576C15.7648 4.54009 15.8449 4.6946 15.8984 4.87222C15.9344 4.95902 15.963 5.04524 15.9843 5.12636C16.2685 6.03281 16.0689 7.05545 15.6213 8.16576C15.4997 8.46759 15.1668 8.62555 14.856 8.52887C14.5519 8.43428 14.2162 8.39042 13.8667 8.39042H8.10834C7.89803 8.39042 7.70182 8.28465 7.58623 8.10896C7.47063 7.93328 7.45114 7.71123 7.53436 7.51809L9.95103 1.90976L9.97554 1.85256ZM10.8804 2.91159L9.05821 7.14042H13.8667C14.1236 7.14042 14.385 7.15868 14.6449 7.20011C14.8945 6.43787 14.9187 5.89558 14.7883 5.49001C14.7841 5.47692 14.7803 5.46368 14.777 5.45034C14.7688 5.41764 14.7554 5.37693 14.7372 5.33593C14.7239 5.3059 14.7129 5.27487 14.7044 5.24313C14.6931 5.20051 14.6689 5.14414 14.6159 5.06173C14.6072 5.04816 14.599 5.03427 14.5914 5.02007C14.5593 4.96057 14.5201 4.90418 14.4532 4.82387L14.4482 4.81791C14.1144 4.40704 13.5151 4.01412 12.519 3.60109L12.5159 3.59983L10.8804 2.91159Z" fill="#2D3748"/> | |||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M4.38703 8.66608C3.15902 9.197 2.30145 10.4179 2.30145 11.8323V13.4573C2.30145 13.6235 2.31536 13.7956 2.33787 13.9681C2.33959 13.9813 2.34089 13.9945 2.34176 14.0078C2.42259 15.2317 2.78348 16.0867 3.35277 16.656C3.92206 17.2253 4.77705 17.5862 6.00097 17.667C6.01423 17.6679 6.02745 17.6692 6.04062 17.6709C6.21317 17.6934 6.38526 17.7073 6.55145 17.7073H13.0515C14.5016 17.7073 15.5063 17.3623 16.1636 16.7708C16.8152 16.1845 17.2205 15.2698 17.294 13.9244C17.3024 13.7558 17.3098 13.6052 17.3098 13.4573V11.8323C17.3098 10.2759 16.2748 8.96242 14.8713 8.53078C14.5643 8.44042 14.2252 8.39062 13.8765 8.39062H5.74312C5.26592 8.39062 4.8152 8.48817 4.38703 8.66608ZM3.90273 7.5137C4.47352 7.27588 5.08829 7.14062 5.74312 7.14062H13.8765C14.3433 7.14062 14.803 7.20717 15.2285 7.33291L15.2346 7.33471L15.2346 7.33474C17.1463 7.92072 18.5598 9.70646 18.5598 11.8323V13.4573C18.5598 13.6397 18.5508 13.8195 18.5427 13.9818L18.5423 13.9885L18.5422 13.9913C18.4571 15.5536 17.9709 16.8261 16.9997 17.7C16.0341 18.5689 14.6847 18.9573 13.0515 18.9573H6.55145C6.32498 18.9573 6.10404 18.9391 5.89884 18.9129C4.48164 18.8161 3.31027 18.3812 2.46889 17.5399C1.6275 16.6985 1.19268 15.5271 1.09581 14.1099C1.06968 13.9047 1.05145 13.6838 1.05145 13.4573V11.8323C1.05145 9.89805 2.2256 8.23656 3.89573 7.51667L3.90272 7.51366L3.90273 7.5137Z" fill="#2D3748"/> | |||
| <path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M6.07593 4.2123C6.22187 4.39115 6.25735 4.63587 6.1682 4.8488L4.70987 8.33214C4.64736 8.48143 4.52938 8.60066 4.38075 8.66472C3.15088 9.19484 2.29169 10.4167 2.29169 11.8324C2.29169 12.1776 2.01186 12.4574 1.66669 12.4574C1.32151 12.4574 1.04169 12.1776 1.04169 11.8324V9.39077C1.04169 6.72062 2.94106 4.49267 5.47087 3.99423C5.69735 3.94961 5.92999 4.03345 6.07593 4.2123ZM2.37269 8.55998C2.74117 8.18123 3.1728 7.8643 3.65026 7.62627L4.46514 5.67987C3.39844 6.27771 2.61743 7.32255 2.37269 8.55998Z" fill="#2D3748"/> | |||
| <path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M14.8847 4.63728C15.0772 4.44724 15.3701 4.4026 15.6105 4.52666C17.3638 5.43161 18.5572 7.28489 18.5572 9.39038V11.832C18.5572 12.1772 18.2773 12.457 17.9322 12.457C17.587 12.457 17.3072 12.1772 17.3072 11.832C17.3072 10.2802 16.2768 8.9613 14.8692 8.53902C14.7012 8.48861 14.5621 8.36991 14.4859 8.21191C14.4097 8.0539 14.4034 7.87114 14.4685 7.70826C14.8822 6.67398 14.9489 5.98405 14.7992 5.47507C14.7953 5.4616 14.7918 5.448 14.7887 5.4343C14.7811 5.39989 14.7714 5.37472 14.7648 5.36156C14.6438 5.11962 14.6922 4.82732 14.8847 4.63728ZM17.2247 8.55527C17.0608 7.73598 16.6611 6.99912 16.1004 6.42527C16.0619 6.79361 15.9739 7.17693 15.8454 7.57621C16.3635 7.81687 16.8303 8.1504 17.2247 8.55527Z" fill="#2D3748"/> | |||
| </svg> | |||
| @@ -0,0 +1,4 @@ | |||
| <svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M10.6553 4.26099L8.23901 1.84473C8.09805 1.70457 7.90752 1.62562 7.70874 1.625H4.29126C4.09248 1.62562 3.90195 1.70457 3.76099 1.84473L1.34473 4.26099C1.20457 4.40195 1.12562 4.59248 1.125 4.79126V8.20874C1.12562 8.40752 1.20457 8.59805 1.34473 8.73901L3.76099 11.1553C3.90195 11.2954 4.09248 11.3744 4.29126 11.375H7.70874C7.90752 11.3744 8.09805 11.2954 8.23901 11.1553L10.6553 8.73901C10.7954 8.59805 10.8744 8.40752 10.875 8.20874V4.79126C10.8744 4.59248 10.7954 4.40195 10.6553 4.26099ZM5.625 4.25C5.625 4.15054 5.66451 4.05516 5.73484 3.98484C5.80516 3.91451 5.90054 3.875 6 3.875C6.09946 3.875 6.19484 3.91451 6.26517 3.98484C6.33549 4.05516 6.375 4.15054 6.375 4.25V6.875C6.375 6.97446 6.33549 7.06984 6.26517 7.14017C6.19484 7.21049 6.09946 7.25 6 7.25C5.90054 7.25 5.80516 7.21049 5.73484 7.14017C5.66451 7.06984 5.625 6.97446 5.625 6.875V4.25ZM6 9.125C5.88875 9.125 5.77999 9.09201 5.68749 9.0302C5.59499 8.96839 5.52289 8.88054 5.48032 8.77776C5.43774 8.67498 5.4266 8.56188 5.44831 8.45276C5.47001 8.34365 5.52359 8.24342 5.60225 8.16475C5.68092 8.08609 5.78115 8.03251 5.89026 8.01081C5.99938 7.9891 6.11248 8.00024 6.21526 8.04282C6.31804 8.08539 6.40589 8.15749 6.4677 8.24999C6.52951 8.34249 6.5625 8.45125 6.5625 8.5625C6.56249 8.71168 6.50323 8.85475 6.39774 8.96024C6.29225 9.06573 6.14918 9.12499 6 9.125Z" fill="#F65555"/> | |||
| </svg> | |||
| @@ -0,0 +1,6 @@ | |||
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M12.3335 15.1667C10.7735 15.1667 9.50016 13.8933 9.50016 12.3333V12C9.50016 11.7267 9.72683 11.5 10.0002 11.5C10.2735 11.5 10.5002 11.7267 10.5002 12V12.3333C10.5002 13.3467 11.3202 14.1667 12.3335 14.1667C13.3468 14.1667 14.1668 13.3467 14.1668 12.3333C14.1668 11.32 13.3468 10.5 12.3335 10.5H1.3335C1.06016 10.5 0.833496 10.2733 0.833496 10C0.833496 9.72667 1.06016 9.5 1.3335 9.5H12.3335C13.8935 9.5 15.1668 10.7733 15.1668 12.3333C15.1668 13.8933 13.8935 15.1667 12.3335 15.1667Z" fill="white"/> | |||
| <path opacity="0.4" d="M12.3335 8.50004H1.3335C1.06016 8.50004 0.833496 8.27337 0.833496 8.00004C0.833496 7.72671 1.06016 7.50004 1.3335 7.50004H12.3335C13.3468 7.50004 14.1668 6.68004 14.1668 5.66671C14.1668 4.65337 13.3468 3.83337 12.3335 3.83337C11.3202 3.83337 10.5002 4.65337 10.5002 5.66671V6.00004C10.5002 6.27337 10.2735 6.50004 10.0002 6.50004C9.72683 6.50004 9.50016 6.27337 9.50016 6.00004V5.66671C9.50016 4.10671 10.7735 2.83337 12.3335 2.83337C13.8935 2.83337 15.1668 4.10671 15.1668 5.66671C15.1668 7.22671 13.8935 8.50004 12.3335 8.50004Z" fill="white"/> | |||
| <path d="M6.20683 6.5H1.3335C1.06016 6.5 0.833496 6.27333 0.833496 6C0.833496 5.72666 1.06016 5.5 1.3335 5.5H6.20683C6.92016 5.5 7.50016 4.92 7.50016 4.20666C7.50016 3.49333 6.92016 2.91333 6.20683 2.91333C5.4935 2.91333 4.9135 3.49333 4.9135 4.20666V4.46C4.9135 4.73333 4.68683 4.96 4.4135 4.96C4.14016 4.96 3.9135 4.74 3.9135 4.46V4.20666C3.9135 2.94 4.94016 1.91333 6.20683 1.91333C7.4735 1.91333 8.50016 2.94 8.50016 4.20666C8.50016 5.47333 7.4735 6.5 6.20683 6.5Z" fill="white"/> | |||
| </svg> | |||
| @@ -1,5 +1,5 @@ | |||
| # Uncomment this line to define a global platform for your project | |||
| # platform :ios, '9.0' | |||
| platform :ios, '9.0' | |||
| # CocoaPods analytics sends network stats synchronously affecting flutter build latency. | |||
| ENV['COCOAPODS_DISABLE_STATS'] = 'true' | |||
| @@ -1,202 +1,150 @@ | |||
| PODS: | |||
| - barcode_scan (0.0.1): | |||
| - camera_avfoundation (0.0.1): | |||
| - Flutter | |||
| - MTBBarcodeScanner | |||
| - SwiftProtobuf | |||
| - camera (0.0.1): | |||
| - Flutter | |||
| - DKImagePickerController/Core (4.3.2): | |||
| - DKImagePickerController/ImageDataManager | |||
| - DKImagePickerController/Resource | |||
| - DKImagePickerController/ImageDataManager (4.3.2) | |||
| - DKImagePickerController/PhotoGallery (4.3.2): | |||
| - DKImagePickerController/Core | |||
| - DKPhotoGallery | |||
| - DKImagePickerController/Resource (4.3.2) | |||
| - DKPhotoGallery (0.0.17): | |||
| - DKPhotoGallery/Core (= 0.0.17) | |||
| - DKPhotoGallery/Model (= 0.0.17) | |||
| - DKPhotoGallery/Preview (= 0.0.17) | |||
| - DKPhotoGallery/Resource (= 0.0.17) | |||
| - SDWebImage | |||
| - SwiftyGif | |||
| - DKPhotoGallery/Core (0.0.17): | |||
| - DKPhotoGallery/Model | |||
| - DKPhotoGallery/Preview | |||
| - SDWebImage | |||
| - SwiftyGif | |||
| - DKPhotoGallery/Model (0.0.17): | |||
| - SDWebImage | |||
| - SwiftyGif | |||
| - DKPhotoGallery/Preview (0.0.17): | |||
| - DKPhotoGallery/Model | |||
| - DKPhotoGallery/Resource | |||
| - SDWebImage | |||
| - SwiftyGif | |||
| - DKPhotoGallery/Resource (0.0.17): | |||
| - SDWebImage | |||
| - SwiftyGif | |||
| - file_picker (0.0.1): | |||
| - DKImagePickerController/PhotoGallery | |||
| - Flutter | |||
| - Firebase/CoreOnly (6.26.0): | |||
| - FirebaseCore (= 6.7.2) | |||
| - Firebase/Messaging (6.26.0): | |||
| - Firebase/CoreOnly (10.3.0): | |||
| - FirebaseCore (= 10.3.0) | |||
| - Firebase/Messaging (10.3.0): | |||
| - Firebase/CoreOnly | |||
| - FirebaseMessaging (~> 4.4.1) | |||
| - firebase_core (0.5.0): | |||
| - Firebase/CoreOnly (~> 6.26.0) | |||
| - FirebaseMessaging (~> 10.3.0) | |||
| - firebase_core (2.7.1): | |||
| - Firebase/CoreOnly (= 10.3.0) | |||
| - Flutter | |||
| - firebase_messaging (7.0.0): | |||
| - Firebase/CoreOnly (~> 6.26.0) | |||
| - Firebase/Messaging (~> 6.26.0) | |||
| - firebase_messaging (14.2.6): | |||
| - Firebase/Messaging (= 10.3.0) | |||
| - firebase_core | |||
| - Flutter | |||
| - FirebaseAnalyticsInterop (1.5.0) | |||
| - FirebaseCore (6.7.2): | |||
| - FirebaseCoreDiagnostics (~> 1.3) | |||
| - FirebaseCoreDiagnosticsInterop (~> 1.2) | |||
| - GoogleUtilities/Environment (~> 6.5) | |||
| - GoogleUtilities/Logger (~> 6.5) | |||
| - FirebaseCoreDiagnostics (1.7.0): | |||
| - GoogleDataTransport (~> 7.4) | |||
| - GoogleUtilities/Environment (~> 6.7) | |||
| - GoogleUtilities/Logger (~> 6.7) | |||
| - nanopb (~> 1.30906.0) | |||
| - FirebaseCoreDiagnosticsInterop (1.2.0) | |||
| - FirebaseInstallations (1.3.0): | |||
| - FirebaseCore (~> 6.6) | |||
| - GoogleUtilities/Environment (~> 6.6) | |||
| - GoogleUtilities/UserDefaults (~> 6.6) | |||
| - PromisesObjC (~> 1.2) | |||
| - FirebaseInstanceID (4.3.4): | |||
| - FirebaseCore (~> 6.6) | |||
| - FirebaseInstallations (~> 1.0) | |||
| - GoogleUtilities/Environment (~> 6.5) | |||
| - GoogleUtilities/UserDefaults (~> 6.5) | |||
| - FirebaseMessaging (4.4.1): | |||
| - FirebaseAnalyticsInterop (~> 1.5) | |||
| - FirebaseCore (~> 6.6) | |||
| - FirebaseInstanceID (~> 4.3) | |||
| - GoogleUtilities/AppDelegateSwizzler (~> 6.5) | |||
| - GoogleUtilities/Environment (~> 6.5) | |||
| - GoogleUtilities/Reachability (~> 6.5) | |||
| - GoogleUtilities/UserDefaults (~> 6.5) | |||
| - Protobuf (>= 3.9.2, ~> 3.9) | |||
| - FirebaseCore (10.3.0): | |||
| - FirebaseCoreInternal (~> 10.0) | |||
| - GoogleUtilities/Environment (~> 7.8) | |||
| - GoogleUtilities/Logger (~> 7.8) | |||
| - FirebaseCoreInternal (10.9.0): | |||
| - "GoogleUtilities/NSData+zlib (~> 7.8)" | |||
| - FirebaseInstallations (10.9.0): | |||
| - FirebaseCore (~> 10.0) | |||
| - GoogleUtilities/Environment (~> 7.8) | |||
| - GoogleUtilities/UserDefaults (~> 7.8) | |||
| - PromisesObjC (~> 2.1) | |||
| - FirebaseMessaging (10.3.0): | |||
| - FirebaseCore (~> 10.0) | |||
| - FirebaseInstallations (~> 10.0) | |||
| - GoogleDataTransport (~> 9.2) | |||
| - GoogleUtilities/AppDelegateSwizzler (~> 7.8) | |||
| - GoogleUtilities/Environment (~> 7.8) | |||
| - GoogleUtilities/Reachability (~> 7.8) | |||
| - GoogleUtilities/UserDefaults (~> 7.8) | |||
| - nanopb (< 2.30910.0, >= 2.30908.0) | |||
| - Flutter (1.0.0) | |||
| - flutter_image_compress (0.0.1): | |||
| - flutter_image_compress (1.0.0): | |||
| - Flutter | |||
| - Mantle | |||
| - SDWebImage | |||
| - SDWebImageWebPCoder | |||
| - flutter_local_notifications (0.0.1): | |||
| - Flutter | |||
| - fluttertoast (0.0.2): | |||
| - Flutter | |||
| - Toast | |||
| - FMDB (2.7.5): | |||
| - FMDB/standard (= 2.7.5) | |||
| - FMDB/standard (2.7.5) | |||
| - GoogleDataTransport (7.5.0): | |||
| - nanopb (~> 1.30906.0) | |||
| - GoogleUtilities/AppDelegateSwizzler (6.7.2): | |||
| - GoogleDataTransport (9.2.2): | |||
| - GoogleUtilities/Environment (~> 7.7) | |||
| - nanopb (< 2.30910.0, >= 2.30908.0) | |||
| - PromisesObjC (< 3.0, >= 1.2) | |||
| - GoogleUtilities/AppDelegateSwizzler (7.11.1): | |||
| - GoogleUtilities/Environment | |||
| - GoogleUtilities/Logger | |||
| - GoogleUtilities/Network | |||
| - GoogleUtilities/Environment (6.7.2): | |||
| - PromisesObjC (~> 1.2) | |||
| - GoogleUtilities/Logger (6.7.2): | |||
| - GoogleUtilities/Environment (7.11.1): | |||
| - PromisesObjC (< 3.0, >= 1.2) | |||
| - GoogleUtilities/Logger (7.11.1): | |||
| - GoogleUtilities/Environment | |||
| - GoogleUtilities/Network (6.7.2): | |||
| - GoogleUtilities/Network (7.11.1): | |||
| - GoogleUtilities/Logger | |||
| - "GoogleUtilities/NSData+zlib" | |||
| - GoogleUtilities/Reachability | |||
| - "GoogleUtilities/NSData+zlib (6.7.2)" | |||
| - GoogleUtilities/Reachability (6.7.2): | |||
| - "GoogleUtilities/NSData+zlib (7.11.1)" | |||
| - GoogleUtilities/Reachability (7.11.1): | |||
| - GoogleUtilities/Logger | |||
| - GoogleUtilities/UserDefaults (6.7.2): | |||
| - GoogleUtilities/UserDefaults (7.11.1): | |||
| - GoogleUtilities/Logger | |||
| - libwebp (1.1.0): | |||
| - libwebp/demux (= 1.1.0) | |||
| - libwebp/mux (= 1.1.0) | |||
| - libwebp/webp (= 1.1.0) | |||
| - libwebp/demux (1.1.0): | |||
| - image_picker_ios (0.0.1): | |||
| - Flutter | |||
| - libwebp (1.2.4): | |||
| - libwebp/demux (= 1.2.4) | |||
| - libwebp/mux (= 1.2.4) | |||
| - libwebp/webp (= 1.2.4) | |||
| - libwebp/demux (1.2.4): | |||
| - libwebp/webp | |||
| - libwebp/mux (1.1.0): | |||
| - libwebp/mux (1.2.4): | |||
| - libwebp/demux | |||
| - libwebp/webp (1.1.0) | |||
| - Mantle (2.1.4): | |||
| - Mantle/extobjc (= 2.1.4) | |||
| - Mantle/extobjc (2.1.4) | |||
| - MTBBarcodeScanner (5.0.11) | |||
| - nanopb (1.30906.0): | |||
| - nanopb/decode (= 1.30906.0) | |||
| - nanopb/encode (= 1.30906.0) | |||
| - nanopb/decode (1.30906.0) | |||
| - nanopb/encode (1.30906.0) | |||
| - libwebp/webp (1.2.4) | |||
| - Mantle (2.2.0): | |||
| - Mantle/extobjc (= 2.2.0) | |||
| - Mantle/extobjc (2.2.0) | |||
| - nanopb (2.30909.0): | |||
| - nanopb/decode (= 2.30909.0) | |||
| - nanopb/encode (= 2.30909.0) | |||
| - nanopb/decode (2.30909.0) | |||
| - nanopb/encode (2.30909.0) | |||
| - package_info (0.0.1): | |||
| - Flutter | |||
| - path_provider (0.0.1): | |||
| - path_provider_foundation (0.0.1): | |||
| - Flutter | |||
| - PromisesObjC (1.2.11) | |||
| - Protobuf (3.13.0) | |||
| - SDWebImage (5.9.2): | |||
| - SDWebImage/Core (= 5.9.2) | |||
| - SDWebImage/Core (5.9.2) | |||
| - SDWebImageWebPCoder (0.6.1): | |||
| - FlutterMacOS | |||
| - PromisesObjC (2.2.0) | |||
| - SDWebImage (5.15.6): | |||
| - SDWebImage/Core (= 5.15.6) | |||
| - SDWebImage/Core (5.15.6) | |||
| - SDWebImageWebPCoder (0.11.0): | |||
| - libwebp (~> 1.0) | |||
| - SDWebImage/Core (~> 5.7) | |||
| - shared_preferences (0.0.1): | |||
| - SDWebImage/Core (~> 5.15) | |||
| - shared_preferences_foundation (0.0.1): | |||
| - Flutter | |||
| - sqflite (0.0.1): | |||
| - FlutterMacOS | |||
| - sqflite (0.0.2): | |||
| - Flutter | |||
| - FMDB (~> 2.7.2) | |||
| - SwiftProtobuf (1.12.0) | |||
| - SwiftyGif (5.3.0) | |||
| - video_player (0.0.1): | |||
| - FMDB (>= 2.7.5) | |||
| - Toast (4.0.0) | |||
| - video_player_avfoundation (0.0.1): | |||
| - Flutter | |||
| DEPENDENCIES: | |||
| - barcode_scan (from `.symlinks/plugins/barcode_scan/ios`) | |||
| - camera (from `.symlinks/plugins/camera/ios`) | |||
| - file_picker (from `.symlinks/plugins/file_picker/ios`) | |||
| - camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`) | |||
| - firebase_core (from `.symlinks/plugins/firebase_core/ios`) | |||
| - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) | |||
| - Flutter (from `Flutter`) | |||
| - flutter_image_compress (from `.symlinks/plugins/flutter_image_compress/ios`) | |||
| - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) | |||
| - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) | |||
| - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) | |||
| - package_info (from `.symlinks/plugins/package_info/ios`) | |||
| - path_provider (from `.symlinks/plugins/path_provider/ios`) | |||
| - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) | |||
| - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) | |||
| - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) | |||
| - sqflite (from `.symlinks/plugins/sqflite/ios`) | |||
| - video_player (from `.symlinks/plugins/video_player/ios`) | |||
| - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`) | |||
| SPEC REPOS: | |||
| trunk: | |||
| - DKImagePickerController | |||
| - DKPhotoGallery | |||
| - Firebase | |||
| - FirebaseAnalyticsInterop | |||
| - FirebaseCore | |||
| - FirebaseCoreDiagnostics | |||
| - FirebaseCoreDiagnosticsInterop | |||
| - FirebaseCoreInternal | |||
| - FirebaseInstallations | |||
| - FirebaseInstanceID | |||
| - FirebaseMessaging | |||
| - FMDB | |||
| - GoogleDataTransport | |||
| - GoogleUtilities | |||
| - libwebp | |||
| - Mantle | |||
| - MTBBarcodeScanner | |||
| - nanopb | |||
| - PromisesObjC | |||
| - Protobuf | |||
| - SDWebImage | |||
| - SDWebImageWebPCoder | |||
| - SwiftProtobuf | |||
| - SwiftyGif | |||
| - Toast | |||
| EXTERNAL SOURCES: | |||
| barcode_scan: | |||
| :path: ".symlinks/plugins/barcode_scan/ios" | |||
| camera: | |||
| :path: ".symlinks/plugins/camera/ios" | |||
| file_picker: | |||
| :path: ".symlinks/plugins/file_picker/ios" | |||
| camera_avfoundation: | |||
| :path: ".symlinks/plugins/camera_avfoundation/ios" | |||
| firebase_core: | |||
| :path: ".symlinks/plugins/firebase_core/ios" | |||
| firebase_messaging: | |||
| @@ -205,54 +153,53 @@ EXTERNAL SOURCES: | |||
| :path: Flutter | |||
| flutter_image_compress: | |||
| :path: ".symlinks/plugins/flutter_image_compress/ios" | |||
| flutter_local_notifications: | |||
| :path: ".symlinks/plugins/flutter_local_notifications/ios" | |||
| fluttertoast: | |||
| :path: ".symlinks/plugins/fluttertoast/ios" | |||
| image_picker_ios: | |||
| :path: ".symlinks/plugins/image_picker_ios/ios" | |||
| package_info: | |||
| :path: ".symlinks/plugins/package_info/ios" | |||
| path_provider: | |||
| :path: ".symlinks/plugins/path_provider/ios" | |||
| shared_preferences: | |||
| :path: ".symlinks/plugins/shared_preferences/ios" | |||
| path_provider_foundation: | |||
| :path: ".symlinks/plugins/path_provider_foundation/ios" | |||
| shared_preferences_foundation: | |||
| :path: ".symlinks/plugins/shared_preferences_foundation/ios" | |||
| sqflite: | |||
| :path: ".symlinks/plugins/sqflite/ios" | |||
| video_player: | |||
| :path: ".symlinks/plugins/video_player/ios" | |||
| video_player_avfoundation: | |||
| :path: ".symlinks/plugins/video_player_avfoundation/ios" | |||
| SPEC CHECKSUMS: | |||
| barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479 | |||
| camera: a0ca5080336f7af47b88436e5e26da3dee5568f0 | |||
| DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d | |||
| DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 | |||
| file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1 | |||
| Firebase: 7cf5f9c67f03cb3b606d1d6535286e1080e57eb6 | |||
| firebase_core: 3134fe79d257d430f163b558caf52a10a87efe8a | |||
| firebase_messaging: 6061cbdfe4463502a0d4d7049820c25d1757a095 | |||
| FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae | |||
| FirebaseCore: f42e5e5f382cdcf6b617ed737bf6c871a6947b17 | |||
| FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 | |||
| FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850 | |||
| FirebaseInstallations: 6f5f680e65dc374397a483c32d1799ba822a395b | |||
| FirebaseInstanceID: cef67c4967c7cecb56ea65d8acbb4834825c587b | |||
| FirebaseMessaging: 29543feb343b09546ab3aa04d008ee8595b43c44 | |||
| Flutter: 0e3d915762c693b495b44d77113d4970485de6ec | |||
| flutter_image_compress: 082f8daaf6c1b0c9fe798251c750ef0ecd98d7ae | |||
| camera_avfoundation: 82dc5597033fe2dcdcca6e41f7e464d0855e74ad | |||
| Firebase: f92fc551ead69c94168d36c2b26188263860acd9 | |||
| firebase_core: 1ae9f9aa76e6e1edc14fb181637ad466fd6c6fa4 | |||
| firebase_messaging: f8c01f8b540feb4196e8dbe45ae17534747d779d | |||
| FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a | |||
| FirebaseCoreInternal: d2b4acb827908e72eca47a9fd896767c3053921e | |||
| FirebaseInstallations: c58489c9caacdbf27d1da60891a87318e20218e0 | |||
| FirebaseMessaging: e345b219fd15d325f0cf2fef28cb8ce00d851b3f | |||
| Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a | |||
| flutter_image_compress: 5a5e9aee05b6553048b8df1c3bc456d0afaac433 | |||
| flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 | |||
| fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 | |||
| FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a | |||
| GoogleDataTransport: 445302b7da4216da63071a4c29e7023f47192e5a | |||
| GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 | |||
| libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3 | |||
| Mantle: bf2e1b464f82465b9074e9de970739a2615e093a | |||
| MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb | |||
| nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc | |||
| GoogleDataTransport: 8378d1fa8ac49753ea6ce70d65a7cb70ce5f66e6 | |||
| GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749 | |||
| image_picker_ios: 58b9c4269cb176f89acea5e5d043c9358f2d25f8 | |||
| libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef | |||
| Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d | |||
| nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 | |||
| package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 | |||
| path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c | |||
| PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f | |||
| Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748 | |||
| SDWebImage: 0b42b8719ab0c5257177d5894306e8a336b21cbb | |||
| SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21 | |||
| shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d | |||
| sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0 | |||
| SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699 | |||
| SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40 | |||
| video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e | |||
| path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 | |||
| PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef | |||
| SDWebImage: d47d81bea8a77187896b620dc79c3c528e8906b9 | |||
| SDWebImageWebPCoder: 295a6573c512f54ad2dd58098e64e17dcf008499 | |||
| shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472 | |||
| sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 | |||
| Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 | |||
| video_player_avfoundation: 6d971a232d72e6ee25368378d48a079dea01f1cf | |||
| PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c | |||
| PODFILE CHECKSUM: a75497545d4391e2d394c3668e20cfb1c2bbd4aa | |||
| COCOAPODS: 1.10.0 | |||
| COCOAPODS: 1.12.1 | |||
| @@ -403,15 +403,17 @@ | |||
| ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | |||
| CLANG_ENABLE_MODULES = YES; | |||
| CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | |||
| CODE_SIGN_IDENTITY = "Apple Development"; | |||
| CODE_SIGN_STYLE = Automatic; | |||
| CURRENT_PROJECT_VERSION = 3; | |||
| DEVELOPMENT_TEAM = C3DTD2JH94; | |||
| DEVELOPMENT_TEAM = P9V88ZF854; | |||
| ENABLE_BITCODE = NO; | |||
| FRAMEWORK_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| INFOPLIST_FILE = Runner/Info.plist; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 9.0; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 12.0; | |||
| LD_RUNPATH_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "@executable_path/Frameworks", | |||
| @@ -421,8 +423,9 @@ | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| MARKETING_VERSION = 1.0.1; | |||
| PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.tpfarm; | |||
| PRODUCT_BUNDLE_IDENTIFIER = vn.bteducation.vietkids; | |||
| PRODUCT_NAME = Runner; | |||
| PROVISIONING_PROFILE_SPECIFIER = ""; | |||
| SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | |||
| SWIFT_VERSION = 5.0; | |||
| TARGETED_DEVICE_FAMILY = "1,2"; | |||
| @@ -546,15 +549,17 @@ | |||
| ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | |||
| CLANG_ENABLE_MODULES = YES; | |||
| CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | |||
| CODE_SIGN_IDENTITY = "Apple Development"; | |||
| CODE_SIGN_STYLE = Automatic; | |||
| CURRENT_PROJECT_VERSION = 3; | |||
| DEVELOPMENT_TEAM = C3DTD2JH94; | |||
| DEVELOPMENT_TEAM = P9V88ZF854; | |||
| ENABLE_BITCODE = NO; | |||
| FRAMEWORK_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| INFOPLIST_FILE = Runner/Info.plist; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 9.0; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 12.0; | |||
| LD_RUNPATH_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "@executable_path/Frameworks", | |||
| @@ -564,8 +569,9 @@ | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| MARKETING_VERSION = 1.0.1; | |||
| PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.tpfarm; | |||
| PRODUCT_BUNDLE_IDENTIFIER = vn.bteducation.vietkids; | |||
| PRODUCT_NAME = Runner; | |||
| PROVISIONING_PROFILE_SPECIFIER = ""; | |||
| SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | |||
| SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | |||
| SWIFT_VERSION = 5.0; | |||
| @@ -581,15 +587,17 @@ | |||
| ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | |||
| CLANG_ENABLE_MODULES = YES; | |||
| CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | |||
| CODE_SIGN_IDENTITY = "Apple Development"; | |||
| CODE_SIGN_STYLE = Automatic; | |||
| CURRENT_PROJECT_VERSION = 3; | |||
| DEVELOPMENT_TEAM = C3DTD2JH94; | |||
| DEVELOPMENT_TEAM = P9V88ZF854; | |||
| ENABLE_BITCODE = NO; | |||
| FRAMEWORK_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| INFOPLIST_FILE = Runner/Info.plist; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 9.0; | |||
| IPHONEOS_DEPLOYMENT_TARGET = 12.0; | |||
| LD_RUNPATH_SEARCH_PATHS = ( | |||
| "$(inherited)", | |||
| "@executable_path/Frameworks", | |||
| @@ -599,8 +607,9 @@ | |||
| "$(PROJECT_DIR)/Flutter", | |||
| ); | |||
| MARKETING_VERSION = 1.0.1; | |||
| PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.tpfarm; | |||
| PRODUCT_BUNDLE_IDENTIFIER = vn.bteducation.vietkids; | |||
| PRODUCT_NAME = Runner; | |||
| PROVISIONING_PROFILE_SPECIFIER = ""; | |||
| SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | |||
| SWIFT_VERSION = 5.0; | |||
| TARGETED_DEVICE_FAMILY = "1,2"; | |||
| @@ -2,6 +2,8 @@ | |||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
| <plist version="1.0"> | |||
| <dict> | |||
| <key>CADisableMinimumFrameDurationOnPhone</key> | |||
| <true/> | |||
| <key>CFBundleDevelopmentRegion</key> | |||
| <string>$(DEVELOPMENT_LANGUAGE)</string> | |||
| <key>CFBundleExecutable</key> | |||
| @@ -54,7 +56,5 @@ | |||
| </array> | |||
| <key>UIViewControllerBasedStatusBarAppearance</key> | |||
| <false/> | |||
| <key>CADisableMinimumFrameDurationOnPhone</key> | |||
| <true/> | |||
| </dict> | |||
| </plist> | |||
| @@ -1,106 +1,184 @@ | |||
| import 'package:farm_tpf/presentation/screens/login/view/login_page.dart'; | |||
| import 'package:farm_tpf/presentation/screens/splash/view/splash_page.dart'; | |||
| import 'package:farm_tpf/presentation/screens/login/login_page.dart'; | |||
| import 'package:farm_tpf/presentation/screens/tabbar/tabbar.dart'; | |||
| import 'package:farm_tpf/routes/route_name.dart'; | |||
| import 'package:farm_tpf/routes/routes.dart'; | |||
| import 'package:farm_tpf/utils/const_color.dart'; | |||
| import 'package:farm_tpf/services/firebase_notification_service.dart'; | |||
| import 'package:farm_tpf/themes/themes.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:flutter_localizations/flutter_localizations.dart'; | |||
| import 'package:flutter_screenutil/flutter_screenutil.dart'; | |||
| import 'package:get/get.dart'; | |||
| import 'package:google_fonts/google_fonts.dart'; | |||
| import 'authentication/bloc/authentication_bloc.dart'; | |||
| import 'data/repository/authentication_repository.dart'; | |||
| import 'main.dart'; | |||
| import 'common/const_enum.dart'; | |||
| import 'data/repository/auth_repository.dart'; | |||
| import 'string/app_strings.dart'; | |||
| class App extends StatelessWidget { | |||
| final AuthenticationRepository authenticationRepository; | |||
| const App({ | |||
| Key? key, | |||
| required this.authenticationRepository, | |||
| }) : super(key: key); | |||
| final AuthenticationRepository authenticationRepository; | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return RepositoryProvider.value( | |||
| value: authenticationRepository, | |||
| child: BlocProvider( | |||
| create: (_) => AuthenticationBloc( | |||
| repository: authenticationRepository, | |||
| ), | |||
| child: AppView(), | |||
| child: MultiBlocProvider( | |||
| providers: [ | |||
| BlocProvider( | |||
| create: (_) => AuthenticationBloc( | |||
| repository: authenticationRepository, | |||
| ), | |||
| ), | |||
| // BlocProvider( | |||
| // create: (_) => LoginCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => NotificationBloc(Repository()), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => WorkCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => FertilizationCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => InfomationFertilizationCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => WorkDetailCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => CowCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => NoteCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => WorkSlipCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => FertilityCheckupCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => InseminateCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => ReproductiveTreatmentCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => AntenatalCheckupCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => CreateWorkCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => NhapBoCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => NhapBeCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => DanBoBloc(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => GiaPhaCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => ThuYBoBenhCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => KhamBenhCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => DieuTriCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => LichSuDieuTriCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => BoBenhBloc(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => ThanhLyCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => ChangePasswordCubit(), | |||
| // ), | |||
| // BlocProvider( | |||
| // create: (_) => BoBenhThanhLyBloc(), | |||
| // ), | |||
| ], | |||
| child: const AppView(), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| class AppView extends StatefulWidget { | |||
| const AppView({ | |||
| Key? key, | |||
| }) : super(key: key); | |||
| @override | |||
| _AppViewState createState() => _AppViewState(); | |||
| } | |||
| class _AppViewState extends State<AppView> { | |||
| NavigatorState? get _navigator => globalNavigator.currentState; | |||
| // NavigatorState get _navigator => _navigatorKey.currentState!; | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return GetMaterialApp( | |||
| debugShowCheckedModeBanner: false, | |||
| initialRoute: RouteName.home, | |||
| navigatorKey: globalNavigator, | |||
| theme: ThemeData( | |||
| backgroundColor: Colors.white, | |||
| brightness: Brightness.light, | |||
| primaryColor: AppColors.DEFAULT, | |||
| accentColor: AppColors.DEFAULT, | |||
| hoverColor: AppColors.GREEN, | |||
| textTheme: GoogleFonts.sairaTextTheme( | |||
| Theme.of(context).textTheme, | |||
| ), | |||
| ), | |||
| // navigatorKey: _navigatorKey, | |||
| builder: (context, child) { | |||
| // return TabbarScreen(); | |||
| // return LoginPage(); | |||
| return BlocListener<AuthenticationBloc, AuthenticationState>( | |||
| listener: (context, state) { | |||
| switch (state.status) { | |||
| case AuthenticationStatus.authenticated: | |||
| _navigator!.pushAndRemoveUntil<void>( | |||
| TabbarScreen.route(), | |||
| (route) => false, | |||
| ); | |||
| break; | |||
| // _navigator.pushAndRemoveUntil<void>( | |||
| // TabbarScreen.route(), | |||
| // (route) => false, | |||
| // ); | |||
| break; | |||
| case AuthenticationStatus.unauthenticated: | |||
| _navigator!.pushAndRemoveUntil<void>( | |||
| LoginPage.route(), | |||
| (route) => false, | |||
| ); | |||
| // _navigator.pushAndRemoveUntil<void>( | |||
| // LoginPage.route(), | |||
| // (route) => false, | |||
| // ); | |||
| break; | |||
| default: | |||
| _navigator!.pushAndRemoveUntil<void>( | |||
| LoginPage.route(), | |||
| (route) => false, | |||
| ); | |||
| break; | |||
| } | |||
| return ScreenUtilInit( | |||
| designSize: const Size(375, 812), | |||
| minTextAdapt: true, | |||
| splitScreenMode: true, | |||
| builder: (BuildContext context, Widget? child) { | |||
| return GetMaterialApp( | |||
| title: 'Trang Trai Bo', | |||
| debugShowCheckedModeBanner: false, | |||
| onGenerateRoute: Routes.buildRoutes, | |||
| initialRoute: RouteName.splash, | |||
| theme: AppTheme.lightThem, | |||
| localizationsDelegates: [ | |||
| GlobalMaterialLocalizations.delegate, | |||
| GlobalCupertinoLocalizations.delegate, | |||
| GlobalWidgetsLocalizations.delegate, | |||
| ], | |||
| supportedLocales: const [ | |||
| Locale('vi', 'VN'), | |||
| Locale('en', 'US'), | |||
| ], | |||
| locale: const Locale('vi', 'VN'), | |||
| fallbackLocale: const Locale('vi', 'VN'), | |||
| translations: AppStrings(), | |||
| builder: (context, child) { | |||
| final mediaQueryData = MediaQuery.of(context); | |||
| final scale = mediaQueryData.textScaleFactor.clamp(1.0, 1.2); | |||
| FirebaseNotificationService.initService(); | |||
| return MediaQuery( | |||
| data: MediaQuery.of(context).copyWith(textScaleFactor: scale), | |||
| child: BlocListener<AuthenticationBloc, AuthenticationState>( | |||
| listener: (context, state) { | |||
| switch (state.status) { | |||
| case AuthenticationStatus.authenticated: | |||
| Get.offAll(() => TabbarScreen()); | |||
| break; | |||
| case AuthenticationStatus.unauthenticated: | |||
| Get.offAll(() => const LoginPage()); | |||
| break; | |||
| default: | |||
| Get.offAll(() => const LoginPage()); | |||
| break; | |||
| } | |||
| }, | |||
| child: child!, | |||
| ), | |||
| ); | |||
| }, | |||
| child: child, | |||
| ); | |||
| }, | |||
| onGenerateRoute: Routes.buildRoutes, | |||
| ); | |||
| } | |||
| } | |||
| @@ -1 +0,0 @@ | |||
| export 'bloc/authentication_bloc.dart'; | |||
| @@ -1,9 +1,9 @@ | |||
| import 'dart:async'; | |||
| import 'package:bloc/bloc.dart'; | |||
| import 'package:equatable/equatable.dart'; | |||
| import 'package:farm_tpf/data/repository/authentication_repository.dart'; | |||
| import 'package:meta/meta.dart'; | |||
| import '../../common/const_enum.dart'; | |||
| import '../../data/repository/auth_repository.dart'; | |||
| part 'authentication_event.dart'; | |||
| part 'authentication_state.dart'; | |||
| @@ -11,7 +11,11 @@ part 'authentication_state.dart'; | |||
| class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState> { | |||
| AuthenticationBloc({required AuthenticationRepository repository}) | |||
| : _authenticationRepository = repository, | |||
| super(const AuthenticationState.unknown()) {} | |||
| super(const AuthenticationState.unknown()) { | |||
| _authenticationStatusSubscription = _authenticationRepository.status.listen( | |||
| (status) => add(AuthenticationStatusChanged(status)), | |||
| ); | |||
| } | |||
| final AuthenticationRepository _authenticationRepository; | |||
| StreamSubscription<AuthenticationStatus>? _authenticationStatusSubscription; | |||
| @@ -1,9 +1,8 @@ | |||
| part of 'authentication_bloc.dart'; | |||
| abstract class AuthenticationEvent extends Equatable { | |||
| abstract class AuthenticationEvent { | |||
| const AuthenticationEvent(); | |||
| @override | |||
| List<Object> get props => []; | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| part of 'authentication_bloc.dart'; | |||
| class AuthenticationState extends Equatable { | |||
| class AuthenticationState { | |||
| const AuthenticationState._({this.status = AuthenticationStatus.unknown}); | |||
| const AuthenticationState.unknown() : this._(); | |||
| @@ -13,6 +13,5 @@ class AuthenticationState extends Equatable { | |||
| final AuthenticationStatus status; | |||
| @override | |||
| List<Object> get props => [status]; | |||
| } | |||
| @@ -0,0 +1,5 @@ | |||
| enum AuthenticationStatus { | |||
| unknown, | |||
| unauthenticated, | |||
| authenticated, | |||
| } | |||
| @@ -11,24 +11,12 @@ class AppException { | |||
| try { | |||
| var dioError = error as DioError; | |||
| switch (dioError.type) { | |||
| case DioErrorType.CANCEL: | |||
| errorDescription = exception_dio_cancle; | |||
| break; | |||
| case DioErrorType.CONNECT_TIMEOUT: | |||
| errorDescription = exception_dio_connect_timeout; | |||
| break; | |||
| case DioErrorType.DEFAULT: | |||
| errorDescription = exception_dio_default; | |||
| break; | |||
| case DioErrorType.RECEIVE_TIMEOUT: | |||
| errorDescription = exception_dio_receive_timeout; | |||
| break; | |||
| case DioErrorType.RESPONSE: | |||
| int statusCode = dioError.response.statusCode; | |||
| case DioErrorType.response: | |||
| int statusCode = dioError.response?.statusCode ?? 0; | |||
| if (statusCode == 400) { | |||
| errorDescription = customMessageError ?? exception_dio_400; | |||
| try { | |||
| Map<String, dynamic> errorMap = jsonDecode(dioError.response.data); | |||
| Map<String, dynamic> errorMap = jsonDecode(dioError.response?.data); | |||
| var errorCode = ErrorCommon.fromJson(errorMap).errorKey; | |||
| switch (errorCode) { | |||
| @@ -116,8 +104,20 @@ class AppException { | |||
| errorDescription = exception_common; | |||
| } | |||
| break; | |||
| case DioErrorType.SEND_TIMEOUT: | |||
| errorDescription = exception_dio_send_timeout; | |||
| case DioErrorType.connectTimeout: | |||
| // TODO: Handle this case. | |||
| break; | |||
| case DioErrorType.sendTimeout: | |||
| // TODO: Handle this case. | |||
| break; | |||
| case DioErrorType.receiveTimeout: | |||
| // TODO: Handle this case. | |||
| break; | |||
| case DioErrorType.cancel: | |||
| // TODO: Handle this case. | |||
| break; | |||
| case DioErrorType.other: | |||
| // TODO: Handle this case. | |||
| break; | |||
| } | |||
| } catch (e) { | |||
| @@ -1,50 +1,59 @@ | |||
| import 'dart:convert'; | |||
| import 'dart:developer'; | |||
| import 'dart:io'; | |||
| import 'package:dio/dio.dart'; | |||
| import 'package:dio_http_cache/dio_http_cache.dart'; | |||
| import 'package:farm_tpf/utils/const_common.dart'; | |||
| import 'package:farm_tpf/utils/pref.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import '../../authentication/bloc/authentication_bloc.dart'; | |||
| import '../../common/const_enum.dart'; | |||
| import '../../main.dart'; | |||
| import '../../utils/local_storage.dart'; | |||
| class DioProvider { | |||
| static Dio dio = Dio(); | |||
| static Dio instance() { | |||
| final dio = Dio(); | |||
| // dio.interceptors.add(AuthInterceptor()); | |||
| dio.interceptors.add(HttpLogInterceptor()); | |||
| dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: ConstCommon.baseUrl)).interceptor); | |||
| dio.options.baseUrl = 'https://tpf.aztrace.vn/'; | |||
| // (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (HttpClient client) { | |||
| // client.badCertificateCallback = (X509Certificate cert, String host, int port) => true; | |||
| // return client; | |||
| // }; | |||
| dio.interceptors.add( | |||
| InterceptorsWrapper( | |||
| onRequest: (options, handler) { | |||
| var token = LocalStorage.getString(LocalStorageKey.access_token); | |||
| if (token.isNotEmpty) { | |||
| options.headers['Authorization'] = 'Bearer $token'; | |||
| } | |||
| options.headers['Content-Type'] = 'application/json'; | |||
| options.headers['accept'] = 'application/json'; | |||
| log('⭐⭐⭐⭐⭐⭐ onRequest: ${options.uri}\n' | |||
| 'data=${options.data}\n' | |||
| 'method=${options.method}\n' | |||
| 'headers=${options.headers}\n' | |||
| 'queryParameters=${options.queryParameters}'); | |||
| return handler.next(options); | |||
| }, | |||
| onResponse: (response, handler) async { | |||
| // log('🍏🍏🍏🍏🍏🍏 onResponse: $response'); | |||
| return handler.next(response); | |||
| }, | |||
| onError: (DioError e, handler) async { | |||
| log('🔥🔥🔥🔥🔥🔥 onError: $e\n' | |||
| 'Response: ${e.response}'); | |||
| handler.next(e); | |||
| }, | |||
| ), | |||
| ); | |||
| return dio; | |||
| } | |||
| } | |||
| class HttpLogInterceptor extends InterceptorsWrapper { | |||
| var pref = LocalPref(); | |||
| @override | |||
| Future onRequest(RequestOptions options) async { | |||
| var token = await pref.getString(DATA_CONST.TOKEN_KEY); | |||
| // options.headers["Authorization"] = "Bearer $token"; | |||
| options.headers["Authorization"] = | |||
| "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsZWNhb2FuaHF1b2MiLCJhdXRoIjoiUk9MRV9VU0VSIiwiZXhwIjoxNjc4ODk1MTIyfQ.jj3RbPZ4Q1yL9ImFGEPsJyy9SCVe7SKDw5vzHu6no2eUpWg78KVzEypY8W51VzrRa9gV04Yhp_l3YvEe8lsttQ"; | |||
| options.receiveTimeout = 20000; | |||
| log("onRequest: ${options.uri}\n" | |||
| "data=${options.data}\n" | |||
| "method=${options.method}\n" | |||
| "headers=${options.headers}\n" | |||
| "queryParameters=${options.queryParameters}"); | |||
| return options; | |||
| } | |||
| @override | |||
| Future onResponse(Response response) { | |||
| log("onResponse: $response"); | |||
| return super.onResponse(response); | |||
| } | |||
| @override | |||
| Future onError(DioError err) { | |||
| log("onError: $err\n" | |||
| "Response: ${err.response}"); | |||
| return super.onError(err); | |||
| static void logoutAndNavigationToSplashScreen() { | |||
| LocalStorage.clearUserInfo(); | |||
| BlocProvider.of<AuthenticationBloc>(globalNavigator.currentContext!).add( | |||
| const AuthenticationStatusChanged( | |||
| AuthenticationStatus.unauthenticated, | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -23,11 +23,8 @@ class _RestClient implements RestClient { | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = <String, dynamic>{}; | |||
| _data.addAll(userRequest?.toJson() ?? <String, dynamic>{}); | |||
| final Response<Map<String, dynamic>> _result = await _dio.request('/api/authenticate', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| final value = User.fromJson(_result.data); | |||
| final Response<Map<String, dynamic>> _result = await _dio.request('/api/authenticate', queryParameters: queryParameters, data: _data); | |||
| final value = User.fromJson(_result.data!); | |||
| return value; | |||
| } | |||
| @@ -36,11 +33,8 @@ class _RestClient implements RestClient { | |||
| const _extra = <String, dynamic>{}; | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = <String, dynamic>{}; | |||
| final Response<Map<String, dynamic>> _result = await _dio.request('/api/account', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| final value = Account.fromJson(_result.data); | |||
| final Response<Map<String, dynamic>> _result = await _dio.request('/api/account', queryParameters: queryParameters, data: _data); | |||
| final value = Account.fromJson(_result.data ?? Map<String, dynamic>()); | |||
| return value; | |||
| } | |||
| @@ -50,10 +44,11 @@ class _RestClient implements RestClient { | |||
| const _extra = <String, dynamic>{}; | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = email; | |||
| await _dio.request<void>('/api/account/reset-password/init', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| await _dio.request<void>( | |||
| '/api/account/reset-password/init', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| return null; | |||
| } | |||
| @@ -63,11 +58,8 @@ class _RestClient implements RestClient { | |||
| const _extra = <String, dynamic>{}; | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = <String, dynamic>{}; | |||
| _data.addAll(password?.toJson() ?? <String, dynamic>{}); | |||
| await _dio.request<void>('/api/account/reset-password/finish', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| _data.addAll(password.toJson() ?? <String, dynamic>{}); | |||
| await _dio.request<void>('/api/account/reset-password/finish', queryParameters: queryParameters, data: _data); | |||
| return null; | |||
| } | |||
| @@ -78,10 +70,11 @@ class _RestClient implements RestClient { | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = <String, dynamic>{}; | |||
| _data.addAll(password?.toJson() ?? <String, dynamic>{}); | |||
| await _dio.request<void>('/api/account/change-password', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| await _dio.request<void>( | |||
| '/api/account/change-password', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| return null; | |||
| } | |||
| @@ -92,11 +85,8 @@ class _RestClient implements RestClient { | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = <String, dynamic>{}; | |||
| _data.addAll(account?.toJson() ?? <String, dynamic>{}); | |||
| final Response<Map<String, dynamic>> _result = await _dio.request('/api/update-my-profile', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| final value = Account.fromJson(_result.data); | |||
| final Response<Map<String, dynamic>> _result = await _dio.request('/api/update-my-profile', queryParameters: queryParameters, data: _data); | |||
| final value = Account.fromJson(_result.data ?? Map<String, dynamic>()); | |||
| return value; | |||
| } | |||
| @@ -110,10 +100,13 @@ class _RestClient implements RestClient { | |||
| final newOptions = newRequestOptions(options ?? Options()); | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/list-supplies-in-warehouses/$type?q=$query', | |||
| queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data); | |||
| var value = _result.data.map((dynamic i) => Supply.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/list-supplies-in-warehouses/$type?q=$query', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => Supply.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -122,10 +115,11 @@ class _RestClient implements RestClient { | |||
| const _extra = <String, dynamic>{}; | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = token; | |||
| await _dio.request<void>('/api/update-fcmToken', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| await _dio.request<void>( | |||
| '/api/update-fcmToken', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| return null; | |||
| } | |||
| @@ -135,10 +129,11 @@ class _RestClient implements RestClient { | |||
| const _extra = <String, dynamic>{}; | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = token; | |||
| await _dio.request<void>('/api/delete-fcmToken', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| await _dio.request<void>( | |||
| '/api/delete-fcmToken', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| return null; | |||
| } | |||
| @@ -148,12 +143,13 @@ class _RestClient implements RestClient { | |||
| final queryParameters = <String, dynamic>{}; | |||
| queryParameters.removeWhere((k, v) => v == null); | |||
| final _data = <String, dynamic>{}; | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/_search/tb-crops?page=$page&size=$size&sort=id,asc&query=$query', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| var value = _result.data.map((dynamic i) => Crop.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/_search/tb-crops?page=$page&size=$size&sort=id,asc&query=$query', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => Crop.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -165,10 +161,13 @@ class _RestClient implements RestClient { | |||
| final newOptions = newRequestOptions(options ?? Options()); | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/listActivityTypesOther', | |||
| queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data); | |||
| var value = _result.data.map((dynamic i) => ActionType.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/listActivityTypesOther', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => ActionType.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -180,10 +179,13 @@ class _RestClient implements RestClient { | |||
| final newOptions = newRequestOptions(options ?? Options()); | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/water-types', | |||
| queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data); | |||
| var value = _result.data.map((dynamic i) => WaterType.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/water-types', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => WaterType.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -195,10 +197,13 @@ class _RestClient implements RestClient { | |||
| final newOptions = newRequestOptions(options ?? Options()); | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/tb-harvests', | |||
| queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data); | |||
| var value = _result.data.map((dynamic i) => Harvest.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/tb-harvests', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => Harvest.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -210,10 +215,13 @@ class _RestClient implements RestClient { | |||
| final newOptions = newRequestOptions(options ?? Options()); | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/listDeviceForActivity', | |||
| queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data); | |||
| var value = _result.data.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/listDeviceForActivity', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -222,10 +230,11 @@ class _RestClient implements RestClient { | |||
| const _extra = <String, dynamic>{}; | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = status; | |||
| await _dio.request<void>('/api/notifications/update-all', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| await _dio.request<void>( | |||
| '/api/notifications/update-all', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| return null; | |||
| } | |||
| @@ -236,10 +245,11 @@ class _RestClient implements RestClient { | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = <String, dynamic>{}; | |||
| _data.addAll(updateNoti?.toJson() ?? <String, dynamic>{}); | |||
| await _dio.request<void>('/api/notifications/update', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| await _dio.request<void>( | |||
| '/api/notifications/update', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| return null; | |||
| } | |||
| @@ -252,10 +262,13 @@ class _RestClient implements RestClient { | |||
| final newOptions = newRequestOptions(options ?? Options()); | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/tb-countries?page=$page&size=$size&query=$query&&sort=name,ASC', | |||
| queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data); | |||
| var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/tb-countries?page=$page&size=$size&query=$query&&sort=name,ASC', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -269,12 +282,12 @@ class _RestClient implements RestClient { | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/tb-cities-by-country/$countryId?page=$page&size=$size&query=$query&&sort=name,ASC', | |||
| queryParameters: queryParameters, | |||
| options: newOptions.merge(method: 'GET', baseUrl: baseUrl), | |||
| data: _data); | |||
| var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| '/api/tb-cities-by-country/$countryId?page=$page&size=$size&query=$query&&sort=name,ASC', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -288,12 +301,12 @@ class _RestClient implements RestClient { | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/tb-districts-by-city/$provinceId?page=$page&size=$size&query=$query&&sort=name,ASC', | |||
| queryParameters: queryParameters, | |||
| options: newOptions.merge(method: 'GET', baseUrl: baseUrl), | |||
| data: _data); | |||
| var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| '/api/tb-districts-by-city/$provinceId?page=$page&size=$size&query=$query&&sort=name,ASC', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -307,12 +320,12 @@ class _RestClient implements RestClient { | |||
| newOptions.extra.addAll(_extra); | |||
| newOptions.headers.addAll(<String, dynamic>{}); | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/tb-wards-by-district/$districtId?page=$page&size=$size&query=$query&&sort=name,ASC', | |||
| queryParameters: queryParameters, | |||
| options: newOptions.merge(method: 'GET', baseUrl: baseUrl), | |||
| data: _data); | |||
| var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| '/api/tb-wards-by-district/$districtId?page=$page&size=$size&query=$query&&sort=name,ASC', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -323,11 +336,11 @@ class _RestClient implements RestClient { | |||
| queryParameters.removeWhere((k, v) => v == null); | |||
| final _data = <String, dynamic>{}; | |||
| final Response<Map<String, dynamic>> _result = await _dio.request( | |||
| '/api/tb-crops-detail-for-app/$cropId?page=$page&size=$size&sort=executeDate,DESC', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| final value = CropPlot.fromJson(_result.data); | |||
| '/api/tb-crops-detail-for-app/$cropId?page=$page&size=$size&sort=executeDate,DESC', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| final value = CropPlot.fromJson(_result.data ?? Map<String, dynamic>()); | |||
| return value; | |||
| } | |||
| @@ -339,11 +352,11 @@ class _RestClient implements RestClient { | |||
| queryParameters.removeWhere((k, v) => v == null); | |||
| final _data = <String, dynamic>{}; | |||
| final Response<Map<String, dynamic>> _result = await _dio.request( | |||
| '/api/tb-crops-scan-qrCode/$cropCode?page=$page&size=$size&sort=executeDate,DESC', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| final value = CropPlot.fromJson(_result.data); | |||
| '/api/tb-crops-scan-qrCode/$cropCode?page=$page&size=$size&sort=executeDate,DESC', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| final value = CropPlot.fromJson(_result.data ?? Map<String, dynamic>()); | |||
| return value; | |||
| } | |||
| @@ -354,10 +367,11 @@ class _RestClient implements RestClient { | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = <String, dynamic>{}; | |||
| _data.addAll(crop?.toJson() ?? <String, dynamic>{}); | |||
| await _dio.request<void>('/api/tb-crops', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| await _dio.request<void>( | |||
| '/api/tb-crops', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| return null; | |||
| } | |||
| @@ -366,12 +380,10 @@ class _RestClient implements RestClient { | |||
| const _extra = <String, dynamic>{}; | |||
| final queryParameters = <String, dynamic>{}; | |||
| final _data = <String, dynamic>{}; | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/listDeviceOfUserCustomers?query=$query', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| var value = _result.data.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = | |||
| await _dio.request('/api/listDeviceOfUserCustomers?query=$query', queryParameters: queryParameters, data: _data); | |||
| var value = _result.data?.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| @override | |||
| @@ -381,20 +393,22 @@ class _RestClient implements RestClient { | |||
| final queryParameters = <String, dynamic>{}; | |||
| queryParameters.removeWhere((k, v) => v == null); | |||
| final _data = <String, dynamic>{}; | |||
| final Response<List<dynamic>> _result = await _dio.request('/api/list-environment-updates-display/$cropId?page=$page&size=$size', | |||
| queryParameters: queryParameters, | |||
| options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl), | |||
| data: _data); | |||
| var value = _result.data.map((dynamic i) => EnvironmentParameter.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value; | |||
| final Response<List<dynamic>> _result = await _dio.request( | |||
| '/api/list-environment-updates-display/$cropId?page=$page&size=$size', | |||
| queryParameters: queryParameters, | |||
| data: _data, | |||
| ); | |||
| var value = _result.data?.map((dynamic i) => EnvironmentParameter.fromJson(i as Map<String, dynamic>)).toList(); | |||
| return value ?? []; | |||
| } | |||
| RequestOptions newRequestOptions(Options options) { | |||
| if (options is RequestOptions) { | |||
| return options; | |||
| } | |||
| RequestOptions newRequestOptions(Options? options) { | |||
| // if (options is RequestOptions) { | |||
| // // return options ?? RequestOptions(path: ''); | |||
| // return RequestOptions!; | |||
| // } | |||
| if (options == null) { | |||
| return RequestOptions(); | |||
| return RequestOptions(path: ''); | |||
| } | |||
| return RequestOptions( | |||
| method: options.method, | |||
| @@ -410,6 +424,7 @@ class _RestClient implements RestClient { | |||
| maxRedirects: options.maxRedirects, | |||
| requestEncoder: options.requestEncoder, | |||
| responseDecoder: options.responseDecoder, | |||
| path: '', | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,43 @@ | |||
| import 'dart:async'; | |||
| import '../../common/const_enum.dart'; | |||
| import '../../utils/local_storage.dart'; | |||
| class AuthenticationRepository { | |||
| final _controller = StreamController<AuthenticationStatus>(); | |||
| Stream<AuthenticationStatus> get status async* { | |||
| var status = await checkAuthStatus(); | |||
| switch (status) { | |||
| case AuthenticationStatus.authenticated: | |||
| yield AuthenticationStatus.authenticated; | |||
| break; | |||
| case AuthenticationStatus.unauthenticated: | |||
| yield AuthenticationStatus.unauthenticated; | |||
| break; | |||
| default: | |||
| yield AuthenticationStatus.unauthenticated; | |||
| break; | |||
| } | |||
| yield* _controller.stream; | |||
| } | |||
| Future<AuthenticationStatus> checkAuthStatus() async { | |||
| try { | |||
| var isLogged = LocalStorage.getBool(LocalStorageKey.is_logged); | |||
| if (isLogged) { | |||
| return AuthenticationStatus.authenticated; | |||
| } else { | |||
| return AuthenticationStatus.unauthenticated; | |||
| } | |||
| } catch (_) { | |||
| return AuthenticationStatus.unauthenticated; | |||
| } | |||
| } | |||
| void logOut() { | |||
| LocalStorage.clearUserInfo(); | |||
| _controller.add(AuthenticationStatus.unauthenticated); | |||
| } | |||
| void dispose() => _controller.close(); | |||
| } | |||
| @@ -1,55 +0,0 @@ | |||
| import 'dart:async'; | |||
| import 'package:farm_tpf/custom_model/user.dart'; | |||
| import 'package:farm_tpf/custom_model/user_request.dart'; | |||
| import 'package:farm_tpf/data/api/dio_provider.dart'; | |||
| import 'package:farm_tpf/data/api/rest_client.dart'; | |||
| import 'package:farm_tpf/utils/const_common.dart'; | |||
| import 'package:farm_tpf/utils/pref.dart'; | |||
| enum AuthenticationStatus { unknown, authenticated, unauthenticated } | |||
| class AuthenticationRepository { | |||
| final _controller = StreamController<AuthenticationStatus>(); | |||
| final dio = DioProvider.instance(); | |||
| final pref = LocalPref(); | |||
| Stream<AuthenticationStatus> get status async* { | |||
| try { | |||
| var token = await pref.getString(DATA_CONST.TOKEN_KEY); | |||
| var expiredTime = await pref.getString(DATA_CONST.EXPIRED_TIME); | |||
| var currentTime = DateTime.now().millisecondsSinceEpoch; | |||
| var isNotExpired = (currentTime - (int.tryParse(expiredTime) ?? 0)) < ConstCommon.kExpiredTime; | |||
| if (token.isNotEmpty && isNotExpired) { | |||
| yield AuthenticationStatus.authenticated; | |||
| } else { | |||
| yield AuthenticationStatus.unauthenticated; | |||
| } | |||
| } catch (_) { | |||
| yield AuthenticationStatus.unauthenticated; | |||
| } | |||
| yield* _controller.stream; | |||
| } | |||
| Future<User> signInWithCredentials(String username, String password) async { | |||
| final client = RestClient(dio); | |||
| try { | |||
| var url = 'https://tpf.aztrace.vn/api/authenticate'; | |||
| var res = await dio.post(url, data: UserRequest(username: username, password: password)); | |||
| var user = User.fromJson(res.data); | |||
| return user; | |||
| // return ResponseUser.fromJson(res.data); | |||
| } catch (e) { | |||
| rethrow; | |||
| } | |||
| // var result = client.login(UserRequest(username: username, password: password)); | |||
| // return result; | |||
| } | |||
| void logOut() { | |||
| _controller.add(AuthenticationStatus.unauthenticated); | |||
| } | |||
| void dispose() => _controller.close(); | |||
| } | |||
| @@ -1,5 +1,4 @@ | |||
| import 'package:dio/dio.dart'; | |||
| import 'package:dio_http_cache/dio_http_cache.dart'; | |||
| import 'package:farm_tpf/custom_model/CropPlot.dart'; | |||
| import 'package:farm_tpf/custom_model/Device.dart'; | |||
| import 'package:farm_tpf/custom_model/EnvironmentParameter.dart'; | |||
| @@ -18,25 +17,54 @@ import 'package:farm_tpf/models/index.dart'; | |||
| import 'package:farm_tpf/utils/const_common.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import '../../environment/app_config.dart'; | |||
| import '../../presentation/screens/login/models/request_user.dart'; | |||
| import '../../presentation/screens/login/models/response_user.dart'; | |||
| class Repository { | |||
| final dio = DioProvider.instance(); | |||
| Future<void> login( | |||
| Function(ResponseUser) onSuccess, | |||
| Function(String) onError, { | |||
| required RequestUser requestUser, | |||
| }) async { | |||
| try { | |||
| var url = FlavorConfig.values.baseUrl + '/api/authenticate'; | |||
| await dio.post( | |||
| url, | |||
| data: { | |||
| 'username': requestUser.username ?? '', | |||
| 'password': requestUser.password ?? '', | |||
| }, | |||
| ).then( | |||
| (value) { | |||
| var res = ResponseUser.fromJson(value.data); | |||
| onSuccess(res); | |||
| }, | |||
| ).catchError((error) { | |||
| var dioError = error as DioError; | |||
| var message = dioError.response?.data['Error']; | |||
| onError(message); | |||
| }); | |||
| } catch (e) { | |||
| onError('Đã có lỗi xảy ra'); | |||
| } | |||
| } | |||
| Future<List<ActionType>> getActionTypes() { | |||
| final client = RestClient(dio); | |||
| var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache)); | |||
| return client.getActionTypes(options: op); | |||
| return client.getActionTypes(); | |||
| } | |||
| Future<List<Harvest>> getHarvests() { | |||
| final client = RestClient(dio); | |||
| var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache)); | |||
| return client.getHarvests(options: op); | |||
| return client.getHarvests(); | |||
| } | |||
| Future<List<WaterType>> getWaterTypes() { | |||
| final client = RestClient(dio); | |||
| var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache)); | |||
| return client.getWaterTypes(options: op); | |||
| return client.getWaterTypes(); | |||
| } | |||
| Future<CropPlot> getPlotDetail(int cropId, {int page = 0, int size = 20}) { | |||
| @@ -75,14 +103,15 @@ class Repository { | |||
| Future<List<Supply>> getSupplies(String type, {String query = ""}) async { | |||
| final client = RestClient(dio); | |||
| var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache)); | |||
| return client.getSupplies(type, query: query, options: op); | |||
| return client.getSupplies( | |||
| type, | |||
| query: query, | |||
| ); | |||
| } | |||
| Future<List<Device>> getDeviceForActivity() async { | |||
| final client = RestClient(dio); | |||
| var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache)); | |||
| return client.getDeviceForActivity(options: op); | |||
| return client.getDeviceForActivity(); | |||
| } | |||
| Future<void> updateAllNotification(String status) { | |||
| @@ -106,17 +135,16 @@ class Repository { | |||
| Future<List<LocationUnit>> getLocationUnits( | |||
| {required LocationType locationType, required int filterId, int page = 0, int size = 500, String query = ''}) { | |||
| final client = RestClient(dio); | |||
| var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache)); | |||
| var response; | |||
| switch (locationType) { | |||
| case LocationType.province: | |||
| response = client.getProvinces(filterId, options: op, page: page, size: size, query: query); | |||
| response = client.getProvinces(filterId, page: page, size: size, query: query); | |||
| break; | |||
| case LocationType.district: | |||
| response = client.getDistricts(filterId, options: op, page: page, size: size, query: query); | |||
| response = client.getDistricts(filterId, page: page, size: size, query: query); | |||
| break; | |||
| case LocationType.ward: | |||
| response = client.getWards(filterId, options: op, page: page, size: size, query: query); | |||
| response = client.getWards(filterId, page: page, size: size, query: query); | |||
| break; | |||
| default: | |||
| response = client.getCountries(query: query); | |||
| @@ -0,0 +1,67 @@ | |||
| import 'app_environment.dart'; | |||
| class FlavorValues { | |||
| FlavorValues({ | |||
| required this.server, | |||
| required this.baseUrl, | |||
| required this.appName, | |||
| required this.LocalDBName, | |||
| }); | |||
| final String server; | |||
| final String baseUrl; | |||
| final String appName; | |||
| final String LocalDBName; | |||
| } | |||
| abstract class FlavorConfig { | |||
| static AppEnvironment? _flavor; | |||
| static FlavorValues? _values; | |||
| static void set(AppEnvironment flavor, FlavorValues values) { | |||
| _flavor = flavor; | |||
| _values = values; | |||
| } | |||
| static bool isInitialized() => _flavor != null; | |||
| static bool isDev() => _flavor! == AppEnvironment.DEV; | |||
| static bool isProduction() => _flavor! == AppEnvironment.PROD; | |||
| static FlavorValues get values => _values!; | |||
| } | |||
| void setFlavorDevelopment() { | |||
| FlavorConfig.set( | |||
| AppEnvironment.DEV, | |||
| FlavorValues( | |||
| appName: 'LaFarm', | |||
| server: 'https://tpf.aztrace.vn', | |||
| baseUrl: 'https://tpf.aztrace.vn', | |||
| LocalDBName: 'AppLocalStorage', | |||
| ), | |||
| ); | |||
| } | |||
| void setFlavorOutsourceDevelopment() { | |||
| FlavorConfig.set( | |||
| AppEnvironment.DEV, | |||
| FlavorValues( | |||
| appName: 'LaFarm', | |||
| server: 'https://tpf.aztrace.vn/', | |||
| baseUrl: 'https://tpf.aztrace.vn/', | |||
| LocalDBName: 'AppLocalStorage', | |||
| ), | |||
| ); | |||
| } | |||
| void setFlavorProduction() { | |||
| FlavorConfig.set( | |||
| AppEnvironment.PROD, | |||
| FlavorValues( | |||
| appName: 'Trang Trai Bo', | |||
| server: 'https://test-trangtraibo.aristqnu.com/', | |||
| baseUrl: 'https://test-trangtraibo.aristqnu.com/', | |||
| LocalDBName: 'AppLocalStorage', | |||
| ), | |||
| ); | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| enum AppEnvironment { | |||
| DEV, | |||
| PROD, | |||
| } | |||
| @@ -1,115 +1,39 @@ | |||
| // import 'package:barcode_scan/barcode_scan.dart'; | |||
| import 'package:camera/camera.dart'; | |||
| import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart'; | |||
| import 'dart:io'; | |||
| import 'package:firebase_core/firebase_core.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter/services.dart'; | |||
| import 'package:get/route_manager.dart'; | |||
| import 'package:hive/hive.dart'; | |||
| import 'package:path_provider/path_provider.dart'; | |||
| import 'app.dart'; | |||
| import 'data/repository/authentication_repository.dart'; | |||
| import 'data/repository/repository.dart'; | |||
| import 'presentation/custom_widgets/widget_utils.dart'; | |||
| import 'data/repository/auth_repository.dart'; | |||
| import 'environment/app_config.dart'; | |||
| final GlobalKey<NavigatorState> globalNavigator = GlobalKey<NavigatorState>(); | |||
| // List<CameraDescription> cameras = []; | |||
| Future<void> main() async { | |||
| // Fetch the available cameras before initializing the app. | |||
| // try { | |||
| // WidgetsFlutterBinding.ensureInitialized(); | |||
| // // cameras = await availableCameras(); | |||
| // } on CameraException catch (e) { | |||
| // print(e.description); | |||
| // } | |||
| WidgetsFlutterBinding.ensureInitialized(); | |||
| runApp(App(authenticationRepository: AuthenticationRepository())); | |||
| // runApp(MaterialApp( | |||
| // home: Scaffold( | |||
| // appBar: AppBar(), | |||
| // body: Container( | |||
| // color: Colors.red, | |||
| // // width: 100, | |||
| // // height: 100, | |||
| // ), | |||
| // ), | |||
| // )); | |||
| } | |||
| void myBackgroundMessageHandler(Map<String, dynamic> message) { | |||
| if (message.containsKey('data')) { | |||
| // Handle data message | |||
| final dynamic data = message['data']; | |||
| } | |||
| if (message.containsKey('notification')) { | |||
| // Handle notification message | |||
| final dynamic notification = message['notification']; | |||
| } | |||
| // Or do other work. | |||
| } | |||
| Future scan(BuildContext context) async { | |||
| print('scan QR'); | |||
| // var _aspectTolerance = 0.00; | |||
| // var _selectedCamera = -1; | |||
| // var _useAutoFocus = true; | |||
| // var _autoEnableFlash = false; | |||
| // var repository = Repository(); | |||
| // try { | |||
| // var options = ScanOptions( | |||
| // strings: { | |||
| // "cancel": "Huỷ", | |||
| // "flash_on": "Bật flash", | |||
| // "flash_off": "Tắt flash", | |||
| // }, | |||
| // useCamera: _selectedCamera, | |||
| // autoEnableFlash: _autoEnableFlash, | |||
| // android: AndroidOptions( | |||
| // aspectTolerance: _aspectTolerance, | |||
| // useAutoFocus: _useAutoFocus, | |||
| // ), | |||
| Firebase.initializeApp(); | |||
| // if (Platform.isAndroid) { | |||
| // await Firebase.initializeApp( | |||
| // options: DefaultFirebaseOptions.currentPlatform, | |||
| // ); | |||
| // var result = await BarcodeScanner.scan(options: options); | |||
| // print(result.toString()); | |||
| // if (result.type == ResultType.Cancelled) { | |||
| // print("canncel"); | |||
| // } else if (result.type == ResultType.Error) { | |||
| // print("error"); | |||
| // } else { | |||
| // print("show check crop"); | |||
| // _showAlertCheckCropCode(context, result.rawContent, repository); | |||
| // } | |||
| // } on PlatformException catch (e) { | |||
| // print("error: ${e.message}"); | |||
| // } else { | |||
| // await Firebase.initializeApp(); | |||
| // } | |||
| } | |||
| // await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(alert: true, badge: true, sound: true); | |||
| // FirebaseMessaging.onBackgroundMessage(FirebaseMessages.firebaseMessagingBackgroundHandler); | |||
| // FirebaseMessaging.onMessageOpenedApp.listen(FirebaseMessages.firebaseMessagingBackgroundHandler); | |||
| // _showAlertCheckCropCode(BuildContext context, String cropCode, Repository repository) async { | |||
| // Get.defaultDialog(title: "Kiểm tra thông tin lô ....", middleText: "", content: const CircularProgressIndicator()); | |||
| // try { | |||
| // await repository.getPlotDetailByCode(cropCode, page: 1, size: 1).then((value) { | |||
| // print("ok"); | |||
| // if (Get.isDialogOpen) Get.back(); | |||
| // Get.to(PlotDetailScreen(cropId: value.tbCropDTO?.id ?? -1, cropType: value.tbCropDTO?.type ?? -1, initialIndex: 0)); | |||
| // }).catchError((onError) { | |||
| // Utils.showDialog( | |||
| // title: "Không tìm thấy lô", | |||
| // message: "Thử lại với mã tem khác?", | |||
| // textConfirm: "Thử lại", | |||
| // textCancel: "Huỷ", | |||
| // onConfirm: () { | |||
| // Get.back(); | |||
| // scan(context); | |||
| // }); | |||
| // }); | |||
| // } catch (e) { | |||
| // Utils.showDialog( | |||
| // title: "Không tìm thấy lô", | |||
| // message: "Thử lại với mã tem khác?", | |||
| // textConfirm: "Thử lại", | |||
| // textCancel: "Huỷ", | |||
| // onConfirm: () { | |||
| // Get.back(); | |||
| // scan(context); | |||
| // }); | |||
| // } | |||
| // } | |||
| await SystemChrome.setPreferredOrientations([ | |||
| DeviceOrientation.portraitDown, | |||
| DeviceOrientation.portraitUp, | |||
| ]); | |||
| setFlavorDevelopment(); | |||
| final appDocumentDirectory = await getApplicationDocumentsDirectory(); | |||
| Hive..init(appDocumentDirectory.path); | |||
| await Hive.openBox('LocalDBName'); | |||
| runApp(App( | |||
| authenticationRepository: AuthenticationRepository(), | |||
| )); | |||
| } | |||
| @@ -0,0 +1,5 @@ | |||
| class ItemDropDown { | |||
| String? key; | |||
| String? value; | |||
| ItemDropDown({this.key, this.value}); | |||
| } | |||
| @@ -0,0 +1,36 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_svg/svg.dart'; | |||
| import '../../../themes/app_colors.dart'; | |||
| import '../../../utils/app_images.dart'; | |||
| class FloatButtonWidget extends StatelessWidget { | |||
| final Function onPressed; | |||
| final String? icon; | |||
| const FloatButtonWidget({ | |||
| Key? key, | |||
| required this.onPressed, | |||
| this.icon, | |||
| }) : super(key: key); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return InkWell( | |||
| onTap: () { | |||
| onPressed(); | |||
| }, | |||
| child: Container( | |||
| width: 52, | |||
| height: 52, | |||
| decoration: BoxDecoration( | |||
| borderRadius: BorderRadius.circular(52), | |||
| color: AppColors.primary2, | |||
| ), | |||
| padding: const EdgeInsets.all(14), | |||
| child: SvgPicture.asset( | |||
| icon ?? AssetSVG.icAddCircle, | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,28 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import '../../../themes/app_colors.dart'; | |||
| import '../../../themes/styles_text.dart'; | |||
| class GhostButtonWidget extends StatelessWidget { | |||
| final String title; | |||
| final Function() onPressed; | |||
| final Color? color; | |||
| const GhostButtonWidget({ | |||
| required this.title, | |||
| required this.onPressed, | |||
| this.color, | |||
| }); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return InkWell( | |||
| onTap: onPressed, | |||
| child: Text( | |||
| title, | |||
| style: StylesText.body3.copyWith( | |||
| color: color ?? AppColors.black, | |||
| decoration: TextDecoration.underline, | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,64 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import '../../../themes/app_dimension.dart'; | |||
| import '../../../themes/app_colors.dart'; | |||
| import '../../../themes/styles_text.dart'; | |||
| class PrimaryButtonWidget extends StatelessWidget { | |||
| final String title; | |||
| final double width; | |||
| final double? height; | |||
| final bool isEnable; | |||
| final Function() onPressed; | |||
| final Color? color; | |||
| final Color? titleColor; | |||
| const PrimaryButtonWidget({ | |||
| required this.title, | |||
| required this.onPressed, | |||
| this.width = double.infinity, | |||
| this.isEnable = true, | |||
| this.color, | |||
| this.height, | |||
| this.titleColor, | |||
| }); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return SizedBox( | |||
| width: width, | |||
| height: height ?? 45.h, | |||
| child: ElevatedButton( | |||
| onPressed: isEnable ? onPressed : null, | |||
| style: ButtonStyle( | |||
| backgroundColor: MaterialStateProperty.resolveWith( | |||
| (states) { | |||
| if (states.contains(MaterialState.disabled)) { | |||
| return AppColors.neutral4; | |||
| } | |||
| return color ?? AppColors.primary1; | |||
| }, | |||
| ), | |||
| shadowColor: MaterialStateProperty.resolveWith( | |||
| (states) { | |||
| return Colors.transparent; | |||
| }, | |||
| ), | |||
| overlayColor: MaterialStateProperty.resolveWith( | |||
| (states) { | |||
| return Colors.transparent; | |||
| }, | |||
| ), | |||
| shape: MaterialStateProperty.all<RoundedRectangleBorder>( | |||
| RoundedRectangleBorder( | |||
| borderRadius: BorderRadius.circular(12.0), | |||
| ), | |||
| ), | |||
| ), | |||
| child: Text( | |||
| title, | |||
| style: StylesText.body5.copyWith( | |||
| color: titleColor ?? AppColors.white, | |||
| ), | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -39,7 +39,14 @@ class ButtonIconWidget extends StatelessWidget { | |||
| child: Row( | |||
| mainAxisSize: MainAxisSize.max, | |||
| children: [ | |||
| leadingIcon == null ? const SizedBox() : SizedBox(width: 20, height: 20, child: SvgPicture.asset(leadingIcon)), | |||
| leadingIcon == null | |||
| ? const SizedBox() | |||
| : SizedBox( | |||
| width: 20, | |||
| height: 20, | |||
| child: SvgPicture.asset( | |||
| leadingIcon ?? '', | |||
| )), | |||
| const SizedBox(width: 4), | |||
| Expanded( | |||
| child: Column( | |||
| @@ -59,7 +66,11 @@ class ButtonIconWidget extends StatelessWidget { | |||
| ], | |||
| ), | |||
| ), | |||
| trailingIcon == null ? const SizedBox() : SvgPicture.asset(trailingIcon) | |||
| trailingIcon == null | |||
| ? const SizedBox() | |||
| : SvgPicture.asset( | |||
| trailingIcon ?? '', | |||
| ) | |||
| ], | |||
| ), | |||
| ), | |||
| @@ -294,7 +294,7 @@ class _CameraHelperState extends State<CameraHelper> with WidgetsBindingObserver | |||
| try { | |||
| videoPath = filePath; | |||
| await controller.startVideoRecording(filePath); | |||
| // await controller.startVideoRecording(filePath); | |||
| } on CameraException catch (e) { | |||
| _showCameraException(e); | |||
| // return null; | |||
| @@ -357,7 +357,7 @@ class _CameraHelperState extends State<CameraHelper> with WidgetsBindingObserver | |||
| } | |||
| try { | |||
| await controller.takePicture(filePath); | |||
| // await controller.takePicture(filePath); | |||
| } on CameraException catch (e) { | |||
| _showCameraException(e); | |||
| // return null; | |||
| @@ -366,7 +366,7 @@ class _CameraHelperState extends State<CameraHelper> with WidgetsBindingObserver | |||
| } | |||
| void _showCameraException(CameraException e) { | |||
| logError(e.code, e.description); | |||
| // logError(e.code, e.description); | |||
| showInSnackBar('Lỗi: ${e.code}\n${e.description}'); | |||
| } | |||
| } | |||
| @@ -20,8 +20,8 @@ class _LoadingListPageState extends State<LoadingListPage> { | |||
| children: <Widget>[ | |||
| Expanded( | |||
| child: Shimmer.fromColors( | |||
| baseColor: Colors.grey[300], | |||
| highlightColor: Colors.grey[100], | |||
| baseColor: Colors.grey.shade300, | |||
| highlightColor: Colors.grey.shade300, | |||
| enabled: _enabled, | |||
| child: ListView.builder( | |||
| itemBuilder: (_, __) => Padding( | |||
| @@ -23,8 +23,8 @@ class ShimmerImage extends StatelessWidget { | |||
| return Stack( | |||
| children: <Widget>[ | |||
| Shimmer.fromColors( | |||
| baseColor: Colors.grey[200], | |||
| highlightColor: Colors.grey[100], | |||
| baseColor: Colors.grey, | |||
| highlightColor: Colors.grey, | |||
| child: aspectRatio != null | |||
| ? AspectRatio( | |||
| aspectRatio: aspectRatio ?? 1, | |||
| @@ -0,0 +1,227 @@ | |||
| import 'package:farm_tpf/themes/app_dimension.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter/services.dart'; | |||
| import 'package:flutter_svg/svg.dart'; | |||
| import '../../../themes/app_colors.dart'; | |||
| import '../../../themes/styles_text.dart'; | |||
| import '../../../utils/app_images.dart'; | |||
| import '../../../utils/validators.dart'; | |||
| class TextFieldNormal extends StatefulWidget { | |||
| final TextEditingController controller; | |||
| final Function(String)? onFieldSubmitted; | |||
| final Function(String)? onChanged; | |||
| final FormFieldValidator<String>? validator; | |||
| final String hint; | |||
| final FocusNode? focusNode; | |||
| final TextInputType? keyboardType; | |||
| final TextInputAction? textInputAction; | |||
| final List<TextInputFormatter>? inputFormatters; | |||
| final bool? obscureText; | |||
| final String? errorText; | |||
| final Color? borderColor; | |||
| final bool? isPasswordField; | |||
| final Widget? prefixIcon; | |||
| final String? prefixText; | |||
| final int? maxLength; | |||
| final bool? disabled; | |||
| final TextCapitalization? textCapitalization; | |||
| final String? suffixText; | |||
| final HexColor? disableColor; | |||
| final InputBorder? customBorder; | |||
| final int? maxLines; | |||
| final bool? autofocus; | |||
| TextFieldNormal({ | |||
| required this.controller, | |||
| required this.hint, | |||
| this.validator, | |||
| this.onFieldSubmitted, | |||
| this.focusNode, | |||
| this.keyboardType, | |||
| this.textInputAction, | |||
| this.inputFormatters, | |||
| this.obscureText, | |||
| this.errorText, | |||
| this.onChanged, | |||
| this.borderColor, | |||
| this.isPasswordField, | |||
| this.prefixIcon, | |||
| this.maxLength, | |||
| this.disabled, | |||
| this.textCapitalization, | |||
| this.suffixText, | |||
| this.disableColor, | |||
| this.prefixText, | |||
| this.customBorder, | |||
| this.maxLines, | |||
| this.autofocus, | |||
| }); | |||
| @override | |||
| _TextFieldNormalState createState() => _TextFieldNormalState(); | |||
| } | |||
| class _TextFieldNormalState extends State<TextFieldNormal> { | |||
| var isObscureText = false; | |||
| late HexColor disableColor; | |||
| final _errorMessage = ValueNotifier(''); | |||
| @override | |||
| void initState() { | |||
| super.initState(); | |||
| isObscureText = widget.isPasswordField ?? false; | |||
| disableColor = widget.disableColor ?? AppColors.white; | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Column( | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| children: [ | |||
| TextFormField( | |||
| keyboardType: widget.keyboardType ?? TextInputType.text, | |||
| textInputAction: widget.textInputAction ?? TextInputAction.done, | |||
| inputFormatters: widget.inputFormatters, | |||
| obscureText: isObscureText, | |||
| controller: widget.controller, | |||
| validator: onValidator, | |||
| onFieldSubmitted: widget.onFieldSubmitted, | |||
| focusNode: widget.focusNode, | |||
| autocorrect: false, | |||
| autofocus: widget.autofocus ?? false, | |||
| onChanged: widget.onChanged, | |||
| maxLength: widget.maxLength, | |||
| style: StylesText.body6, | |||
| maxLines: widget.maxLines ?? 1, | |||
| autovalidateMode: AutovalidateMode.disabled, | |||
| enabled: widget.disabled != true, | |||
| textCapitalization: widget.textCapitalization ?? TextCapitalization.none, | |||
| decoration: InputDecoration( | |||
| contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16), | |||
| isDense: true, | |||
| counterText: '', | |||
| suffixText: widget.suffixText, | |||
| suffixIconConstraints: BoxConstraints(maxHeight: 20), | |||
| suffixIcon: widget.isPasswordField != null | |||
| ? Padding( | |||
| padding: const EdgeInsetsDirectional.only(end: 20.0), | |||
| child: InkWell( | |||
| onTap: () { | |||
| setState( | |||
| () { | |||
| isObscureText = !isObscureText; | |||
| }, | |||
| ); | |||
| }, | |||
| child: isObscureText | |||
| ? SizedBox( | |||
| width: 20.w, | |||
| height: 20.h, | |||
| child: SvgPicture.asset( | |||
| AssetSVG.eye, | |||
| ), | |||
| ) | |||
| : SizedBox( | |||
| width: 20.w, | |||
| height: 20.h, | |||
| child: SvgPicture.asset( | |||
| AssetSVG.eyeOff, | |||
| ), | |||
| ), | |||
| ), | |||
| ) | |||
| : Padding( | |||
| padding: const EdgeInsetsDirectional.only(end: 8.0), | |||
| child: Text( | |||
| '', | |||
| style: StylesText.body3, | |||
| ), | |||
| ), | |||
| enabledBorder: widget.customBorder ?? | |||
| OutlineInputBorder( | |||
| borderRadius: BorderRadius.circular(12), | |||
| borderSide: BorderSide( | |||
| color: widget.borderColor ?? AppColors.neutral4, | |||
| width: 1, | |||
| ), | |||
| ), | |||
| focusedBorder: widget.customBorder ?? | |||
| OutlineInputBorder( | |||
| borderRadius: BorderRadius.circular(12), | |||
| borderSide: BorderSide( | |||
| color: widget.borderColor ?? AppColors.neutral4, | |||
| width: 1, | |||
| ), | |||
| ), | |||
| errorBorder: OutlineInputBorder( | |||
| borderRadius: BorderRadius.circular(12), | |||
| borderSide: BorderSide( | |||
| color: widget.borderColor ?? AppColors.semantic6, | |||
| width: 1, | |||
| ), | |||
| ), | |||
| focusedErrorBorder: OutlineInputBorder( | |||
| borderRadius: BorderRadius.circular(12), | |||
| borderSide: BorderSide( | |||
| color: widget.borderColor ?? AppColors.semantic6, | |||
| width: 1, | |||
| ), | |||
| ), | |||
| disabledBorder: OutlineInputBorder( | |||
| borderRadius: BorderRadius.circular(12), | |||
| borderSide: BorderSide( | |||
| color: widget.borderColor ?? AppColors.neutral4, | |||
| width: 1, | |||
| ), | |||
| ), | |||
| hintText: widget.hint, | |||
| hintStyle: StylesText.body6.copyWith( | |||
| color: AppColors.neutral3, | |||
| ), | |||
| errorStyle: const TextStyle(fontSize: 0, height: 0), | |||
| fillColor: (widget.disabled ?? false) ? AppColors.background1.withOpacity(0.1) : AppColors.white, | |||
| filled: true, | |||
| ), | |||
| ), | |||
| ValueListenableBuilder<String>( | |||
| valueListenable: _errorMessage, | |||
| builder: (context, message, _) { | |||
| if (Validators.stringNotNullOrEmpty(message)) { | |||
| return Padding( | |||
| padding: const EdgeInsets.only(top: 0.0), | |||
| child: Row( | |||
| children: [ | |||
| SvgPicture.asset(AssetSVG.icWarning), | |||
| const SizedBox( | |||
| width: 4, | |||
| ), | |||
| Text( | |||
| message, | |||
| style: StylesText.caption3.copyWith( | |||
| color: AppColors.semantic6, | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| ); | |||
| } else { | |||
| return const SizedBox.shrink(); | |||
| } | |||
| }, | |||
| ), | |||
| ], | |||
| ); | |||
| } | |||
| String? onValidator(String? value) { | |||
| if (widget.validator != null) { | |||
| _errorMessage.value = widget.validator!(value!) ?? ''; | |||
| return widget.validator!(value); | |||
| } else { | |||
| _errorMessage.value = ''; | |||
| return null; | |||
| } | |||
| } | |||
| } | |||
| @@ -13,6 +13,7 @@ import 'package:farm_tpf/utils/const_string.dart'; | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:image_picker/image_picker.dart'; | |||
| import 'bloc/media_helper_bloc.dart'; | |||
| import 'hoz_list_view.dart'; | |||
| @@ -29,6 +30,7 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> { | |||
| List<Media> currentItems = []; | |||
| List<String> addNewFilePaths = <String>[]; | |||
| List<String> deleteFilePaths = <String>[]; | |||
| final picker = ImagePicker(); | |||
| @override | |||
| void initState() { | |||
| @@ -64,12 +66,13 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> { | |||
| ), | |||
| onTap: () { | |||
| showDialog( | |||
| context: context, | |||
| barrierDismissible: true, | |||
| builder: (context) => Opacity( | |||
| child: multipleChoice(contextB), | |||
| opacity: 1, | |||
| )); | |||
| context: context, | |||
| barrierDismissible: true, | |||
| builder: (context) => Opacity( | |||
| child: multipleChoice(contextB), | |||
| opacity: 1, | |||
| ), | |||
| ); | |||
| }, | |||
| ), | |||
| const SizedBox( | |||
| @@ -92,92 +95,115 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> { | |||
| title: const Text(label_title_select_media), | |||
| actions: <Widget>[ | |||
| CupertinoDialogAction( | |||
| child: const Text(label_take_photo_or_video), | |||
| onPressed: () { | |||
| Navigator.pop(context, 'Discard'); | |||
| Navigator.of(context).push(MaterialPageRoute(builder: (context) => CameraHelper())).then((value) { | |||
| if (value != null) { | |||
| print("ok"); | |||
| print(value); | |||
| String filePath = value[0]; | |||
| var f = File(filePath); | |||
| f.length().then((lengthFileInBytes) { | |||
| if (lengthFileInBytes > ConstCommon.kFileSize) { | |||
| Utils.showSnackBarWarning(message: label_file_to_large); | |||
| } else { | |||
| bool isVideo = value[1]; | |||
| var newMedia = Media() | |||
| ..isVideo = isVideo | |||
| ..isServerFile = false | |||
| ..pathFile = filePath; | |||
| currentItems.add(newMedia); | |||
| addNewFilePaths.add(filePath); | |||
| BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| } | |||
| }); | |||
| child: const Text('Chụp ảnh'), | |||
| onPressed: () async { | |||
| Navigator.pop(context, 'Discard'); | |||
| var isExistedFileTooLarge = false; | |||
| var compressFile = await picker.pickImage(source: ImageSource.camera, imageQuality: 10); | |||
| if (compressFile != null) { | |||
| var imageFile = File(compressFile.path); | |||
| if (imageFile.lengthSync() > ConstCommon.kFileSize) { | |||
| isExistedFileTooLarge = true; | |||
| } else { | |||
| var newMedia = Media() | |||
| ..isVideo = false | |||
| ..isServerFile = false | |||
| ..pathFile = imageFile.path; | |||
| currentItems.add(newMedia); | |||
| addNewFilePaths.add(compressFile.path); | |||
| } | |||
| if (isExistedFileTooLarge) { | |||
| Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| } | |||
| BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| } | |||
| }, | |||
| ), | |||
| CupertinoDialogAction( | |||
| child: const Text(label_select_image_from_library), | |||
| onPressed: () async { | |||
| Navigator.pop(context, 'Discard'); | |||
| final List<XFile> images = await picker.pickMultiImage(imageQuality: 50); | |||
| var isExistedFileTooLarge = false; | |||
| images.forEach( | |||
| (compressFile) { | |||
| var imageFile = File(compressFile.path); | |||
| if (imageFile.lengthSync() > ConstCommon.kFileSize) { | |||
| isExistedFileTooLarge = true; | |||
| } else { | |||
| var newMedia = Media() | |||
| ..isVideo = false | |||
| ..isServerFile = false | |||
| ..pathFile = imageFile.path; | |||
| currentItems.add(newMedia); | |||
| addNewFilePaths.add(compressFile.path); | |||
| } | |||
| }); | |||
| }), | |||
| // CupertinoDialogAction( | |||
| // child: const Text(label_select_image_from_library), | |||
| // onPressed: () async { | |||
| // Navigator.pop(context, 'Discard'); | |||
| // FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true); | |||
| // if (result != null) { | |||
| // var listFuture = <Future<File>>[]; | |||
| // result.files.forEach((element) { | |||
| // listFuture.add(UtilAction.compressImage(File(element.path ?? ''))); | |||
| // }); | |||
| // Future.wait(listFuture).then((values) { | |||
| // var isExistedFileTooLarge = false; | |||
| // values.forEach((compressFile) { | |||
| // if (compressFile.lengthSync() > ConstCommon.kFileSize) { | |||
| // isExistedFileTooLarge = true; | |||
| // } else { | |||
| // var newMedia = Media() | |||
| // ..isVideo = false | |||
| // ..isServerFile = false | |||
| // ..pathFile = compressFile.path; | |||
| // currentItems.add(newMedia); | |||
| // addNewFilePaths.add(compressFile.path); | |||
| // } | |||
| // }); | |||
| // if (isExistedFileTooLarge) { | |||
| // Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| // } | |||
| // BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| // widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| // }); | |||
| // } | |||
| // }), | |||
| // CupertinoDialogAction( | |||
| // child: const Text(label_select_video_from_library), | |||
| // onPressed: () async { | |||
| // Navigator.pop(context, 'Discard'); | |||
| // FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.video, allowMultiple: true); | |||
| if (isExistedFileTooLarge) { | |||
| Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| } | |||
| BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| }, | |||
| ); | |||
| // if (result != null) { | |||
| // var isExistedFileTooLarge = false; | |||
| // result.files?.forEach((videoFile) { | |||
| // if (videoFile.size * 1000 > ConstCommon.kFileSize) { | |||
| // isExistedFileTooLarge = true; | |||
| // } else { | |||
| // var newMedia = Media() | |||
| // ..isVideo = true | |||
| // ..isServerFile = false | |||
| // ..pathFile = videoFile.path; | |||
| // currentItems.add(newMedia); | |||
| // addNewFilePaths.add(videoFile.path ?? ''); | |||
| // } | |||
| // }); | |||
| // if (isExistedFileTooLarge) { | |||
| // Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| // } | |||
| // BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| // widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| // } | |||
| // }), | |||
| // } | |||
| }, | |||
| ), | |||
| CupertinoDialogAction( | |||
| child: const Text('Quay video'), | |||
| onPressed: () async { | |||
| Navigator.pop(context, 'Discard'); | |||
| var isExistedFileTooLarge = false; | |||
| var compressFile = await picker.pickVideo(source: ImageSource.camera); | |||
| if (compressFile != null) { | |||
| var imageFile = File(compressFile.path); | |||
| if (imageFile.lengthSync() > ConstCommon.kFileSize) { | |||
| isExistedFileTooLarge = true; | |||
| } else { | |||
| var newMedia = Media() | |||
| ..isVideo = true | |||
| ..isServerFile = false | |||
| ..pathFile = imageFile.path; | |||
| currentItems.add(newMedia); | |||
| addNewFilePaths.add(compressFile.path); | |||
| } | |||
| if (isExistedFileTooLarge) { | |||
| Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| } | |||
| BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| } | |||
| }, | |||
| ), | |||
| CupertinoDialogAction( | |||
| child: const Text(label_select_video_from_library), | |||
| onPressed: () async { | |||
| Navigator.pop(context, 'Discard'); | |||
| var result = await picker.pickVideo(source: ImageSource.gallery); | |||
| // FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.video, allowMultiple: true); | |||
| if (result != null) { | |||
| var isExistedFileTooLarge = false; | |||
| var fileVideo = File(result.path); | |||
| if (fileVideo.lengthSync() > ConstCommon.kFileSize) { | |||
| isExistedFileTooLarge = true; | |||
| } else { | |||
| var newMedia = Media() | |||
| ..isVideo = true | |||
| ..isServerFile = false | |||
| ..pathFile = fileVideo.path; | |||
| currentItems.add(newMedia); | |||
| addNewFilePaths.add(fileVideo.path); | |||
| } | |||
| if (isExistedFileTooLarge) { | |||
| Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| } | |||
| BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| } | |||
| }, | |||
| ), | |||
| CupertinoDialogAction( | |||
| child: const Text(label_cancel), | |||
| textStyle: const TextStyle(fontWeight: FontWeight.bold), | |||
| @@ -242,20 +268,24 @@ class _WidgetItemMedia extends StatelessWidget { | |||
| // overflow: Overflow.visible, | |||
| children: <Widget>[ | |||
| Positioned.fill( | |||
| child: (item.isVideo ?? false) | |||
| ? VideoWidget( | |||
| pathFile: item.pathFile ?? '', | |||
| isServerFile: item.isServerFile ?? false, | |||
| play: false, | |||
| ) | |||
| : Container( | |||
| margin: const EdgeInsets.all(4.0), | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, border: Border.all(color: Colors.grey), borderRadius: const BorderRadius.all(Radius.circular(8.0))), | |||
| child: (item.isServerFile ?? false) | |||
| ? CachedNetworkImage(placeholder: (context, url) => const Icon(Icons.crop_original), imageUrl: item.pathFile) | |||
| : Image.file(File(item.pathFile ?? '')), | |||
| )), | |||
| child: (item.isVideo ?? false) | |||
| ? VideoWidget( | |||
| pathFile: item.pathFile ?? '', | |||
| isServerFile: item.isServerFile ?? false, | |||
| play: false, | |||
| ) | |||
| : Container( | |||
| margin: const EdgeInsets.all(4.0), | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, border: Border.all(color: Colors.grey), borderRadius: const BorderRadius.all(Radius.circular(8.0))), | |||
| child: (item.isServerFile ?? false) | |||
| ? CachedNetworkImage( | |||
| placeholder: (context, url) => const Icon(Icons.crop_original), | |||
| imageUrl: item.pathFile ?? '', | |||
| ) | |||
| : Image.file(File(item.pathFile ?? '')), | |||
| ), | |||
| ), | |||
| Positioned.fill( | |||
| top: positionIconDelete, | |||
| right: positionIconDelete, | |||
| @@ -16,7 +16,7 @@ class VideoWidget extends StatefulWidget { | |||
| } | |||
| class _VideoWidgetState extends State<VideoWidget> { | |||
| late VideoPlayerController videoPlayerController; | |||
| VideoPlayerController? videoPlayerController; | |||
| late Future<void> _initializeVideoPlayerFuture; | |||
| @override | |||
| @@ -28,12 +28,12 @@ class _VideoWidgetState extends State<VideoWidget> { | |||
| videoPlayerController = VideoPlayerController.file(File(widget.pathFile)); | |||
| } | |||
| _initializeVideoPlayerFuture = videoPlayerController.initialize().then((_) { | |||
| _initializeVideoPlayerFuture = videoPlayerController!.initialize().then((_) { | |||
| // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. | |||
| videoPlayerController.play(); | |||
| videoPlayerController.setVolume(0.0); | |||
| videoPlayerController?.play(); | |||
| videoPlayerController?.setVolume(0.0); | |||
| Timer.periodic(const Duration(seconds: 1), (_) { | |||
| videoPlayerController.pause(); | |||
| videoPlayerController?.pause(); | |||
| }); | |||
| setState(() {}); | |||
| }); | |||
| @@ -41,7 +41,7 @@ class _VideoWidgetState extends State<VideoWidget> { | |||
| @override | |||
| void dispose() { | |||
| videoPlayerController.dispose(); | |||
| videoPlayerController?.dispose(); | |||
| print("dispose video item"); | |||
| super.dispose(); | |||
| } | |||
| @@ -61,7 +61,7 @@ class _VideoWidgetState extends State<VideoWidget> { | |||
| height: 100, | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, border: Border.all(color: Colors.red), borderRadius: const BorderRadius.all(Radius.circular(8.0))), | |||
| child: VideoPlayer(videoPlayerController), | |||
| child: VideoPlayer(videoPlayerController!), | |||
| ), | |||
| ), | |||
| ); | |||
| @@ -15,7 +15,7 @@ class TextFieldDescriptionWidget extends StatelessWidget { | |||
| controller: controller, | |||
| decoration: const InputDecoration(labelText: "Ghi chú", hintText: 'Ghi chú', border: InputBorder.none), | |||
| onSaved: (v) { | |||
| onSaved(); | |||
| // onSaved(); | |||
| }, | |||
| ), | |||
| ); | |||
| @@ -4,7 +4,7 @@ import 'package:get/get.dart'; | |||
| class Utils { | |||
| static void showSnackBarSuccess({required String message}) { | |||
| if (Get.isSnackbarOpen) Get.back(); | |||
| Get.snackbar(null, message, | |||
| Get.snackbar('', message, | |||
| icon: const Icon( | |||
| Icons.done, | |||
| color: Colors.white, | |||
| @@ -15,7 +15,7 @@ class Utils { | |||
| static void showSnackBarError({required String message}) { | |||
| if (Get.isSnackbarOpen) Get.back(); | |||
| Get.snackbar(null, message, | |||
| Get.snackbar('', message, | |||
| icon: const Icon( | |||
| Icons.error, | |||
| color: Colors.white, | |||
| @@ -26,7 +26,7 @@ class Utils { | |||
| static void showSnackBarWarning({required String message}) { | |||
| if (Get.isSnackbarOpen) Get.back(); | |||
| Get.snackbar(null, message, | |||
| Get.snackbar('', message, | |||
| icon: const Icon( | |||
| Icons.warning, | |||
| color: Colors.yellow, | |||
| @@ -37,7 +37,7 @@ class Utils { | |||
| static void showDialog( | |||
| {required String title, required String message, required String textConfirm, required String textCancel, required Function() onConfirm}) { | |||
| if (Get.isDialogOpen) Get.back(); | |||
| if (Get.isDialogOpen ?? false) Get.back(); | |||
| Get.defaultDialog( | |||
| title: title, | |||
| middleText: message, | |||
| @@ -49,7 +49,7 @@ class Utils { | |||
| } | |||
| static void showDialogConfirmSupply({required Function() onConfirm}) { | |||
| if (Get.isDialogOpen) Get.back(); | |||
| if (Get.isDialogOpen ?? false) Get.back(); | |||
| Get.defaultDialog( | |||
| title: "Vật tư chưa được thêm", | |||
| middleText: "Bạn có muốn cập nhật?", | |||
| @@ -22,6 +22,8 @@ class _AccountScreenState extends State<AccountScreen> { | |||
| PackageInfo _packageInfo = PackageInfo( | |||
| version: '1.0.0', | |||
| buildNumber: '1.', | |||
| appName: '', | |||
| packageName: '', | |||
| ); | |||
| Future<void> _initPackageInfo() async { | |||
| @@ -38,25 +40,22 @@ class _AccountScreenState extends State<AccountScreen> { | |||
| } | |||
| _clickSignOut() async { | |||
| context.bloc<AuthenticationBloc>().add(AuthenticationLogoutRequested()); | |||
| // try { | |||
| // var pushKey = await pref.getString(DATA_CONST.PUSH_KEY); | |||
| // if (pushKey.isNotEmpty) { | |||
| // _userRepository | |||
| // .deleteFcmToken(pushKey) | |||
| // .then((value) {}) | |||
| // .catchError((err) {}) | |||
| // .whenComplete(() { | |||
| // pref.saveString(DATA_CONST.TOKEN_KEY, ""); | |||
| // pref.saveString(DATA_CONST.PUSH_KEY, ""); | |||
| // pref.saveString(DATA_CONST.CURRENT_FULL_NAME, ""); | |||
| // }); | |||
| // } | |||
| // } catch (e) { | |||
| // pref.saveString(DATA_CONST.CURRENT_FULL_NAME, ""); | |||
| // pref.saveString(DATA_CONST.TOKEN_KEY, ""); | |||
| // pref.saveString(DATA_CONST.PUSH_KEY, ""); | |||
| // } | |||
| BlocProvider.of<AuthenticationBloc>(context).add(AuthenticationLogoutRequested()); | |||
| // context.bloc<AuthenticationBloc>().add(AuthenticationLogoutRequested()); | |||
| try { | |||
| var pushKey = await pref.getString(DATA_CONST.PUSH_KEY); | |||
| if (pushKey.isNotEmpty) { | |||
| _userRepository.deleteFcmToken(pushKey).then((value) {}).catchError((err) {}).whenComplete(() { | |||
| pref.saveString(DATA_CONST.TOKEN_KEY, ""); | |||
| pref.saveString(DATA_CONST.PUSH_KEY, ""); | |||
| pref.saveString(DATA_CONST.CURRENT_FULL_NAME, ""); | |||
| }); | |||
| } | |||
| } catch (e) { | |||
| pref.saveString(DATA_CONST.CURRENT_FULL_NAME, ""); | |||
| pref.saveString(DATA_CONST.TOKEN_KEY, ""); | |||
| pref.saveString(DATA_CONST.PUSH_KEY, ""); | |||
| } | |||
| } | |||
| @override | |||
| @@ -31,7 +31,7 @@ class ActionDetailBloc extends Bloc<ActionDetailEvent, ActionDetailState> { | |||
| try { | |||
| yield ActionDetailLoading(); | |||
| Response<String> response = await dio.get("${ConstCommon.baseUrl}/${event.apiActivity}/${event.activityId}"); | |||
| final jsonData = json.decode(response.data); | |||
| final jsonData = json.decode(response.data ?? ''); | |||
| yield ActionDetailSuccess(item: jsonData); | |||
| } catch (error) { | |||
| yield ActionDetailFailure(errorString: AppException.handleError(error)); | |||
| @@ -76,7 +76,7 @@ class _EditActionCropStatusScreenState extends State<EditActionCropStatusScreen> | |||
| _validateInputs() async { | |||
| if (_formKey.currentState!.validate()) { | |||
| _formKey.currentState!.save(); | |||
| // _formKey.currentState!.save(); | |||
| LoadingDialog.showLoadingDialog(context); | |||
| filePaths = Get.find<ChangeFileController>().newFiles; | |||
| //Create request general model | |||
| @@ -290,7 +290,7 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> { | |||
| // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)), | |||
| child: const Text("Huỷ"), | |||
| onTap: () { | |||
| context.bloc<StatusAddFormBloc>().add(Reset()); | |||
| BlocProvider.of<StatusAddFormBloc>(context).add(Reset()); | |||
| }), | |||
| Expanded( | |||
| child: FlatButton( | |||
| @@ -303,18 +303,18 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> { | |||
| ..trayNumber = _trayNumberController.text; | |||
| if (state is Edit) { | |||
| context.bloc<ExpansionListBloc>().add( | |||
| Update( | |||
| index: state.index, | |||
| item: _nurseryDetail, | |||
| items: state.items ?? <NurseryDetail>[], | |||
| ), | |||
| ); | |||
| BlocProvider.of<ExpansionListBloc>(context).add( | |||
| Update( | |||
| index: state.index, | |||
| item: _nurseryDetail, | |||
| items: state.items ?? <NurseryDetail>[], | |||
| ), | |||
| ); | |||
| } else { | |||
| currentNurseryDetail.insert(0, _nurseryDetail); | |||
| BlocProvider.of<ExpansionListBloc>(context).add(AddNew(items: currentNurseryDetail)); | |||
| } | |||
| context.bloc<StatusAddFormBloc>().add(Reset()); | |||
| BlocProvider.of<StatusAddFormBloc>(context).add(Reset()); | |||
| } else { | |||
| Utils.showSnackBarWarning(message: "Vui lòng nhập tên công nhân"); | |||
| } | |||
| @@ -360,7 +360,7 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> { | |||
| onTap: () { | |||
| print("edit worker"); | |||
| currentIndexUpdate = index; | |||
| context.bloc<StatusAddFormBloc>().add(Changed( | |||
| BlocProvider.of<StatusAddFormBloc>(context).add(Changed( | |||
| status: CRUDStatus.edit, index: index, nurseryDetail: currentNurseryDetail[index], items: currentNurseryDetail)); | |||
| }, | |||
| child: Card( | |||
| @@ -400,8 +400,8 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> { | |||
| ), | |||
| onPressed: () { | |||
| print("Delete worker"); | |||
| context.bloc<ExpansionListBloc>().add(DeleteItem(index: index, items: currentNurseryDetail)); | |||
| context.bloc<StatusAddFormBloc>().add(Changed( | |||
| BlocProvider.of<ExpansionListBloc>(context).add(DeleteItem(index: index, items: currentNurseryDetail)); | |||
| BlocProvider.of<StatusAddFormBloc>(context).add(Changed( | |||
| status: CRUDStatus.delete, | |||
| index: index, | |||
| nurseryDetail: currentNurseryDetail[index], | |||
| @@ -16,7 +16,6 @@ class UtilAction { | |||
| var tempFile = await DefaultCacheManager().getSingleFile(ConstCommon.baseImageUrl + mediaPaths[i]); | |||
| print(tempFile.path); | |||
| var isVideo = lookupMimeType(tempFile.path) == "video/mp4"; | |||
| print("file type: " + lookupMimeType(tempFile.path)); | |||
| var media = Media() | |||
| ..pathFile = tempFile.path | |||
| ..isVideo = isVideo; | |||
| @@ -88,7 +87,7 @@ class UtilAction { | |||
| static Future<File> compressAndGetFile(File file, String targetPath) async { | |||
| try { | |||
| final result = await FlutterImageCompress.compressAndGetFile(file.absolute.path, targetPath, quality: 50, minWidth: 1280, minHeight: 720); | |||
| return result; | |||
| return result!; | |||
| } on UnsupportedError catch (e) { | |||
| return Future.value(file); | |||
| } | |||
| @@ -54,7 +54,7 @@ class _ControlDeviceScreenState extends State<ControlDeviceScreen> { | |||
| }), | |||
| Expanded( | |||
| child: BlocBuilder<DeviceBloc, DeviceState>( | |||
| cubit: _deviceBloc, | |||
| bloc: _deviceBloc, | |||
| builder: (context, state) { | |||
| if (state is DisplayDevice) { | |||
| if (state.loading) { | |||
| @@ -1,98 +0,0 @@ | |||
| import 'dart:async'; | |||
| import 'package:bloc/bloc.dart'; | |||
| import 'package:equatable/equatable.dart'; | |||
| import 'package:farm_tpf/data/repository/authentication_repository.dart'; | |||
| import 'package:farm_tpf/presentation/screens/login/models/password.dart'; | |||
| import 'package:farm_tpf/presentation/screens/login/models/username.dart'; | |||
| import 'package:farm_tpf/utils/pref.dart'; | |||
| import 'package:formz/formz.dart'; | |||
| import 'package:meta/meta.dart'; | |||
| part 'login_event.dart'; | |||
| part 'login_state.dart'; | |||
| class LoginBloc extends Bloc<LoginEvent, LoginState> { | |||
| LoginBloc({ | |||
| required AuthenticationRepository authenticationRepository, | |||
| }) : assert(authenticationRepository != null), | |||
| _authenticationRepository = authenticationRepository, | |||
| super(const LoginState()); | |||
| final AuthenticationRepository _authenticationRepository; | |||
| var pref = LocalPref(); | |||
| @override | |||
| Stream<LoginState> mapEventToState( | |||
| LoginEvent event, | |||
| ) async* { | |||
| if (event is LoginUsernameChanged) { | |||
| yield _mapUsernameChangedToState(event, state); | |||
| } else if (event is LoginPasswordChanged) { | |||
| yield _mapPasswordChangedToState(event, state); | |||
| } else if (event is LoginSubmitted) { | |||
| yield* _mapLoginSubmittedToState(event, state); | |||
| } | |||
| } | |||
| LoginState _mapUsernameChangedToState( | |||
| LoginUsernameChanged event, | |||
| LoginState state, | |||
| ) { | |||
| final username = Username.dirty(event.username); | |||
| return state.copyWith( | |||
| username: username, | |||
| status: Formz.validate([state.password, username]), | |||
| ); | |||
| } | |||
| LoginState _mapPasswordChangedToState( | |||
| LoginPasswordChanged event, | |||
| LoginState state, | |||
| ) { | |||
| final password = Password.dirty(event.password); | |||
| return state.copyWith( | |||
| password: password, | |||
| status: Formz.validate([password, state.username]), | |||
| ); | |||
| } | |||
| Stream<LoginState> _mapLoginSubmittedToState( | |||
| LoginSubmitted event, | |||
| LoginState state, | |||
| ) async* { | |||
| if (state.status.isValidated) { | |||
| // yield state.copyWith(status: FormzStatus.submissionInProgress); | |||
| // try { | |||
| // var user = await _authenticationRepository.signInWithCredentials( | |||
| // state.username.value, | |||
| // state.password.value, | |||
| // ); | |||
| // var token = user.idToken; | |||
| // pref.saveString(DATA_CONST.TOKEN_KEY, token ?? ''); | |||
| // var currentTime = DateTime.now().millisecondsSinceEpoch; | |||
| // pref.saveString(DATA_CONST.EXPIRED_TIME, currentTime.toString()); | |||
| // yield state.copyWith(status: FormzStatus.submissionSuccess); | |||
| // } on Exception catch (_) { | |||
| // yield state.copyWith(status: FormzStatus.submissionFailure); | |||
| // } | |||
| } | |||
| yield state.copyWith(status: FormzStatus.submissionInProgress); | |||
| try { | |||
| var user = await _authenticationRepository.signInWithCredentials( | |||
| // state.username.value, | |||
| // state.password.value, | |||
| 'lecaoanhquoc', | |||
| '12345678', | |||
| ); | |||
| var token = user.idToken; | |||
| pref.saveString(DATA_CONST.TOKEN_KEY, token ?? ''); | |||
| var currentTime = DateTime.now().millisecondsSinceEpoch; | |||
| pref.saveString(DATA_CONST.EXPIRED_TIME, currentTime.toString()); | |||
| yield state.copyWith(status: FormzStatus.submissionSuccess); | |||
| } on Exception catch (_) { | |||
| yield state.copyWith(status: FormzStatus.submissionFailure); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,30 +0,0 @@ | |||
| part of 'login_bloc.dart'; | |||
| abstract class LoginEvent extends Equatable { | |||
| const LoginEvent(); | |||
| @override | |||
| List<Object> get props => []; | |||
| } | |||
| class LoginUsernameChanged extends LoginEvent { | |||
| const LoginUsernameChanged(this.username); | |||
| final String username; | |||
| @override | |||
| List<Object> get props => [username]; | |||
| } | |||
| class LoginPasswordChanged extends LoginEvent { | |||
| const LoginPasswordChanged(this.password); | |||
| final String password; | |||
| @override | |||
| List<Object> get props => [password]; | |||
| } | |||
| class LoginSubmitted extends LoginEvent { | |||
| const LoginSubmitted(); | |||
| } | |||
| @@ -1,28 +0,0 @@ | |||
| part of 'login_bloc.dart'; | |||
| class LoginState extends Equatable { | |||
| const LoginState({ | |||
| this.status = FormzStatus.pure, | |||
| this.username = const Username.pure(), | |||
| this.password = const Password.pure(), | |||
| }); | |||
| final FormzStatus status; | |||
| final Username username; | |||
| final Password password; | |||
| LoginState copyWith({ | |||
| FormzStatus? status, | |||
| Username? username, | |||
| Password? password, | |||
| }) { | |||
| return LoginState( | |||
| status: status ?? this.status, | |||
| username: username ?? this.username, | |||
| password: password ?? this.password, | |||
| ); | |||
| } | |||
| @override | |||
| List<Object> get props => [status, username, password]; | |||
| } | |||
| @@ -0,0 +1,89 @@ | |||
| import 'package:bloc/bloc.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:get/get.dart'; | |||
| import '../../../../data/repository/repository.dart'; | |||
| import '../../../../utils/local_storage.dart'; | |||
| import '../../../../utils/validators.dart'; | |||
| import '../models/request_user.dart'; | |||
| import '../models/response_user.dart'; | |||
| part 'login_state.dart'; | |||
| class LoginCubit extends Cubit<LoginState> { | |||
| LoginCubit() : super(LoginInitial()); | |||
| final formKey = GlobalKey<FormState>(); | |||
| final usernameCtl = TextEditingController(); | |||
| final passwordCtl = TextEditingController(); | |||
| final usernameFocus = FocusNode(); | |||
| final passwordFocus = FocusNode(); | |||
| final _repository = Repository(); | |||
| var isRemember = ValueNotifier(true); | |||
| Future<void> loginWithCredential() async { | |||
| // if (!formKey.currentState!.validate()) { | |||
| // return; | |||
| // } | |||
| emit(LoginLoading()); | |||
| var userLoginRequest = RequestUser() | |||
| ..username = usernameCtl.text | |||
| ..password = passwordCtl.text; | |||
| await _repository.login( | |||
| (data) { | |||
| handleLoginLogic( | |||
| responseUser: data, | |||
| username: usernameCtl.text, | |||
| ); | |||
| }, | |||
| (error) { | |||
| emit(LoginFailure('Tên đăng nhập hoặc mật khẩu không đúng')); | |||
| }, | |||
| requestUser: userLoginRequest, | |||
| ); | |||
| } | |||
| Future<void> handleLoginLogic({ | |||
| required ResponseUser responseUser, | |||
| required String username, | |||
| }) async { | |||
| try { | |||
| LocalStorage.saveUserInfo(responseUser, username); | |||
| } catch (_) {} | |||
| emit( | |||
| LoginSuccess( | |||
| routeName: '', | |||
| ), | |||
| ); | |||
| } | |||
| String? validateEmail(String value) { | |||
| if (!Validators.stringNotNullOrEmpty(value)) { | |||
| return 'Nhập email'; | |||
| } | |||
| if (!Validators.isValidEmail(value)) { | |||
| return 'Nhập email'; | |||
| } | |||
| return null; | |||
| } | |||
| String? validatePassword(String value) { | |||
| if (!Validators.stringNotNullOrEmpty(value)) { | |||
| return 'Nhập mật khẩu'; | |||
| } | |||
| return null; | |||
| } | |||
| void rememberMe(bool isRememberLogin) { | |||
| isRemember.value = isRememberLogin; | |||
| } | |||
| void dispose() { | |||
| usernameCtl.dispose(); | |||
| passwordCtl.dispose(); | |||
| usernameFocus.dispose(); | |||
| passwordFocus.dispose(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,22 @@ | |||
| part of 'login_cubit.dart'; | |||
| @immutable | |||
| abstract class LoginState {} | |||
| class LoginInitial extends LoginState {} | |||
| class LoginLoading extends LoginState {} | |||
| class LoginFailure extends LoginState { | |||
| final String errorMessage; | |||
| LoginFailure(this.errorMessage); | |||
| } | |||
| class LoginSuccess extends LoginState { | |||
| final String routeName; | |||
| LoginSuccess({ | |||
| required this.routeName, | |||
| }); | |||
| } | |||
| @@ -1,3 +0,0 @@ | |||
| export 'bloc/login_bloc.dart'; | |||
| export 'models/models.dart'; | |||
| export 'view/view.dart'; | |||
| @@ -0,0 +1,258 @@ | |||
| import 'package:farm_tpf/themes/app_dimension.dart'; | |||
| import 'package:flutter/foundation.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:flutter_svg/svg.dart'; | |||
| import 'package:keyboard_dismisser/keyboard_dismisser.dart'; | |||
| import '../../../authentication/bloc/authentication_bloc.dart'; | |||
| import '../../../common/const_enum.dart'; | |||
| import '../../../themes/app_colors.dart'; | |||
| import '../../../themes/styles_text.dart'; | |||
| import '../../../utils/app_images.dart'; | |||
| import '../../../utils/helpers.dart'; | |||
| import '../../../utils/utils.dart'; | |||
| import '../../../utils/validators.dart'; | |||
| import '../../custom_widgets/button/primary_button_widget.dart'; | |||
| import '../../custom_widgets/textfield/text_field_normal.dart'; | |||
| import 'cubit/login_cubit.dart'; | |||
| class LoginPage extends StatefulWidget { | |||
| const LoginPage({Key? key}) : super(key: key); | |||
| @override | |||
| State<LoginPage> createState() => _LoginPageState(); | |||
| } | |||
| class _LoginPageState extends State<LoginPage> { | |||
| var loginBloc = LoginCubit(); | |||
| var loginErrorMessage = ValueNotifier(''); | |||
| @override | |||
| void initState() { | |||
| super.initState(); | |||
| if (kDebugMode) { | |||
| loginBloc.usernameCtl.text = 'lecaoanhquoc'; | |||
| loginBloc.passwordCtl.text = '12345678'; | |||
| } | |||
| } | |||
| @override | |||
| void dispose() { | |||
| super.dispose(); | |||
| loginBloc.dispose(); | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return BlocListener<LoginCubit, LoginState>( | |||
| bloc: loginBloc, | |||
| listener: (context, state) { | |||
| if (state is LoginLoading) { | |||
| Helpers.hideKeyboard(context); | |||
| UtilWidget.showLoading(); | |||
| } else if (state is LoginFailure) { | |||
| UtilWidget.hideLoading(); | |||
| loginErrorMessage.value = state.errorMessage; | |||
| loginErrorMessage.notifyListeners(); | |||
| } else if (state is LoginSuccess) { | |||
| UtilWidget.hideLoading(); | |||
| BlocProvider.of<AuthenticationBloc>(context).add( | |||
| const AuthenticationStatusChanged( | |||
| AuthenticationStatus.authenticated, | |||
| ), | |||
| ); | |||
| } else { | |||
| UtilWidget.hideLoading(); | |||
| } | |||
| }, | |||
| child: _widgetMainBody(), | |||
| ); | |||
| } | |||
| Widget _widgetMainBody() { | |||
| return Scaffold( | |||
| body: KeyboardDismisser( | |||
| child: Container( | |||
| decoration: BoxDecoration( | |||
| color: AppColors.primary1, | |||
| ), | |||
| child: Stack( | |||
| children: <Widget>[ | |||
| Positioned( | |||
| top: 0, | |||
| right: 0, | |||
| left: 0, | |||
| child: Container( | |||
| height: 370.h, | |||
| decoration: BoxDecoration( | |||
| color: AppColors.background1, | |||
| // image: const DecorationImage( | |||
| // image: AssetImage(AssetPNG.backgroundLogin), | |||
| // fit: BoxFit.cover, | |||
| // ), | |||
| ), | |||
| ), | |||
| ), | |||
| Positioned( | |||
| top: 0, | |||
| right: 0, | |||
| left: 0, | |||
| child: Container( | |||
| height: 371.h, | |||
| decoration: BoxDecoration( | |||
| color: AppColors.primary1, | |||
| gradient: LinearGradient( | |||
| colors: [ | |||
| AppColors.primary1, | |||
| AppColors.primary1.withOpacity(0), | |||
| ], | |||
| begin: Alignment.bottomCenter, | |||
| end: Alignment.topCenter, | |||
| ), | |||
| ), | |||
| ), | |||
| ), | |||
| Positioned( | |||
| top: 140.h, | |||
| right: 40.w, | |||
| left: 40.w, | |||
| child: Image.asset( | |||
| AssetPNG.logo, | |||
| height: 150, | |||
| ), | |||
| ), | |||
| Positioned( | |||
| bottom: 8, | |||
| right: 8, | |||
| left: 8, | |||
| child: SafeArea( | |||
| child: Container( | |||
| width: double.infinity, | |||
| padding: EdgeInsets.all(32.r), | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, | |||
| borderRadius: BorderRadius.circular(16.r), | |||
| ), | |||
| child: Form( | |||
| key: loginBloc.formKey, | |||
| child: Column( | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| mainAxisSize: MainAxisSize.min, | |||
| children: [ | |||
| Text( | |||
| 'Đăng Nhập', | |||
| style: StylesText.header1, | |||
| ), | |||
| const SizedBox( | |||
| height: 9, | |||
| ), | |||
| Text( | |||
| 'Nhập tài khoản và mật khẩu để đăng nhập', | |||
| style: StylesText.body6.copyWith( | |||
| color: AppColors.neutral2, | |||
| ), | |||
| ), | |||
| SizedBox( | |||
| height: 24.h, | |||
| ), | |||
| Text( | |||
| 'Tài Khoản', | |||
| style: StylesText.body6, | |||
| ), | |||
| const SizedBox( | |||
| height: 4, | |||
| ), | |||
| TextFieldNormal( | |||
| controller: loginBloc.usernameCtl, | |||
| hint: 'Nhập tài khoản', | |||
| validator: (val) { | |||
| return Validators.validateNotNullOrEmpty( | |||
| val ?? '', | |||
| 'Nhập tài khoản', | |||
| ); | |||
| }, | |||
| ), | |||
| const SizedBox( | |||
| height: 16, | |||
| ), | |||
| Text( | |||
| 'Mật Khẩu', | |||
| style: StylesText.body6, | |||
| ), | |||
| const SizedBox( | |||
| height: 4, | |||
| ), | |||
| TextFieldNormal( | |||
| controller: loginBloc.passwordCtl, | |||
| hint: 'Nhập Mật Khẩu', | |||
| isPasswordField: true, | |||
| validator: (val) { | |||
| return Validators.validateNotNullOrEmpty( | |||
| val ?? '', | |||
| 'Nhập Mật Khẩu', | |||
| ); | |||
| }, | |||
| ), | |||
| ValueListenableBuilder<String>( | |||
| valueListenable: loginErrorMessage, | |||
| builder: (context, errorMessage, _) { | |||
| if (Validators.stringNotNullOrEmpty(errorMessage)) { | |||
| return Container( | |||
| decoration: BoxDecoration( | |||
| color: AppColors.semantic7, | |||
| borderRadius: BorderRadius.circular(8), | |||
| ), | |||
| margin: const EdgeInsets.only( | |||
| top: 16, | |||
| ), | |||
| padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), | |||
| child: Row( | |||
| children: [ | |||
| SvgPicture.asset(AssetSVG.icWarning), | |||
| const SizedBox( | |||
| width: 4, | |||
| ), | |||
| Text( | |||
| errorMessage, | |||
| style: StylesText.caption3.copyWith( | |||
| color: AppColors.semantic6, | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| ); | |||
| } else { | |||
| return const SizedBox.shrink(); | |||
| } | |||
| }, | |||
| ), | |||
| SizedBox( | |||
| height: 24.h, | |||
| ), | |||
| PrimaryButtonWidget( | |||
| title: 'Đăng Nhập', | |||
| onPressed: () => onPressedLogin(), | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| ), | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| void onPressedRememberLogin(bool isRemember) { | |||
| loginBloc.rememberMe(isRemember); | |||
| } | |||
| void onPressedForgotPassword() {} | |||
| void onPressedLogin() { | |||
| loginBloc.loginWithCredential(); | |||
| } | |||
| } | |||
| @@ -1,2 +0,0 @@ | |||
| export 'password.dart'; | |||
| export 'username.dart'; | |||
| @@ -1,13 +0,0 @@ | |||
| import 'package:formz/formz.dart'; | |||
| enum PasswordValidationError { empty, notEmpty } | |||
| class Password extends FormzInput<String, PasswordValidationError> { | |||
| const Password.pure() : super.pure(''); | |||
| const Password.dirty([String value = '']) : super.dirty(value); | |||
| @override | |||
| PasswordValidationError validator(String value) { | |||
| return value?.isNotEmpty == true ? PasswordValidationError.notEmpty : PasswordValidationError.empty; | |||
| } | |||
| } | |||
| @@ -0,0 +1,16 @@ | |||
| class RequestUser { | |||
| String? username; | |||
| String? password; | |||
| RequestUser({ | |||
| this.username, | |||
| this.password, | |||
| }); | |||
| Map<String, dynamic> toJson() { | |||
| final data = <String, dynamic>{}; | |||
| data['username'] = username; | |||
| data['password'] = password; | |||
| return data; | |||
| } | |||
| } | |||
| @@ -0,0 +1,13 @@ | |||
| class ResponseUser { | |||
| String? accessToken; | |||
| String? refreshToken; | |||
| int? expiresIn; | |||
| ResponseUser({this.accessToken, this.refreshToken, this.expiresIn}); | |||
| ResponseUser.fromJson(Map<String, dynamic> json) { | |||
| accessToken = json['id_token']; | |||
| refreshToken = json['refresh_token']; | |||
| expiresIn = json['expires_in']; | |||
| } | |||
| } | |||
| @@ -1,13 +0,0 @@ | |||
| import 'package:formz/formz.dart'; | |||
| enum UsernameValidationError { empty, notEmpty } | |||
| class Username extends FormzInput<String, UsernameValidationError> { | |||
| const Username.pure() : super.pure(''); | |||
| const Username.dirty([String value = '']) : super.dirty(value); | |||
| @override | |||
| UsernameValidationError validator(String value) { | |||
| return value?.isNotEmpty == true ? UsernameValidationError.notEmpty : UsernameValidationError.empty; | |||
| } | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| class ValidationModel { | |||
| String? value; | |||
| String? error; | |||
| ValidationModel(this.value, this.error); | |||
| } | |||
| @@ -1,173 +0,0 @@ | |||
| import 'package:farm_tpf/authentication/authentication.dart'; | |||
| import 'package:farm_tpf/data/repository/authentication_repository.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart'; | |||
| import 'package:farm_tpf/presentation/screens/forgot_password/sc_forgot_password.dart'; | |||
| import 'package:farm_tpf/presentation/screens/login/bloc/login_bloc.dart'; | |||
| import 'package:farm_tpf/utils/const_color.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:formz/formz.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| class LoginForm extends StatelessWidget { | |||
| late AuthenticationBloc _authenticationBloc; | |||
| FocusNode _usernameFocus = FocusNode(); | |||
| FocusNode _passwordFocus = FocusNode(); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| _authenticationBloc = BlocProvider.of<AuthenticationBloc>(context); | |||
| return BlocListener<LoginBloc, LoginState>( | |||
| listener: (context, state) { | |||
| if (state.status.isSubmissionFailure) { | |||
| LoadingDialog.hideLoadingDialog(context); | |||
| Utils.showSnackBarError(message: 'Tài khoản hoặc mật khẩu không đúng.'); | |||
| } | |||
| if (state.status.isSubmissionSuccess) { | |||
| LoadingDialog.hideLoadingDialog(context); | |||
| _authenticationBloc.add(const AuthenticationStatusChanged(AuthenticationStatus.authenticated)); | |||
| } | |||
| if (state.status.isSubmissionInProgress) { | |||
| LoadingDialog.showLoadingDialog(context); | |||
| } | |||
| }, | |||
| child: Align( | |||
| child: Column( | |||
| mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
| mainAxisSize: MainAxisSize.min, | |||
| children: [ | |||
| _UsernameInput(usernameFocus: _usernameFocus, nextFocus: _passwordFocus), | |||
| const Padding(padding: EdgeInsets.all(12)), | |||
| _PasswordInput( | |||
| passwordFocus: _passwordFocus, | |||
| ), | |||
| const Padding(padding: EdgeInsets.all(16)), | |||
| _LoginButton(), | |||
| const Padding(padding: EdgeInsets.all(6)), | |||
| _FogotPasswordButton(), | |||
| ], | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| class _FogotPasswordButton extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Align( | |||
| alignment: Alignment.center, | |||
| child: FlatButton( | |||
| child: Text('Quên mật khẩu', style: TextStyle(color: AppColors.BLUE, fontSize: 16)), | |||
| onPressed: () { | |||
| Navigator.of(context).push(MaterialPageRoute(builder: (_) => ForgotPasswordScreen())); | |||
| })); | |||
| } | |||
| } | |||
| class _UsernameInput extends StatelessWidget { | |||
| final FocusNode usernameFocus; | |||
| final FocusNode nextFocus; | |||
| _UsernameInput({required this.usernameFocus, required this.nextFocus}); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return BlocBuilder<LoginBloc, LoginState>( | |||
| buildWhen: (previous, current) => previous.username != current.username, | |||
| builder: (context, state) { | |||
| return Container( | |||
| height: 50, | |||
| padding: const EdgeInsets.symmetric(horizontal: 8), | |||
| child: Center( | |||
| child: TextFormField( | |||
| focusNode: usernameFocus, | |||
| textInputAction: TextInputAction.next, | |||
| onChanged: (username) => context.bloc<LoginBloc>().add(LoginUsernameChanged(username)), | |||
| // autovalidate: true, | |||
| validator: (_) { | |||
| return state.username.invalid ? 'Vui lòng nhập tài khoản' : null; | |||
| }, | |||
| onFieldSubmitted: (_) { | |||
| usernameFocus.unfocus(); | |||
| FocusScope.of(context).requestFocus(nextFocus); | |||
| }, | |||
| maxLines: 1, | |||
| keyboardType: TextInputType.text, | |||
| obscureText: false, | |||
| textAlign: TextAlign.left, | |||
| decoration: const InputDecoration( | |||
| hintText: 'Tài khoản', | |||
| ), | |||
| ), | |||
| )); | |||
| }, | |||
| ); | |||
| } | |||
| } | |||
| class _PasswordInput extends StatelessWidget { | |||
| final FocusNode passwordFocus; | |||
| _PasswordInput({required this.passwordFocus}); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return BlocBuilder<LoginBloc, LoginState>( | |||
| buildWhen: (previous, current) => previous.password != current.password, | |||
| builder: (context, state) { | |||
| return Container( | |||
| height: 50, | |||
| padding: const EdgeInsets.symmetric(horizontal: 8), | |||
| child: Center( | |||
| child: TextFormField( | |||
| focusNode: passwordFocus, | |||
| onChanged: (password) => context.bloc<LoginBloc>().add(LoginPasswordChanged(password)), | |||
| // autovalidate: true, | |||
| validator: (_) { | |||
| return state.password.invalid ? 'Vui lòng nhập mật khẩu' : null; | |||
| }, | |||
| onFieldSubmitted: (_) { | |||
| passwordFocus.unfocus(); | |||
| if (state.status.isValidated) { | |||
| context.bloc<LoginBloc>().add(const LoginSubmitted()); | |||
| } | |||
| }, | |||
| maxLines: 1, | |||
| keyboardType: TextInputType.text, | |||
| obscureText: true, | |||
| textAlign: TextAlign.left, | |||
| decoration: const InputDecoration( | |||
| hintText: 'Mật khẩu', | |||
| ), | |||
| ), | |||
| )); | |||
| }, | |||
| ); | |||
| } | |||
| } | |||
| class _LoginButton extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return BlocBuilder<LoginBloc, LoginState>( | |||
| buildWhen: (previous, current) => previous.status != current.status, | |||
| builder: (context, state) { | |||
| return SizedBox( | |||
| width: double.infinity, | |||
| height: 55, | |||
| child: FlatButton( | |||
| onPressed: () { | |||
| // if (state.status.isValidated) { | |||
| // context.bloc<LoginBloc>().add(const LoginSubmitted()); | |||
| // } | |||
| context.bloc<LoginBloc>().add(const LoginSubmitted()); | |||
| }, | |||
| color: state.status.isValidated ? AppColors.DEFAULT : AppColors.GRAY1_50, | |||
| shape: RoundedRectangleBorder( | |||
| borderRadius: BorderRadius.circular(7.0), | |||
| ), | |||
| child: Text('Đăng nhập'.toUpperCase(), style: TextStyle(fontWeight: FontWeight.bold, color: AppColors.WHITE, fontSize: 18)), | |||
| ), | |||
| ); | |||
| }, | |||
| ); | |||
| } | |||
| } | |||
| @@ -1,35 +0,0 @@ | |||
| import 'package:farm_tpf/data/repository/authentication_repository.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/camera_helper.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/nursery/sc_edit_action_nursery.dart'; | |||
| import 'package:farm_tpf/presentation/screens/login/bloc/login_bloc.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:get/get.dart'; | |||
| import 'package:keyboard_dismisser/keyboard_dismisser.dart'; | |||
| import 'login_form.dart'; | |||
| import 'widget_top_welcome.dart'; | |||
| class LoginPage extends StatelessWidget { | |||
| static Route route() { | |||
| return MaterialPageRoute<void>(builder: (_) => LoginPage()); | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) => KeyboardDismisser( | |||
| child: Scaffold( | |||
| body: Padding( | |||
| padding: const EdgeInsets.all(12), | |||
| child: BlocProvider( | |||
| create: (context) { | |||
| return LoginBloc( | |||
| authenticationRepository: RepositoryProvider.of<AuthenticationRepository>(context), | |||
| ); | |||
| }, | |||
| child: ListView( | |||
| children: <Widget>[WidgetTopWelcome(), LoginForm()], | |||
| ), | |||
| ), | |||
| ), | |||
| )); | |||
| } | |||
| @@ -1,2 +0,0 @@ | |||
| export 'login_form.dart'; | |||
| export 'login_page.dart'; | |||
| @@ -1,22 +0,0 @@ | |||
| import 'package:farm_tpf/utils/const_assets.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| class WidgetTopWelcome extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Column( | |||
| children: <Widget>[ | |||
| const SizedBox( | |||
| height: 80, | |||
| ), | |||
| SizedBox( | |||
| width: 180, | |||
| child: Image.asset(AppAssets.logoWithSlogan), | |||
| ), | |||
| const SizedBox( | |||
| height: 80, | |||
| ), | |||
| ], | |||
| ); | |||
| } | |||
| } | |||