add some features
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 8C0 4.22876 0 2.34315 1.17157 1.17157C2.34315 0 4.22876 0 8 0H24C27.7712 0 29.6569 0 30.8284 1.17157C32 2.34315 32 4.22876 32 8V24C32 27.7712 32 29.6569 30.8284 30.8284C29.6569 32 27.7712 32 24 32H8C4.22876 32 2.34315 32 1.17157 30.8284C0 29.6569 0 27.7712 0 24V8Z" fill="#5F5F5F"/>
|
||||
<path d="M18 21.28L13.6533 16.9333C13.14 16.42 13.14 15.58 13.6533 15.0666L18 10.72" stroke="#EAEAE9" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 591 B |
|
|
@ -0,0 +1,11 @@
|
|||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.5 2V5" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16.5 2V5" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M4 9.08997H21" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M22.5 19C22.5 19.75 22.29 20.46 21.92 21.06C21.23 22.22 19.96 23 18.5 23C17.49 23 16.57 22.63 15.87 22C15.56 21.74 15.29 21.42 15.08 21.06C14.71 20.46 14.5 19.75 14.5 19C14.5 16.79 16.29 15 18.5 15C19.7 15 20.77 15.53 21.5 16.36C22.12 17.07 22.5 17.99 22.5 19Z" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16.9399 19L17.9299 19.99L20.0599 18.02" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21.5 8.5V16.36C20.77 15.53 19.7 15 18.5 15C16.29 15 14.5 16.79 14.5 19C14.5 19.75 14.71 20.46 15.08 21.06C15.29 21.42 15.56 21.74 15.87 22H8.5C5 22 3.5 20 3.5 17V8.5C3.5 5.5 5 3.5 8.5 3.5H16.5C20 3.5 21.5 5.5 21.5 8.5Z" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M12.4955 13.7H12.5045" stroke="#2196F3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M8.79431 13.7H8.80329" stroke="#2196F3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M8.79443 16.7H8.80342" stroke="#2196F3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.75 2V5" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16.75 2V5" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M4.25 9.08997H21.25" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M22.75 19C22.75 19.75 22.54 20.46 22.17 21.06C21.48 22.22 20.21 23 18.75 23C17.74 23 16.82 22.63 16.12 22C15.81 21.74 15.54 21.42 15.33 21.06C14.96 20.46 14.75 19.75 14.75 19C14.75 16.79 16.54 15 18.75 15C19.95 15 21.02 15.53 21.75 16.36C22.37 17.07 22.75 17.99 22.75 19Z" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M17.1899 19L18.1799 19.99L20.3099 18.02" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21.75 8.5V16.36C21.02 15.53 19.95 15 18.75 15C16.54 15 14.75 16.79 14.75 19C14.75 19.75 14.96 20.46 15.33 21.06C15.54 21.42 15.81 21.74 16.12 22H8.75C5.25 22 3.75 20 3.75 17V8.5C3.75 5.5 5.25 3.5 8.75 3.5H16.75C20.25 3.5 21.75 5.5 21.75 8.5Z" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M12.7455 13.7H12.7545" stroke="#121110" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M9.04431 13.7H9.05329" stroke="#121110" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M9.04443 16.7H9.05342" stroke="#121110" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="18" height="19" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 17.4625C4.5525 17.4625 0.9375 13.8475 0.9375 9.40002C0.9375 4.95252 4.5525 1.33752 9 1.33752C13.4475 1.33752 17.0625 4.95252 17.0625 9.40002C17.0625 13.8475 13.4475 17.4625 9 17.4625ZM9 2.46252C5.175 2.46252 2.0625 5.57502 2.0625 9.40002C2.0625 13.225 5.175 16.3375 9 16.3375C12.825 16.3375 15.9375 13.225 15.9375 9.40002C15.9375 5.57502 12.825 2.46252 9 2.46252Z" fill="#292D32"/>
|
||||
<path d="M11.7822 12.3475C11.6847 12.3475 11.5872 12.325 11.4972 12.265L9.17224 10.8775C8.59474 10.5325 8.16724 9.77503 8.16724 9.10753V6.03253C8.16724 5.72503 8.42224 5.47003 8.72974 5.47003C9.03724 5.47003 9.29224 5.72503 9.29224 6.03253V9.10753C9.29224 9.37753 9.51724 9.77503 9.74974 9.91003L12.0747 11.2975C12.3447 11.455 12.4272 11.8 12.2697 12.07C12.1572 12.25 11.9697 12.3475 11.7822 12.3475Z" fill="#292D32"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 916 B |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.40771 16.6596C8.19021 16.6596 7.97271 16.6221 7.77021 16.5471C6.83271 16.2396 6.23271 15.2046 6.44271 14.2446L6.81021 11.8821C6.81771 11.8296 6.81771 11.7546 6.76521 11.6946C6.72771 11.6571 6.67521 11.6346 6.61521 11.6346H3.61521C2.88021 11.6346 2.24271 11.3271 1.86771 10.7946C1.50021 10.2771 1.42521 9.59463 1.66521 8.93463L3.45771 3.47463C3.73521 2.38713 4.89771 1.50963 6.09771 1.50963H8.94771C9.36771 1.50963 10.2827 1.63713 10.7702 2.12463L13.0427 3.87963L12.3527 4.77213L10.0277 2.97213C9.84021 2.78463 9.36771 2.63463 8.94771 2.63463H6.09771C5.42271 2.63463 4.69521 3.17463 4.54521 3.78213L2.73021 9.29463C2.61021 9.62463 2.63271 9.92463 2.79021 10.1421C2.95521 10.3746 3.25521 10.5096 3.62271 10.5096H6.62271C7.01271 10.5096 7.37271 10.6746 7.62021 10.9596C7.87521 11.2521 7.98771 11.6421 7.92771 12.0471L7.55271 14.4546C7.46271 14.8746 7.74771 15.3471 8.15271 15.4821C8.51271 15.6171 8.99271 15.4221 9.15771 15.1821L12.2327 10.6071L13.1627 11.2371L10.0877 15.8121C9.73521 16.3371 9.06771 16.6596 8.40771 16.6596Z" fill="#70706E"/>
|
||||
<path d="M15.0227 13.6596H14.2727C12.8852 13.6596 12.2102 13.0071 12.2102 11.6721V4.32213C12.2102 2.98713 12.8852 2.33463 14.2727 2.33463H15.0227C16.4102 2.33463 17.0852 2.98713 17.0852 4.32213V11.6721C17.0852 13.0071 16.4102 13.6596 15.0227 13.6596ZM14.2727 3.45963C13.4552 3.45963 13.3352 3.65463 13.3352 4.32213V11.6721C13.3352 12.3396 13.4552 12.5346 14.2727 12.5346H15.0227C15.8402 12.5346 15.9602 12.3396 15.9602 11.6721V4.32213C15.9602 3.65463 15.8402 3.45963 15.0227 3.45963H14.2727Z" fill="#70706E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 8C0 4.22876 0 2.34315 1.17157 1.17157C2.34315 0 4.22876 0 8 0H24C27.7712 0 29.6569 0 30.8284 1.17157C32 2.34315 32 4.22876 32 8V24C32 27.7712 32 29.6569 30.8284 30.8284C29.6569 32 27.7712 32 24 32H8C4.22876 32 2.34315 32 1.17157 30.8284C0 29.6569 0 27.7712 0 24V8Z" fill="#5F5F5F"/>
|
||||
<path d="M16.465 22.6075C16.21 22.6975 15.79 22.6975 15.535 22.6075C13.36 21.865 8.5 18.7675 8.5 13.5175C8.5 11.2 10.3675 9.32495 12.67 9.32495C14.035 9.32495 15.2425 9.98495 16 11.005C16.7575 9.98495 17.9725 9.32495 19.33 9.32495C21.6325 9.32495 23.5 11.2 23.5 13.5175C23.5 18.7675 18.64 21.865 16.465 22.6075Z" stroke="#EAEAE9" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 796 B |
|
|
@ -0,0 +1,12 @@
|
|||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.4">
|
||||
<path d="M10.0695 12.46L7.01953 15.51" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7.0498 12.4902L10.0998 15.5402" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<path opacity="0.4" d="M14.03 14H14.04" stroke="#2196F3" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M17.97 14H17.98" stroke="#2196F3" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M16 15.98V15.96" stroke="#2196F3" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M16 12.04V12.02" stroke="#2196F3" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.5 22H15.5C20.5 22 22.5 20 22.5 15V13C22.5 8 20.5 6 15.5 6H9.5C4.5 6 2.5 8 2.5 13V15C2.5 20 4.5 22 9.5 22Z" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13.51 2L13.5 3.01C13.49 3.56 13.05 4 12.5 4H12.47C11.92 4 11.48 4.45 11.48 5C11.48 5.55 11.93 6 12.48 6H13.48" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,12 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.4">
|
||||
<path d="M9.56953 12.46L6.51953 15.51" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.5498 12.4902L9.5998 15.5402" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<path opacity="0.4" d="M13.53 14H13.54" stroke="#121110" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M17.47 14H17.48" stroke="#121110" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M15.5 15.98V15.96" stroke="#121110" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M15.5 12.04V12.02" stroke="#121110" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9 22H15C20 22 22 20 22 15V13C22 8 20 6 15 6H9C4 6 2 8 2 13V15C2 20 4 22 9 22Z" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13.01 2L13 3.01C12.99 3.56 12.55 4 12 4H11.97C11.42 4 10.98 4.45 10.98 5C10.98 5.55 11.43 6 11.98 6H12.98" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.5177 16.6596H9.6677C9.2477 16.6596 8.3327 16.5321 7.8452 16.0446L5.5727 14.2896L6.2627 13.3971L8.5877 15.1971C8.7752 15.3771 9.2477 15.5271 9.6677 15.5271H12.5177C13.1927 15.5271 13.9202 14.9871 14.0702 14.3796L15.8852 8.86712C16.0052 8.53712 15.9827 8.23712 15.8252 8.01962C15.6602 7.78712 15.3602 7.65212 14.9927 7.65212H11.9927C11.6027 7.65212 11.2427 7.48712 10.9952 7.20212C10.7402 6.90962 10.6277 6.51962 10.6877 6.11462L11.0627 3.70712C11.1527 3.28712 10.8677 2.81462 10.4627 2.67962C10.0952 2.54462 9.6227 2.73962 9.4577 2.97962L6.3827 7.55462L5.4527 6.93212L8.5277 2.35712C9.0002 1.65212 10.0352 1.31462 10.8452 1.62212C11.7827 1.92962 12.3827 2.96462 12.1727 3.92462L11.8052 6.28712C11.7977 6.33962 11.7977 6.41462 11.8502 6.47462C11.8877 6.51212 11.9402 6.53462 12.0002 6.53462H15.0002C15.7352 6.53462 16.3727 6.84212 16.7477 7.37462C17.1152 7.89212 17.1902 8.57462 16.9502 9.23462L15.1577 14.6946C14.8802 15.7821 13.7252 16.6596 12.5177 16.6596Z" fill="#70706E"/>
|
||||
<path d="M4.34265 15.8346H3.59265C2.20515 15.8346 1.53015 15.1821 1.53015 13.8471V6.49713C1.53015 5.16213 2.20515 4.50963 3.59265 4.50963H4.34265C5.73015 4.50963 6.40515 5.16213 6.40515 6.49713V13.8471C6.40515 15.1821 5.73015 15.8346 4.34265 15.8346ZM3.59265 5.63463C2.77515 5.63463 2.65515 5.82963 2.65515 6.49713V13.8471C2.65515 14.5146 2.77515 14.7096 3.59265 14.7096H4.34265C5.16015 14.7096 5.28015 14.5146 5.28015 13.8471V6.49713C5.28015 5.82963 5.16015 5.63463 4.34265 5.63463H3.59265Z" fill="#70706E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22 9.00002V15C22 17.5 21.5 19.25 20.38 20.38L14 14L21.73 6.27002C21.91 7.06002 22 7.96002 22 9.00002Z" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21.73 6.27L6.26999 21.73C3.25999 21.04 2 18.96 2 15V9C2 4 4 2 9 2H15C18.96 2 21.04 3.26 21.73 6.27Z" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M20.38 20.38C19.25 21.5 17.5 22 15 22H9C7.96 22 7.05999 21.91 6.26999 21.73L14 14L20.38 20.38Z" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M6.23999 7.97997C6.91999 5.04997 11.32 5.04997 12 7.97997C12.39 9.69997 11.31 11.16 10.36 12.06C9.66998 12.72 8.58 12.72 7.88 12.06C6.93 11.16 5.83999 9.69997 6.23999 7.97997Z" stroke="#121110" stroke-width="1.5"/>
|
||||
<path opacity="0.4" d="M9.0946 8.70001H9.10359" stroke="#121110" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22 9.00002V15C22 17.5 21.5 19.25 20.38 20.38L14 14L21.73 6.27002C21.91 7.06002 22 7.96002 22 9.00002Z" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21.73 6.27L6.26999 21.73C3.25999 21.04 2 18.96 2 15V9C2 4 4 2 9 2H15C18.96 2 21.04 3.26 21.73 6.27Z" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M20.38 20.38C19.25 21.5 17.5 22 15 22H9C7.96 22 7.05999 21.91 6.26999 21.73L14 14L20.38 20.38Z" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M6.23999 7.97997C6.91999 5.04997 11.32 5.04997 12 7.97997C12.39 9.69997 11.31 11.16 10.36 12.06C9.66998 12.72 8.58 12.72 7.88 12.06C6.93 11.16 5.83999 9.69997 6.23999 7.97997Z" stroke="#2196F3" stroke-width="1.5"/>
|
||||
<path opacity="0.4" d="M9.0946 8.70001H9.10359" stroke="#2196F3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.4" d="M12.1601 10.87C12.0601 10.86 11.9401 10.86 11.8301 10.87C9.45006 10.79 7.56006 8.84 7.56006 6.44C7.56006 3.99 9.54006 2 12.0001 2C14.4501 2 16.4401 3.99 16.4401 6.44C16.4301 8.84 14.5401 10.79 12.1601 10.87Z" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7.15997 14.56C4.73997 16.18 4.73997 18.82 7.15997 20.43C9.90997 22.27 14.42 22.27 17.17 20.43C19.59 18.81 19.59 16.17 17.17 14.56C14.43 12.73 9.91997 12.73 7.15997 14.56Z" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 687 B |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.4" d="M12.1601 10.87C12.0601 10.86 11.9401 10.86 11.8301 10.87C9.45006 10.79 7.56006 8.84 7.56006 6.44C7.56006 3.99 9.54006 2 12.0001 2C14.4501 2 16.4401 3.99 16.4401 6.44C16.4301 8.84 14.5401 10.79 12.1601 10.87Z" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7.15997 14.56C4.73997 16.18 4.73997 18.82 7.15997 20.43C9.90997 22.27 14.42 22.27 17.17 20.43C19.59 18.81 19.59 16.17 17.17 14.56C14.43 12.73 9.91997 12.73 7.15997 14.56Z" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 687 B |
|
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22 6V8.42C22 10 21 11 19.42 11H16V4.01C16 2.9 16.91 2 18.02 2C19.11 2.01 20.11 2.45 20.83 3.17C21.55 3.9 22 4.9 22 6Z" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2 7V21C2 21.83 2.94 22.3 3.6 21.8L5.31 20.52C5.71 20.22 6.27 20.26 6.63 20.62L8.29 22.29C8.68 22.68 9.32 22.68 9.71 22.29L11.39 20.61C11.74 20.26 12.3 20.22 12.69 20.52L14.4 21.8C15.06 22.29 16 21.82 16 21V4C16 2.9 16.9 2 18 2H7H6C3 2 2 3.79 2 6V7Z" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M6.26999 13.73L11.73 8.27002" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M11.9247 13.5H11.9337" stroke="#2196F3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M6.1947 8.5H6.20368" stroke="#2196F3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,7 @@
|
|||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22.25 6V8.42C22.25 10 21.25 11 19.67 11H16.25V4.01C16.25 2.9 17.16 2 18.27 2C19.36 2.01 20.36 2.45 21.08 3.17C21.8 3.9 22.25 4.9 22.25 6Z" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.25 7V21C2.25 21.83 3.19 22.3 3.85 21.8L5.56 20.52C5.96 20.22 6.52 20.26 6.88 20.62L8.54 22.29C8.93 22.68 9.57 22.68 9.96 22.29L11.64 20.61C11.99 20.26 12.55 20.22 12.94 20.52L14.65 21.8C15.31 22.29 16.25 21.82 16.25 21V4C16.25 2.9 17.15 2 18.25 2H7.25H6.25C3.25 2 2.25 3.79 2.25 6V7Z" stroke="#121110" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M6.52 13.73L11.98 8.27002" stroke="#121110" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M12.1747 13.5H12.1837" stroke="#121110" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path opacity="0.4" d="M6.4447 8.5H6.45368" stroke="#121110" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,7 @@
|
|||
<svg width="18" height="19" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.13245 4.94165C3.71995 4.94165 3.38245 4.60415 3.38245 4.19165C3.38245 3.77915 3.71245 3.44165 4.13245 3.44165H4.13995C4.55245 3.44165 4.88995 3.77915 4.88995 4.19165C4.88995 4.60415 4.55245 4.94165 4.13245 4.94165Z" fill="#292D32"/>
|
||||
<path d="M13.8824 14.6917C13.4699 14.6917 13.1324 14.3542 13.1324 13.9417C13.1324 13.5292 13.4624 13.1917 13.8824 13.1917H13.8899C14.3024 13.1917 14.6399 13.5292 14.6399 13.9417C14.6399 14.3542 14.3024 14.6917 13.8824 14.6917Z" fill="#292D32"/>
|
||||
<path d="M4.10254 7.37915C2.34754 7.37915 0.915039 5.94665 0.915039 4.19165C0.915039 2.43665 2.34754 1.00415 4.10254 1.00415C5.85754 1.00415 7.29004 2.43665 7.29004 4.19165C7.29004 5.94665 5.86504 7.37915 4.10254 7.37915ZM4.10254 2.12915C2.96254 2.12915 2.04004 3.05165 2.04004 4.19165C2.04004 5.33165 2.96254 6.25415 4.10254 6.25415C5.24254 6.25415 6.16504 5.33165 6.16504 4.19165C6.16504 3.05165 5.24254 2.12915 4.10254 2.12915Z" fill="#292D32"/>
|
||||
<path d="M14.9775 17.1292H12.7275C11.5875 17.1292 10.665 16.2067 10.665 15.0667V12.8167C10.665 11.6767 11.5875 10.7542 12.7275 10.7542H14.9775C16.1175 10.7542 17.04 11.6767 17.04 12.8167V15.0667C17.04 16.2067 16.1175 17.1292 14.9775 17.1292ZM12.7275 11.8792C12.21 11.8792 11.79 12.2992 11.79 12.8167V15.0667C11.79 15.5842 12.21 16.0042 12.7275 16.0042H14.9775C15.495 16.0042 15.915 15.5842 15.915 15.0667V12.8167C15.915 12.2992 15.495 11.8792 14.9775 11.8792H12.7275Z" fill="#292D32"/>
|
||||
<path d="M8.99996 14.8792H6.98996C6.11996 14.8792 5.36246 14.3541 5.06246 13.5441C4.75496 12.7341 4.97996 11.8417 5.63246 11.2642L11.625 6.02165C11.985 5.70665 11.9925 5.27915 11.8875 4.98665C11.775 4.69415 11.49 4.37915 11.01 4.37915H8.99996C8.69246 4.37915 8.43746 4.12415 8.43746 3.81665C8.43746 3.50915 8.69246 3.25415 8.99996 3.25415H11.01C11.88 3.25415 12.6375 3.77915 12.9375 4.58915C13.245 5.39915 13.02 6.29165 12.3675 6.86915L6.37496 12.1117C6.01496 12.4267 6.00746 12.8542 6.11246 13.1467C6.22496 13.4392 6.50996 13.7542 6.98996 13.7542H8.99996C9.30746 13.7542 9.56246 14.0092 9.56246 14.3167C9.56246 14.6242 9.30746 14.8792 8.99996 14.8792Z" fill="#292D32"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="19" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.2976 2.83255L11.6176 5.47255C11.7976 5.84005 12.2776 6.19255 12.6826 6.26005L15.0751 6.65755C16.6051 6.91255 16.9651 8.02255 15.8626 9.11755L14.0026 10.9776C13.6876 11.2926 13.5151 11.9001 13.6126 12.3351L14.1451 14.6376C14.5651 16.4601 13.5976 17.1651 11.9851 16.2126L9.74255 14.8851C9.33755 14.6451 8.67005 14.6451 8.25755 14.8851L6.01505 16.2126C4.41005 17.1651 3.43505 16.4526 3.85505 14.6376L4.38755 12.3351C4.48505 11.9001 4.31255 11.2926 3.99755 10.9776L2.13755 9.11755C1.04255 8.02255 1.39505 6.91255 2.92505 6.65755L5.31755 6.26005C5.71505 6.19255 6.19505 5.84005 6.37505 5.47255L7.69505 2.83255C8.41505 1.40005 9.58505 1.40005 10.2976 2.83255Z" fill="#70BF73" stroke="#70BF73" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 852 B |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="18" height="19" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.2976 2.63248L11.6176 5.27248C11.7976 5.63998 12.2776 5.99248 12.6826 6.05998L15.0751 6.45748C16.6051 6.71248 16.9651 7.82248 15.8626 8.91748L14.0026 10.7775C13.6876 11.0925 13.5151 11.7 13.6126 12.135L14.1451 14.4375C14.5651 16.26 13.5976 16.965 11.9851 16.0125L9.74255 14.685C9.33755 14.445 8.67005 14.445 8.25755 14.685L6.01505 16.0125C4.41005 16.965 3.43505 16.2525 3.85505 14.4375L4.38755 12.135C4.48505 11.7 4.31255 11.0925 3.99755 10.7775L2.13755 8.91748C1.04255 7.82248 1.39505 6.71248 2.92505 6.45748L5.31755 6.05998C5.71505 5.99248 6.19505 5.63998 6.37505 5.27248L7.69505 2.63248C8.41505 1.19998 9.58505 1.19998 10.2976 2.63248Z" stroke="#70BF73" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M14.025 11.245C13.755 11.515 13.605 12.0325 13.695 12.4L14.2125 14.6575C14.43 15.595 14.295 16.3 13.83 16.6375C13.6425 16.7725 13.4175 16.84 13.155 16.84C12.7725 16.84 12.3225 16.6975 11.8275 16.405L9.62998 15.1C9.28498 14.8975 8.71498 14.8975 8.36998 15.1L6.17248 16.405C5.33998 16.8925 4.62748 16.975 4.16998 16.6375C3.99748 16.51 3.86998 16.3375 3.78748 16.1125L12.9075 6.99251C13.2525 6.64751 13.74 6.49001 14.2125 6.57251L14.97 6.70001C15.765 6.83501 16.2975 7.19501 16.47 7.72001C16.635 8.24501 16.41 8.85251 15.84 9.42251L14.025 11.245Z" fill="#70BF73"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="21" height="22" viewBox="0 0 21 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.75 16.9H11.25C15 16.9 16.5 15.4 16.5 11.65V7.15002C16.5 3.40002 15 1.90002 11.25 1.90002H6.75C3 1.90002 1.5 3.40002 1.5 7.15002V11.65C1.5 15.4 3 16.9 6.75 16.9Z" stroke="#2A2926" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.8125 9.40003L7.935 11.5225L12.1875 7.27753" stroke="#2A2926" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 465 B |
|
After Width: | Height: | Size: 199 KiB |
|
|
@ -0,0 +1,49 @@
|
|||
class WorkingHours {
|
||||
final String day;
|
||||
final List<Shift> shifts;
|
||||
|
||||
WorkingHours({
|
||||
required this.day,
|
||||
required this.shifts,
|
||||
});
|
||||
|
||||
factory WorkingHours.fromJson(Map<String, dynamic> json) {
|
||||
return WorkingHours(
|
||||
day: json['day'],
|
||||
shifts: (json['shifts'] as List)
|
||||
.map((shift) => Shift.fromJson(shift))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'day': day,
|
||||
'shifts': shifts.map((shift) => shift.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class Shift {
|
||||
final String openAt;
|
||||
final String closeAt;
|
||||
|
||||
Shift({
|
||||
required this.openAt,
|
||||
required this.closeAt,
|
||||
});
|
||||
|
||||
factory Shift.fromJson(Map<String, dynamic> json) {
|
||||
return Shift(
|
||||
openAt: json['open_at'],
|
||||
closeAt: json['close_at'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'open_at': openAt,
|
||||
'close_at': closeAt,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,10 @@ class $AssetsIconsGen {
|
|||
/// File path: assets/icons/Line 4.svg
|
||||
SvgGenImage get line4 => const SvgGenImage('assets/icons/Line 4.svg');
|
||||
|
||||
/// File path: assets/icons/MDS-Public-TW-Button.svg
|
||||
SvgGenImage get mDSPublicTWButton =>
|
||||
const SvgGenImage('assets/icons/MDS-Public-TW-Button.svg');
|
||||
|
||||
/// File path: assets/icons/MDS-Public-TW-Tag.svg
|
||||
SvgGenImage get mDSPublicTWTag =>
|
||||
const SvgGenImage('assets/icons/MDS-Public-TW-Tag.svg');
|
||||
|
|
@ -55,6 +59,14 @@ class $AssetsIconsGen {
|
|||
/// File path: assets/icons/back.svg
|
||||
SvgGenImage get back => const SvgGenImage('assets/icons/back.svg');
|
||||
|
||||
/// File path: assets/icons/calendar-tick 2.svg
|
||||
SvgGenImage get calendarTick2 =>
|
||||
const SvgGenImage('assets/icons/calendar-tick 2.svg');
|
||||
|
||||
/// File path: assets/icons/calendar-tick.svg
|
||||
SvgGenImage get calendarTick =>
|
||||
const SvgGenImage('assets/icons/calendar-tick.svg');
|
||||
|
||||
/// File path: assets/icons/card-pos.svg
|
||||
SvgGenImage get cardPos => const SvgGenImage('assets/icons/card-pos.svg');
|
||||
|
||||
|
|
@ -64,9 +76,15 @@ class $AssetsIconsGen {
|
|||
/// File path: assets/icons/clander.svg
|
||||
SvgGenImage get clander => const SvgGenImage('assets/icons/clander.svg');
|
||||
|
||||
/// File path: assets/icons/clock.svg
|
||||
SvgGenImage get clock => const SvgGenImage('assets/icons/clock.svg');
|
||||
|
||||
/// File path: assets/icons/coin.svg
|
||||
SvgGenImage get coin => const SvgGenImage('assets/icons/coin.svg');
|
||||
|
||||
/// File path: assets/icons/dislike.svg
|
||||
SvgGenImage get dislike => const SvgGenImage('assets/icons/dislike.svg');
|
||||
|
||||
/// File path: assets/icons/down.svg
|
||||
SvgGenImage get down => const SvgGenImage('assets/icons/down.svg');
|
||||
|
||||
|
|
@ -74,10 +92,19 @@ class $AssetsIconsGen {
|
|||
SvgGenImage get elementEqual =>
|
||||
const SvgGenImage('assets/icons/element-equal.svg');
|
||||
|
||||
/// File path: assets/icons/favorite.svg
|
||||
SvgGenImage get favorite => const SvgGenImage('assets/icons/favorite.svg');
|
||||
|
||||
/// File path: assets/icons/fluent-color_location-ripple-16.svg
|
||||
SvgGenImage get fluentColorLocationRipple16 =>
|
||||
const SvgGenImage('assets/icons/fluent-color_location-ripple-16.svg');
|
||||
|
||||
/// File path: assets/icons/game 2.svg
|
||||
SvgGenImage get game2 => const SvgGenImage('assets/icons/game 2.svg');
|
||||
|
||||
/// File path: assets/icons/game.svg
|
||||
SvgGenImage get game => const SvgGenImage('assets/icons/game.svg');
|
||||
|
||||
/// File path: assets/icons/ic_round-local-offer.svg
|
||||
SvgGenImage get icRoundLocalOffer =>
|
||||
const SvgGenImage('assets/icons/ic_round-local-offer.svg');
|
||||
|
|
@ -85,6 +112,9 @@ class $AssetsIconsGen {
|
|||
/// File path: assets/icons/infoPic.svg
|
||||
SvgGenImage get infoPic => const SvgGenImage('assets/icons/infoPic.svg');
|
||||
|
||||
/// File path: assets/icons/like.svg
|
||||
SvgGenImage get like => const SvgGenImage('assets/icons/like.svg');
|
||||
|
||||
/// File path: assets/icons/list.svg
|
||||
SvgGenImage get list => const SvgGenImage('assets/icons/list.svg');
|
||||
|
||||
|
|
@ -126,12 +156,32 @@ class $AssetsIconsGen {
|
|||
SvgGenImage get materialSymbolsLocationWork =>
|
||||
const SvgGenImage('assets/icons/material-symbols_location-work.svg');
|
||||
|
||||
/// File path: assets/icons/nearby.svg
|
||||
SvgGenImage get nearby => const SvgGenImage('assets/icons/nearby.svg');
|
||||
|
||||
/// File path: assets/icons/nearby2.svg
|
||||
SvgGenImage get nearby2 => const SvgGenImage('assets/icons/nearby2.svg');
|
||||
|
||||
/// File path: assets/icons/next.svg
|
||||
SvgGenImage get next => const SvgGenImage('assets/icons/next.svg');
|
||||
|
||||
/// File path: assets/icons/ph_cheese.svg
|
||||
SvgGenImage get phCheese => const SvgGenImage('assets/icons/ph_cheese.svg');
|
||||
|
||||
/// File path: assets/icons/profile 2.svg
|
||||
SvgGenImage get profile2 => const SvgGenImage('assets/icons/profile 2.svg');
|
||||
|
||||
/// File path: assets/icons/profile.svg
|
||||
SvgGenImage get profile => const SvgGenImage('assets/icons/profile.svg');
|
||||
|
||||
/// File path: assets/icons/receipt-discount 2.svg
|
||||
SvgGenImage get receiptDiscount2 =>
|
||||
const SvgGenImage('assets/icons/receipt-discount 2.svg');
|
||||
|
||||
/// File path: assets/icons/receipt-discount.svg
|
||||
SvgGenImage get receiptDiscount =>
|
||||
const SvgGenImage('assets/icons/receipt-discount.svg');
|
||||
|
||||
/// File path: assets/icons/recenter.svg
|
||||
SvgGenImage get recenter => const SvgGenImage('assets/icons/recenter.svg');
|
||||
|
||||
|
|
@ -139,6 +189,9 @@ class $AssetsIconsGen {
|
|||
SvgGenImage get riSearch2Line =>
|
||||
const SvgGenImage('assets/icons/ri_search-2-line.svg');
|
||||
|
||||
/// File path: assets/icons/routing-2.svg
|
||||
SvgGenImage get routing2 => const SvgGenImage('assets/icons/routing-2.svg');
|
||||
|
||||
/// File path: assets/icons/routing.svg
|
||||
SvgGenImage get routing => const SvgGenImage('assets/icons/routing.svg');
|
||||
|
||||
|
|
@ -162,9 +215,18 @@ class $AssetsIconsGen {
|
|||
/// File path: assets/icons/sort.svg
|
||||
SvgGenImage get sort => const SvgGenImage('assets/icons/sort.svg');
|
||||
|
||||
/// File path: assets/icons/star fill.svg
|
||||
SvgGenImage get starFill => const SvgGenImage('assets/icons/star fill.svg');
|
||||
|
||||
/// File path: assets/icons/star half.svg
|
||||
SvgGenImage get starHalf => const SvgGenImage('assets/icons/star half.svg');
|
||||
|
||||
/// File path: assets/icons/star.svg
|
||||
SvgGenImage get star => const SvgGenImage('assets/icons/star.svg');
|
||||
|
||||
/// File path: assets/icons/tick.svg
|
||||
SvgGenImage get tick => const SvgGenImage('assets/icons/tick.svg');
|
||||
|
||||
/// File path: assets/icons/timer-pause.svg
|
||||
SvgGenImage get timerPause =>
|
||||
const SvgGenImage('assets/icons/timer-pause.svg');
|
||||
|
|
@ -180,6 +242,7 @@ class $AssetsIconsGen {
|
|||
List<SvgGenImage> get values => [
|
||||
line1,
|
||||
line4,
|
||||
mDSPublicTWButton,
|
||||
mDSPublicTWTag,
|
||||
nextButton,
|
||||
rectangleOff,
|
||||
|
|
@ -190,15 +253,23 @@ class $AssetsIconsGen {
|
|||
arrowDown,
|
||||
arrowLeft,
|
||||
back,
|
||||
calendarTick2,
|
||||
calendarTick,
|
||||
cardPos,
|
||||
category2,
|
||||
clander,
|
||||
clock,
|
||||
coin,
|
||||
dislike,
|
||||
down,
|
||||
elementEqual,
|
||||
favorite,
|
||||
fluentColorLocationRipple16,
|
||||
game2,
|
||||
game,
|
||||
icRoundLocalOffer,
|
||||
infoPic,
|
||||
like,
|
||||
list,
|
||||
location,
|
||||
mapSelected,
|
||||
|
|
@ -210,10 +281,17 @@ class $AssetsIconsGen {
|
|||
materialSymbolsLocationOn,
|
||||
materialSymbolsLocationOnn,
|
||||
materialSymbolsLocationWork,
|
||||
nearby,
|
||||
nearby2,
|
||||
next,
|
||||
phCheese,
|
||||
profile2,
|
||||
profile,
|
||||
receiptDiscount2,
|
||||
receiptDiscount,
|
||||
recenter,
|
||||
riSearch2Line,
|
||||
routing2,
|
||||
routing,
|
||||
selectedList,
|
||||
shoppingCart,
|
||||
|
|
@ -221,7 +299,10 @@ class $AssetsIconsGen {
|
|||
slide3,
|
||||
slides1,
|
||||
sort,
|
||||
starFill,
|
||||
starHalf,
|
||||
star,
|
||||
tick,
|
||||
timerPause,
|
||||
timerStart,
|
||||
timer,
|
||||
|
|
@ -265,6 +346,10 @@ class $AssetsImagesGen {
|
|||
/// File path: assets/images/userinfo.svg
|
||||
SvgGenImage get userinfo => const SvgGenImage('assets/images/userinfo.svg');
|
||||
|
||||
/// File path: assets/images/wp1929534-fast-food-wallpapers 1.png
|
||||
AssetGenImage get wp1929534FastFoodWallpapers1 =>
|
||||
const AssetGenImage('assets/images/wp1929534-fast-food-wallpapers 1.png');
|
||||
|
||||
/// List of all assets
|
||||
List<dynamic> get values => [
|
||||
frame,
|
||||
|
|
@ -277,6 +362,7 @@ class $AssetsImagesGen {
|
|||
topDealsAndStores,
|
||||
usa,
|
||||
userinfo,
|
||||
wp1929534FastFoodWallpapers1,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ class MyApp extends StatelessWidget {
|
|||
dialogTheme: DialogTheme(
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
dropdownMenuTheme: DropdownMenuThemeData(
|
||||
menuStyle: MenuStyle(
|
||||
backgroundColor: MaterialStatePropertyAll(Colors.white),
|
||||
),
|
||||
),
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
labelStyle: TextStyle(color: Colors.black),
|
||||
hintStyle: TextStyle(color: Colors.grey),
|
||||
|
|
|
|||
|
|
@ -13,4 +13,8 @@ class LightAppColors{
|
|||
static const confirmPopup = Color.fromARGB(255, 23, 107,173);
|
||||
static const nearbyPopup = Color.fromARGB(255, 233, 245,254);
|
||||
static const nearbyPopuphint = Color.fromARGB(255, 112, 112, 110);
|
||||
static const productDetailDivider = Color.fromARGB(255, 112, 112, 110);
|
||||
static const fillOrder = Color.fromARGB(255, 200, 230, 201);
|
||||
static const fillOrderText = Color.fromARGB(255, 32, 74, 34);
|
||||
static const allReviewOpener = Color.fromARGB(255, 183, 28, 28);
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'auth_state.dart';
|
||||
|
||||
|
|
@ -10,40 +8,20 @@ class AuthCubit extends Cubit<AuthState> {
|
|||
String _timeStamp = "";
|
||||
String _timeDue = "";
|
||||
|
||||
final Dio _dio = Dio(BaseOptions(
|
||||
connectTimeout: const Duration(seconds: 30),
|
||||
receiveTimeout: const Duration(seconds: 30),
|
||||
));
|
||||
|
||||
String get timeStamp => _timeStamp;
|
||||
String get timeDue => _timeDue;
|
||||
|
||||
Future<void> sendOTP(String phoneNumber) async {
|
||||
emit(AuthLoading());
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
'https://api-gateway.liara.run/auth/otp/generate',
|
||||
data: {'userId': phoneNumber},
|
||||
);
|
||||
print(response.toString());
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
if (response.data['success'] == true) {
|
||||
_timeStamp = response.data['timestamp'].toString();
|
||||
_timeDue = response.data['due'].toString();
|
||||
emit(AuthSuccess(phoneNumber: phoneNumber));
|
||||
print(response.data.toString());
|
||||
} else {
|
||||
emit(AuthError('Failed to send OTP'));
|
||||
}
|
||||
} else {
|
||||
emit(AuthError('Server error: \${response.statusCode}'));
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
emit(AuthError('Connection error: \${e.message}'));
|
||||
} catch (e) {
|
||||
emit(AuthError('Unexpected error occurred'));
|
||||
}
|
||||
|
||||
// Simulate API delay
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
|
||||
// Mock data for development
|
||||
_timeStamp = DateTime.now().millisecondsSinceEpoch.toString();
|
||||
_timeDue = DateTime.now().add(const Duration(minutes: 2)).millisecondsSinceEpoch.toString();
|
||||
|
||||
emit(AuthSuccess(phoneNumber: phoneNumber));
|
||||
}
|
||||
|
||||
void verifyOTP(String otpCode) {}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class _OnboardingScreenState extends State<OnboardingScreen> {
|
|||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(width / 15, 0, width / 15, width/30),
|
||||
padding: EdgeInsets.fromLTRB(width / 15, 0, width / 15, width / 30),
|
||||
child: Text(
|
||||
'"Join the app to discover exclusive discounts and special offers in specific areas around you for a smarter shopping experience!"',
|
||||
style: TextStyle(fontWeight: FontWeight.w500, color: LightAppColors.hint, fontSize: 15),
|
||||
|
|
@ -98,8 +98,7 @@ class _OnboardingScreenState extends State<OnboardingScreen> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 300),
|
||||
transitionBuilder: (child, animation) => FadeTransition(opacity: animation, child: child),
|
||||
duration: Duration(milliseconds: 200),
|
||||
child: SvgPicture.asset(
|
||||
slides[currentIndex],
|
||||
key: ValueKey(slides[currentIndex]),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||
import 'package:lba/extension/screenSize.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
import 'package:lba/screens/nearby/nearby.dart';
|
||||
import 'package:lba/screens/mains/navigation/navigation.dart';
|
||||
import 'package:lba/screens/mains/nearby/mainNearby/nearby.dart';
|
||||
import 'package:lba/widgets/button.dart';
|
||||
import 'package:lba/widgets/datePicker.dart';
|
||||
|
||||
|
|
@ -37,18 +38,21 @@ class _UserInfoState extends State<UserInfo> {
|
|||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 24),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 0,
|
||||
vertical: 24,
|
||||
),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.images.userinfo.path,
|
||||
height: height /2.9,
|
||||
height: height / 2.9,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: height/20),
|
||||
SizedBox(height: height / 20),
|
||||
const Padding(
|
||||
padding: EdgeInsets.fromLTRB(25, 0, 25, 20),
|
||||
child: Text(
|
||||
|
|
@ -66,13 +70,16 @@ class _UserInfoState extends State<UserInfo> {
|
|||
counterText: '',
|
||||
hintText: "Enter here...",
|
||||
hintStyle: TextStyle(
|
||||
fontWeight: FontWeight.normal, color: Colors.grey),
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.grey,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Color.fromARGB(255, 250, 250, 250),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
borderSide:
|
||||
BorderSide(color: Color.fromARGB(255, 14, 63, 102)),
|
||||
borderSide: BorderSide(
|
||||
color: Color.fromARGB(255, 14, 63, 102),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
|
|
@ -95,66 +102,98 @@ class _UserInfoState extends State<UserInfo> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25),
|
||||
child: Wrap(
|
||||
spacing: 5,
|
||||
spacing: 3,
|
||||
alignment: WrapAlignment.start,
|
||||
runSpacing: 2,
|
||||
runAlignment: WrapAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text("Prefer not to say",
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Radio<String>(
|
||||
value: "Prefer not to say",
|
||||
groupValue: selectedGender,
|
||||
activeColor: Colors.blue,
|
||||
visualDensity: VisualDensity.compact,
|
||||
materialTapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
selectedGender = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
const Text(
|
||||
"Prefer not to say",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 112, 112, 110))),
|
||||
Radio<String>(
|
||||
value: "Prefer not to say",
|
||||
groupValue: selectedGender,
|
||||
activeColor: Colors.blue,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
selectedGender = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
color: Color.fromARGB(255, 112, 112, 110),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text("Male",
|
||||
SizedBox(width: 5,),
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Radio<String>(
|
||||
value: "Male",
|
||||
groupValue: selectedGender,
|
||||
activeColor: Colors.blue,
|
||||
visualDensity: VisualDensity.compact,
|
||||
materialTapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
selectedGender = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
const Text(
|
||||
"Male",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 112, 112, 110))),
|
||||
Radio<String>(
|
||||
value: "Male",
|
||||
groupValue: selectedGender,
|
||||
activeColor: Colors.blue,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
selectedGender = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
color: Color.fromARGB(255, 112, 112, 110),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text("Female",
|
||||
SizedBox(width: 5,),
|
||||
Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Radio<String>(
|
||||
value: "Female",
|
||||
groupValue: selectedGender,
|
||||
activeColor: Colors.blue,
|
||||
visualDensity: VisualDensity.compact,
|
||||
materialTapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
selectedGender = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
const Text(
|
||||
"Female",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 112, 112, 110))),
|
||||
Radio<String>(
|
||||
value: "Female",
|
||||
groupValue: selectedGender,
|
||||
activeColor: Colors.blue,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
selectedGender = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
color: Color.fromARGB(255, 112, 112, 110),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: height/12),
|
||||
SizedBox(height: height / 8),
|
||||
// const Padding(
|
||||
// padding: EdgeInsets.fromLTRB(25, 0, 25, 15),
|
||||
// child: Text(
|
||||
|
|
@ -225,16 +264,19 @@ class _UserInfoState extends State<UserInfo> {
|
|||
// const SizedBox(height: 30),
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: width*0.9,
|
||||
width: width * 0.9,
|
||||
child: Button(
|
||||
text: "Submit",
|
||||
onPressed: () {
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => const Nearby()),
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const MainScreen(),
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
}, color: const Color.fromARGB(255, 30, 137, 221),
|
||||
},
|
||||
color: const Color.fromARGB(255, 30, 137, 221),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -242,7 +284,7 @@ class _UserInfoState extends State<UserInfo> {
|
|||
onTap: () {
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => const Nearby()),
|
||||
MaterialPageRoute(builder: (context) => const MainScreen()),
|
||||
(route) => false,
|
||||
);
|
||||
},
|
||||
|
|
@ -253,18 +295,19 @@ class _UserInfoState extends State<UserInfo> {
|
|||
child: Text(
|
||||
"Skip",
|
||||
style: TextStyle(
|
||||
color: LightAppColors.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16),
|
||||
color: LightAppColors.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class Discover extends StatelessWidget {
|
||||
const Discover({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class Hunt extends StatelessWidget {
|
||||
const Hunt({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
import 'package:lba/screens/mains/discover/discover.dart';
|
||||
import 'package:lba/screens/mains/hunt/hunt.dart';
|
||||
import 'package:lba/screens/mains/nearby/mainNearby/nearby.dart';
|
||||
import 'package:lba/screens/mains/planner/planner.dart';
|
||||
import 'package:lba/screens/mains/profile/profile.dart';
|
||||
|
||||
class MainScreen extends StatefulWidget {
|
||||
const MainScreen({super.key});
|
||||
|
||||
@override
|
||||
State<MainScreen> createState() => _MainScreenState();
|
||||
}
|
||||
|
||||
class _MainScreenState extends State<MainScreen> {
|
||||
int _currentIndex = 0;
|
||||
|
||||
final List<Widget> _screens = [
|
||||
Nearby(),
|
||||
Discover(),
|
||||
Hunt(),
|
||||
Planner(),
|
||||
Profile(),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
extendBody: true,
|
||||
body: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: _screens[_currentIndex],
|
||||
),
|
||||
bottomNavigationBar: CustomBottomNavigationBar(
|
||||
onTap: (int index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
},
|
||||
currentIndex: _currentIndex,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomBottomNavigationBar extends StatefulWidget {
|
||||
final Function(int) onTap;
|
||||
final int currentIndex;
|
||||
|
||||
const CustomBottomNavigationBar({
|
||||
super.key,
|
||||
required this.onTap,
|
||||
required this.currentIndex,
|
||||
});
|
||||
|
||||
@override
|
||||
State<CustomBottomNavigationBar> createState() => _CustomBottomNavigationBarState();
|
||||
}
|
||||
|
||||
class _CustomBottomNavigationBarState extends State<CustomBottomNavigationBar>
|
||||
with SingleTickerProviderStateMixin {
|
||||
final List<_NavItem> items = [
|
||||
_NavItem('Nearby', Assets.icons.nearby.path, Assets.icons.nearby2.path),
|
||||
_NavItem('Discover', Assets.icons.receiptDiscount.path, Assets.icons.receiptDiscount2.path),
|
||||
_NavItem('Hunt', Assets.icons.game.path, Assets.icons.game2.path),
|
||||
_NavItem('Planner', Assets.icons.calendarTick.path, Assets.icons.calendarTick2.path),
|
||||
_NavItem('Profile', Assets.icons.profile.path, Assets.icons.profile2.path),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
||||
child: Container(
|
||||
height: 70,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.15),
|
||||
blurRadius: 20,
|
||||
offset: const Offset(0, 10),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: List.generate(items.length, (index) {
|
||||
final item = items[index];
|
||||
final bool isSelected = index == widget.currentIndex;
|
||||
return GestureDetector(
|
||||
onTap: () => widget.onTap(index),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOutQuint,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? const Color(0xFFE3F2FD) : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: SvgPicture.asset(
|
||||
isSelected ? item.selectedIconPath : item.iconPath,
|
||||
key: ValueKey<bool>(isSelected),
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOut,
|
||||
child: isSelected
|
||||
? Row(
|
||||
children: [
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
item.label,
|
||||
style: const TextStyle(
|
||||
color: LightAppColors.primary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: const SizedBox(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _NavItem {
|
||||
final String label;
|
||||
final String iconPath;
|
||||
final String selectedIconPath;
|
||||
|
||||
_NavItem(this.label, this.iconPath, this.selectedIconPath);
|
||||
}
|
||||
|
|
@ -46,21 +46,7 @@ class NearbyItems extends StatelessWidget {
|
|||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
detailsType==0?"Highest Discount Areas":detailsType==1?"Highest Discount Areas":detailsType==2?"Best Deal, Don't Miss":"",
|
||||
style: TextStyle(fontSize: 15),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Expanded(
|
||||
child: Divider(color: Colors.grey, thickness: 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
DividerTitle(detailsType: detailsType),
|
||||
SizedBox(
|
||||
height: detailsType==0?180:detailsType==1?240:detailsType==2?240:200,
|
||||
child: ListView.builder(
|
||||
|
|
@ -184,3 +170,31 @@ class NearbyItems extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DividerTitle extends StatelessWidget {
|
||||
const DividerTitle({
|
||||
super.key,
|
||||
required this.detailsType,
|
||||
});
|
||||
|
||||
final int detailsType;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
detailsType==0?"Highest Discount Areas":detailsType==1?"Highest Discount Areas":detailsType==2?"Best Deal, Don't Miss":"",
|
||||
style: TextStyle(fontSize: 15),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Expanded(
|
||||
child: Divider(color: Colors.grey, thickness: 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:lba/extension/screenSize.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/widgets/orderType.dart';
|
||||
import 'package:lba/widgets/remainingTime.dart';
|
||||
|
||||
class ListScreen extends StatefulWidget {
|
||||
final bool delivery;
|
||||
final bool pickup;
|
||||
int initialTimerStatus;
|
||||
final String expiryTimeString;
|
||||
final VoidCallback? ontap;
|
||||
|
||||
ListScreen({
|
||||
super.key,
|
||||
required this.delivery,
|
||||
required this.pickup,
|
||||
this.initialTimerStatus=3,
|
||||
required this.expiryTimeString,
|
||||
this.ontap,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ListScreen> createState() => _ListScreenState();
|
||||
}
|
||||
|
||||
class _ListScreenState extends State<ListScreen> {
|
||||
late RemainingTime _timer;
|
||||
late ValueNotifier<int> _timerStatus;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_timer = RemainingTime();
|
||||
_timerStatus = ValueNotifier<int>(widget.initialTimerStatus);
|
||||
_timer.initializeFromExpiry(expiryTimeString: widget.expiryTimeString);
|
||||
|
||||
_timer.remainingSeconds.addListener(() {
|
||||
if (_timer.remainingSeconds.value <= 0) {
|
||||
_timerStatus.value = 3;
|
||||
} else if (_timer.remainingSeconds.value < 18000) {
|
||||
_timerStatus.value = 1;
|
||||
} else if (_timer.remainingSeconds.value > 18000) {
|
||||
_timerStatus.value = 2;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_timer.dispose();
|
||||
_timerStatus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final width = context.screenWidth;
|
||||
final height = context.screenHeight;
|
||||
return
|
||||
GestureDetector(
|
||||
onTap: widget.ontap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 60),
|
||||
padding: const EdgeInsets.only(top: 80),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color.fromARGB(255, 242, 242, 241),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.fromLTRB(12, 0, width/50, 15),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(Assets.icons.phCheese.path),
|
||||
const SizedBox(width: 5),
|
||||
const Text(
|
||||
"Amul Cheese Slices",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.location.path,
|
||||
color: const Color.fromARGB(255, 157, 157, 155),
|
||||
width: 14,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
const Text("Sharjah (750m away)",style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500
|
||||
),),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.coin.path,
|
||||
width: 14,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: const [
|
||||
Text(
|
||||
"18.15 AED",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 157, 157, 155),
|
||||
fontSize: 10,
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 0),
|
||||
Row(
|
||||
children: [
|
||||
Text("15.84 AED",style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500
|
||||
),),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
"(13% off)",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 76, 175, 80),
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(0, 35, widget.delivery == false || widget.pickup == false ? width/5 : width/60, 0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.star.path,
|
||||
width: 14,
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
const Text(
|
||||
"4.8",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 112, 112, 110),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
if (widget.delivery)
|
||||
OrderType(
|
||||
icon: Assets.icons.cardPos.path,
|
||||
typename: "Delivery",
|
||||
fill: false,
|
||||
),
|
||||
if (widget.delivery) const SizedBox(width: 5),
|
||||
if (widget.pickup)
|
||||
OrderType(
|
||||
icon: Assets.icons.shoppingCart.path,
|
||||
typename: "Pickup",
|
||||
fill: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topRight: Radius.circular(10),
|
||||
topLeft: Radius.circular(10),
|
||||
),
|
||||
child: Image.asset(
|
||||
Assets.images.media.path,
|
||||
width: double.infinity,
|
||||
height: 130,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 10,
|
||||
left: 10,
|
||||
child: ValueListenableBuilder<int>(
|
||||
valueListenable: _timerStatus,
|
||||
builder: (context, timerStatus, child) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
color: timerStatus == 1
|
||||
? const Color.fromARGB(255, 255, 193, 7)
|
||||
: timerStatus == 2
|
||||
? const Color.fromARGB(255, 76, 175, 80)
|
||||
: timerStatus == 3
|
||||
? const Color.fromARGB(255, 244, 67, 54)
|
||||
: const Color.fromARGB(255, 244, 67, 54),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
timerStatus == 1
|
||||
? Assets.icons.timer.path
|
||||
: timerStatus == 2
|
||||
? Assets.icons.timerStart.path
|
||||
: Assets.icons.timerPause.path,
|
||||
width: 12,
|
||||
height: 12,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
ValueListenableBuilder<int>(
|
||||
valueListenable: _timer.remainingSeconds,
|
||||
builder: (context, seconds, child) {
|
||||
return Text(
|
||||
timerStatus==3? "Unavailable":"${_timer.formatTime()} left",
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,8 @@ import 'package:flutter_map/flutter_map.dart';
|
|||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
import 'package:lba/screens/nearby/bestNearby.dart';
|
||||
import 'package:lba/screens/mains/nearby/bestNearby.dart';
|
||||
import 'package:lba/screens/product/productdetail.dart';
|
||||
import 'package:location/location.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
|
|
@ -87,7 +88,6 @@ class _CustomMapState extends State<CustomMap>
|
|||
_initializeMarkers();
|
||||
_checkLocationServices();
|
||||
|
||||
// Initialize AnimationController
|
||||
_animationController = AnimationController(
|
||||
duration: const Duration(milliseconds: 500),
|
||||
vsync: this,
|
||||
|
|
@ -206,7 +206,6 @@ class _CustomMapState extends State<CustomMap>
|
|||
right: 0,
|
||||
child: Column(
|
||||
children: [
|
||||
// Recenter Button
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
|
|
@ -248,162 +247,98 @@ class _CustomMapState extends State<CustomMap>
|
|||
],
|
||||
),
|
||||
),
|
||||
// Marker Details
|
||||
if (_selectedMarkerIndex == null)
|
||||
Container(
|
||||
height: 190,
|
||||
height: 245,
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.only(bottom: 25,left: 8),
|
||||
padding: const EdgeInsets.only(bottom: 90,left: 0),
|
||||
child: Center(
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: _manualMarkers.length,
|
||||
itemBuilder: (context, index) {
|
||||
final marker = _manualMarkers[index];
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 5),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: LightAppColors.nearbyPopup,
|
||||
border: Border.all(color: Colors.white, width: 2.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(11),
|
||||
),
|
||||
child: Image.asset(Assets.images.image.path),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
marker.name,
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
"${marker.place} ${marker.distance}",
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
marker.description,
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
fontSize: 10,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.mDSPublicTWTag.path,
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
"(15%) 43 - 36.55 AED ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => Productdetail(),));
|
||||
},
|
||||
child: CustomCard(marker: marker),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 5),
|
||||
padding: const EdgeInsets.all(8.0).copyWith(bottom: 15),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: LightAppColors.nearbyPopup,
|
||||
border: Border.all(color: Colors.white, width: 2.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(11),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 90,right: 8,left: 8,),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 5),
|
||||
padding: const EdgeInsets.all(8.0).copyWith(bottom: 15),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: LightAppColors.nearbyPopup,
|
||||
border: Border.all(color: Colors.white, width: 4.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(11),
|
||||
),
|
||||
child: Image.asset(Assets.images.image.path),
|
||||
),
|
||||
child: Image.asset(Assets.images.image.path),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_manualMarkers[_selectedMarkerIndex!].name,
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
"${_manualMarkers[_selectedMarkerIndex!].place} ${_manualMarkers[_selectedMarkerIndex!].distance}",
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_manualMarkers[_selectedMarkerIndex!].name,
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
_manualMarkers[_selectedMarkerIndex!]
|
||||
.description,
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
fontSize: 10,
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
"${_manualMarkers[_selectedMarkerIndex!].place} ${_manualMarkers[_selectedMarkerIndex!].distance}",
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
_manualMarkers[_selectedMarkerIndex!]
|
||||
.description,
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
fontSize: 10,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset(Assets.icons.mDSPublicTWTag.path),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
"(15%) 43 - 36.55 AED ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset(Assets.icons.mDSPublicTWTag.path),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
"(15%) 43 - 36.55 AED ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -455,7 +390,94 @@ class _CustomMapState extends State<CustomMap>
|
|||
}
|
||||
}
|
||||
|
||||
// Helper class for animating LatLng
|
||||
class CustomCard extends StatelessWidget {
|
||||
const CustomCard({
|
||||
super.key,
|
||||
required this.marker,
|
||||
});
|
||||
|
||||
final MarkerData marker;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 5),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: LightAppColors.nearbyPopup,
|
||||
border: Border.all(color: Colors.white, width: 4.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(11),
|
||||
),
|
||||
child: Image.asset(Assets.images.image.path),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
marker.name,
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
"${marker.place} ${marker.distance}",
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
marker.description,
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
fontSize: 10,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.mDSPublicTWTag.path,
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
"(15%) 43 - 36.55 AED ",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LatLngTween extends Tween<LatLng> {
|
||||
LatLngTween({required LatLng begin, required LatLng end})
|
||||
: super(begin: begin, end: end);
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/screens/nearby/listScreen.dart';
|
||||
import 'package:lba/screens/nearby/map.dart';
|
||||
import 'package:lba/screens/mains/nearby/mainNearby/listScreen.dart';
|
||||
import 'package:lba/screens/mains/nearby/mainNearby/map.dart';
|
||||
import 'package:lba/screens/product/productdetail.dart';
|
||||
import 'package:lba/widgets/customBottomSheet.dart';
|
||||
import 'package:lba/widgets/gpsPopup.dart';
|
||||
|
||||
|
|
@ -36,7 +37,6 @@ class _NearbyState extends State<Nearby> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 70,
|
||||
|
|
@ -114,8 +114,7 @@ class _NearbyState extends State<Nearby> {
|
|||
),
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
body:
|
||||
Column(
|
||||
body: Column(
|
||||
children: [
|
||||
_buildToggleButtons(),
|
||||
Container(
|
||||
|
|
@ -124,9 +123,7 @@ class _NearbyState extends State<Nearby> {
|
|||
color: const Color.fromARGB(255, 14, 63, 102),
|
||||
),
|
||||
Expanded(
|
||||
child: selectedIndex == 1
|
||||
? _buildListContent()
|
||||
: CustomMap(),
|
||||
child: selectedIndex == 1 ? _buildListContent() : CustomMap(),
|
||||
),
|
||||
// ElevatedButton(
|
||||
// onPressed: () => showGPSDialog(context),
|
||||
|
|
@ -180,33 +177,39 @@ class _NearbyState extends State<Nearby> {
|
|||
Positioned(
|
||||
left: 0,
|
||||
child: _buildToggleButton(
|
||||
color: selectedIndex == 1
|
||||
? const Color.fromARGB(255, 10, 69, 117)
|
||||
: const Color.fromARGB(100, 177, 177, 177),
|
||||
color:
|
||||
selectedIndex == 1
|
||||
? const Color.fromARGB(255, 10, 69, 117)
|
||||
: const Color.fromARGB(100, 177, 177, 177),
|
||||
icon: Assets.icons.elementEqual.path,
|
||||
iconColor: selectedIndex == 1
|
||||
? const Color.fromARGB(255, 234, 245, 254)
|
||||
: const Color.fromARGB(255, 157, 157, 155),
|
||||
iconColor:
|
||||
selectedIndex == 1
|
||||
? const Color.fromARGB(255, 234, 245, 254)
|
||||
: const Color.fromARGB(255, 157, 157, 155),
|
||||
text: 'list',
|
||||
isSelected: selectedIndex == 1,
|
||||
onTap: () => setState(() => selectedIndex = 1),
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(12),
|
||||
bottomLeft: Radius.circular(12),
|
||||
topRight: selectedIndex==1? Radius.circular(12):Radius.zero,
|
||||
bottomRight: selectedIndex==1? Radius.circular(12):Radius.zero,
|
||||
topRight:
|
||||
selectedIndex == 1 ? Radius.circular(12) : Radius.zero,
|
||||
bottomRight:
|
||||
selectedIndex == 1 ? Radius.circular(12) : Radius.zero,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
child: _buildToggleButton(
|
||||
color: selectedIndex == 0
|
||||
? const Color.fromARGB(255, 10, 69, 117)
|
||||
: const Color.fromARGB(100, 177, 177, 177),
|
||||
iconColor: selectedIndex == 0
|
||||
? const Color.fromARGB(255, 234, 245, 254)
|
||||
: const Color.fromARGB(255, 157, 157, 155),
|
||||
color:
|
||||
selectedIndex == 0
|
||||
? const Color.fromARGB(255, 10, 69, 117)
|
||||
: const Color.fromARGB(100, 177, 177, 177),
|
||||
iconColor:
|
||||
selectedIndex == 0
|
||||
? const Color.fromARGB(255, 234, 245, 254)
|
||||
: const Color.fromARGB(255, 157, 157, 155),
|
||||
icon: Assets.icons.mapSelected.path,
|
||||
text: 'map',
|
||||
isSelected: selectedIndex == 0,
|
||||
|
|
@ -214,8 +217,10 @@ class _NearbyState extends State<Nearby> {
|
|||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(12),
|
||||
bottomRight: Radius.circular(12),
|
||||
bottomLeft: selectedIndex==0? Radius.circular(12):Radius.zero,
|
||||
topLeft: selectedIndex==0? Radius.circular(12):Radius.zero,
|
||||
bottomLeft:
|
||||
selectedIndex == 0 ? Radius.circular(12) : Radius.zero,
|
||||
topLeft:
|
||||
selectedIndex == 0 ? Radius.circular(12) : Radius.zero,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -245,6 +250,8 @@ class _NearbyState extends State<Nearby> {
|
|||
child: SvgPicture.asset(Assets.icons.arrowDown.path),
|
||||
),
|
||||
elevation: 16,
|
||||
dropdownColor:
|
||||
Colors.white,
|
||||
style: const TextStyle(
|
||||
color: Color.fromARGB(255, 33, 150, 243),
|
||||
fontWeight: FontWeight.w500,
|
||||
|
|
@ -255,12 +262,13 @@ class _NearbyState extends State<Nearby> {
|
|||
selectedOption = newValue!;
|
||||
});
|
||||
},
|
||||
items: options.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
items:
|
||||
options.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
@ -268,7 +276,12 @@ class _NearbyState extends State<Nearby> {
|
|||
ListScreen(
|
||||
delivery: true,
|
||||
pickup: false,
|
||||
expiryTimeString: "2025-05-17T13:20:49.623619357Z",
|
||||
expiryTimeString: "2025-05-19T13:30:49.623619357Z",
|
||||
ontap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => Productdetail()),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListScreen(
|
||||
delivery: false,
|
||||
|
|
@ -280,6 +293,7 @@ class _NearbyState extends State<Nearby> {
|
|||
pickup: true,
|
||||
expiryTimeString: "2025-05-12T13:20:37.435249520Z",
|
||||
),
|
||||
const SizedBox(height: 90),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -287,76 +301,77 @@ class _NearbyState extends State<Nearby> {
|
|||
}
|
||||
|
||||
Widget _buildToggleButton({
|
||||
required String text,
|
||||
required bool isSelected,
|
||||
required VoidCallback onTap,
|
||||
required BorderRadius borderRadius,
|
||||
required Color color,
|
||||
required String icon,
|
||||
required Color iconColor,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
width: 170,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: borderRadius,
|
||||
color: isSelected
|
||||
? const Color.fromARGB(255, 14, 63, 102)
|
||||
: const Color.fromARGB(255, 234, 234, 233),
|
||||
boxShadow: isSelected
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 2),
|
||||
required String text,
|
||||
required bool isSelected,
|
||||
required VoidCallback onTap,
|
||||
required BorderRadius borderRadius,
|
||||
required Color color,
|
||||
required String icon,
|
||||
required Color iconColor,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
width: 170,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: borderRadius,
|
||||
color:
|
||||
isSelected
|
||||
? const Color.fromARGB(255, 14, 63, 102)
|
||||
: const Color.fromARGB(255, 234, 234, 233),
|
||||
boxShadow:
|
||||
isSelected
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 30,
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: color,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(1.0),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(icon, color: iconColor),
|
||||
),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 30,
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(1.0),
|
||||
child: Center(child: SvgPicture.asset(icon, color: iconColor)),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color: isSelected ? Colors.white : Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color: isSelected ? Colors.white : Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isSelected)
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: SvgPicture.asset(
|
||||
Assets.icons.shape.path,
|
||||
height: 4,
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (isSelected)
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: SvgPicture.asset(Assets.icons.shape.path, height: 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class Planner extends StatelessWidget {
|
||||
const Planner({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class Profile extends StatelessWidget {
|
||||
const Profile({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:lba/extension/screenSize.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/widgets/orderType.dart';
|
||||
import 'package:lba/widgets/remainingTime.dart';
|
||||
|
||||
class ListScreen extends StatefulWidget {
|
||||
final bool delivery;
|
||||
final bool pickup;
|
||||
int initialTimerStatus;
|
||||
final String expiryTimeString;
|
||||
|
||||
ListScreen({
|
||||
super.key,
|
||||
required this.delivery,
|
||||
required this.pickup,
|
||||
this.initialTimerStatus=3,
|
||||
required this.expiryTimeString,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ListScreen> createState() => _ListScreenState();
|
||||
}
|
||||
|
||||
class _ListScreenState extends State<ListScreen> {
|
||||
late RemainingTime _timer;
|
||||
late ValueNotifier<int> _timerStatus;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_timer = RemainingTime();
|
||||
_timerStatus = ValueNotifier<int>(widget.initialTimerStatus);
|
||||
_timer.initializeFromExpiry(expiryTimeString: widget.expiryTimeString);
|
||||
|
||||
_timer.remainingSeconds.addListener(() {
|
||||
if (_timer.remainingSeconds.value <= 0) {
|
||||
_timerStatus.value = 3;
|
||||
} else if (_timer.remainingSeconds.value < 18000) {
|
||||
_timerStatus.value = 1;
|
||||
} else if (_timer.remainingSeconds.value > 18000) {
|
||||
_timerStatus.value = 2;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_timer.dispose();
|
||||
_timerStatus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final width = context.screenWidth;
|
||||
final height = context.screenHeight;
|
||||
return
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 60),
|
||||
padding: const EdgeInsets.only(top: 80),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color.fromARGB(255, 242, 242, 241),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.fromLTRB(12, 0, width/50, 15),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(Assets.icons.phCheese.path),
|
||||
const SizedBox(width: 5),
|
||||
const Text(
|
||||
"Amul Cheese Slices",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.location.path,
|
||||
color: const Color.fromARGB(255, 157, 157, 155),
|
||||
width: 14,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
const Text("Sharjah (750m away)",style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500
|
||||
),),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.coin.path,
|
||||
width: 14,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: const [
|
||||
Text(
|
||||
"18.15 AED",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 157, 157, 155),
|
||||
fontSize: 10,
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 0),
|
||||
Row(
|
||||
children: [
|
||||
Text("15.84 AED",style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500
|
||||
),),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
"(13% off)",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 76, 175, 80),
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(0, 35, widget.delivery == false || widget.pickup == false ? width/5 : width/60, 0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.star.path,
|
||||
width: 14,
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
const Text(
|
||||
"4.8",
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 112, 112, 110),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
if (widget.delivery)
|
||||
OrderType(
|
||||
icon: Assets.icons.cardPos.path,
|
||||
typename: "Delivery",
|
||||
),
|
||||
if (widget.delivery) const SizedBox(width: 5),
|
||||
if (widget.pickup)
|
||||
OrderType(
|
||||
icon: Assets.icons.shoppingCart.path,
|
||||
typename: "Pickup",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topRight: Radius.circular(10),
|
||||
topLeft: Radius.circular(10),
|
||||
),
|
||||
child: Image.asset(
|
||||
Assets.images.media.path,
|
||||
width: double.infinity,
|
||||
height: 130,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 10,
|
||||
left: 10,
|
||||
child: ValueListenableBuilder<int>(
|
||||
valueListenable: _timerStatus,
|
||||
builder: (context, timerStatus, child) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
color: timerStatus == 1
|
||||
? const Color.fromARGB(255, 255, 193, 7)
|
||||
: timerStatus == 2
|
||||
? const Color.fromARGB(255, 76, 175, 80)
|
||||
: timerStatus == 3
|
||||
? const Color.fromARGB(255, 244, 67, 54)
|
||||
: const Color.fromARGB(255, 244, 67, 54),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
timerStatus == 1
|
||||
? Assets.icons.timer.path
|
||||
: timerStatus == 2
|
||||
? Assets.icons.timerStart.path
|
||||
: Assets.icons.timerPause.path,
|
||||
width: 12,
|
||||
height: 12,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
ValueListenableBuilder<int>(
|
||||
valueListenable: _timer.remainingSeconds,
|
||||
builder: (context, seconds, child) {
|
||||
return Text(
|
||||
timerStatus==3? "Unavailable":"${_timer.formatTime()} left",
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
import 'package:lba/widgets/buildWarpedInfo.dart';
|
||||
import 'package:lba/widgets/orderType.dart';
|
||||
import 'package:lba/widgets/rate.dart';
|
||||
import 'package:lba/widgets/reviews.dart';
|
||||
|
||||
class Item extends StatefulWidget {
|
||||
String title;
|
||||
String brand;
|
||||
String dimensions;
|
||||
String colour;
|
||||
String material;
|
||||
String description;
|
||||
|
||||
Item({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.brand,
|
||||
required this.dimensions,
|
||||
required this.colour,
|
||||
required this.material,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
@override
|
||||
State<Item> createState() => _ItemState();
|
||||
}
|
||||
|
||||
class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||
bool showAllReviews = false;
|
||||
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
|
||||
|
||||
final List<Map<String, dynamic>> reviews = [
|
||||
{
|
||||
"name": "Sara M",
|
||||
"comment":
|
||||
'"Super happy with my new sofa from Chattels & More! 🙻✨ Great quality, smooth delivery, and helpful staff. Totally worth it!" 😍👌',
|
||||
"rate": 5.0,
|
||||
"yesCount": 2,
|
||||
"noCount": 0,
|
||||
"date": "Jun 09, 2025",
|
||||
},
|
||||
{
|
||||
"name": "Khalid A",
|
||||
"comment":
|
||||
'"Nice design but poor delivery experience 😕🕐 Had to wait extra days and deal with missing parts. Expected better for the price." 👎💸',
|
||||
"rate": 1.0,
|
||||
"yesCount": 5,
|
||||
"noCount": 10,
|
||||
"date": "Dec 26, 2024",
|
||||
},
|
||||
{
|
||||
"name": "Khalid A",
|
||||
"comment":
|
||||
'"Nice design but poor delivery experience 😕🕐 Had to wait extra days and deal with missing parts. Expected better for the price." 👎💸',
|
||||
"rate": 3.0,
|
||||
"yesCount": 5,
|
||||
"noCount": 10,
|
||||
"date": "Dec 26, 2024",
|
||||
},
|
||||
{
|
||||
"name": "Sara M",
|
||||
"comment":
|
||||
'"Super happy with my new sofa from Chattels & More! 🙻✨ Great quality, smooth delivery, and helpful staff. Totally worth it!" 😍👌',
|
||||
"rate": 4.0,
|
||||
"yesCount": 2,
|
||||
"noCount": 0,
|
||||
"date": "Jun 09, 2025",
|
||||
},
|
||||
];
|
||||
|
||||
List<Map<String, dynamic>> displayedReviews = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
displayedReviews = reviews.length > 2 ? reviews.sublist(0, 2) : List.from(reviews);
|
||||
}
|
||||
|
||||
void _showAllReviewsWithAnimation() async {
|
||||
final newItems = reviews.sublist(displayedReviews.length);
|
||||
for (int i = 0; i < newItems.length; i++) {
|
||||
await Future.delayed(Duration(milliseconds: 150));
|
||||
displayedReviews.add(newItems[i]);
|
||||
_listKey.currentState?.insertItem(displayedReviews.length - 1);
|
||||
setState(() {});
|
||||
}
|
||||
setState(() {
|
||||
showAllReviews = true;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
widget.title,
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Row(
|
||||
children: [
|
||||
Text("Brand: "),
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.brand,
|
||||
style: TextStyle(color: LightAppColors.primary),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
CustomStarRating(rating: 4.8),
|
||||
SizedBox(width: 3),
|
||||
Text(
|
||||
"4.8",
|
||||
style: TextStyle(color: LightAppColors.productDetailDivider),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Row(
|
||||
children: [
|
||||
OrderType(
|
||||
icon: Assets.icons.cardPos.path,
|
||||
typename: "Delivery",
|
||||
fill: true,
|
||||
),
|
||||
SizedBox(width: 7),
|
||||
OrderType(
|
||||
icon: Assets.icons.shoppingCart.path,
|
||||
typename: "Pickup",
|
||||
fill: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
buildWrappedInfo("Dimensions:", widget.dimensions),
|
||||
buildWrappedInfo("Colour:", widget.colour),
|
||||
buildWrappedInfo("Material:", widget.material),
|
||||
buildWrappedInfo("Description:", widget.description),
|
||||
SizedBox(height: 30),
|
||||
Center(
|
||||
child: Text(
|
||||
"Top reviews from the United Arab Emirates",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
|
||||
AnimatedList(
|
||||
key: _listKey,
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
initialItemCount: displayedReviews.length,
|
||||
itemBuilder: (context, index, animation) {
|
||||
final review = displayedReviews[index];
|
||||
return SizeTransition(
|
||||
sizeFactor: animation,
|
||||
axisAlignment: -1,
|
||||
child: Reviews(
|
||||
name: review['name'],
|
||||
comment: review['comment'],
|
||||
rate: review['rate'],
|
||||
yesCount: review['yesCount'],
|
||||
noCount: review['noCount'],
|
||||
date: review['date'],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
if (!showAllReviews && reviews.length > 2)
|
||||
Column(
|
||||
children: [
|
||||
Center(
|
||||
child: InkWell(
|
||||
onTap: _showAllReviewsWithAnimation,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"See all reviews",
|
||||
style: TextStyle(
|
||||
color: LightAppColors.allReviewOpener,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
SvgPicture.asset(
|
||||
Assets.icons.arrowDown.path,
|
||||
color: LightAppColors.allReviewOpener,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 50,)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:lba/data/model/workingHours.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
import 'package:lba/screens/product/item.dart';
|
||||
import 'package:lba/screens/product/shop.dart';
|
||||
|
||||
class Productdetail extends StatefulWidget {
|
||||
const Productdetail({super.key});
|
||||
|
||||
@override
|
||||
State<Productdetail> createState() => _ProductdetailState();
|
||||
}
|
||||
|
||||
class _ProductdetailState extends State<Productdetail>
|
||||
with SingleTickerProviderStateMixin {
|
||||
String selectedImage = Assets.images.media.path;
|
||||
int selectedIndex = 0;
|
||||
|
||||
final List<String> imageList = [
|
||||
Assets.images.media.path,
|
||||
Assets.images.topDealsAndStores.path,
|
||||
Assets.images.image.path,
|
||||
Assets.images.topDealsAndStores.path,
|
||||
];
|
||||
|
||||
late AnimationController _controller;
|
||||
late Animation<double> _fadeAnimation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
);
|
||||
_fadeAnimation = CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
_controller.forward();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onToggleTap(int index) {
|
||||
setState(() {
|
||||
selectedIndex = index;
|
||||
_controller.forward(from: 0);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 400,
|
||||
width: double.infinity,
|
||||
child: Stack(
|
||||
children: [
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: Image.asset(
|
||||
selectedImage,
|
||||
key: ValueKey<String>(selectedImage),
|
||||
fit: BoxFit.cover,
|
||||
height: 350,
|
||||
width: double.infinity,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 40,
|
||||
left: 16,
|
||||
child: IconButton(
|
||||
icon: SvgPicture.asset(
|
||||
Assets.icons.mDSPublicTWButton.path,
|
||||
),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 40,
|
||||
right: 16,
|
||||
child: IconButton(
|
||||
icon: SvgPicture.asset(Assets.icons.favorite.path),
|
||||
onPressed: () {},
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
height: 105,
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, -2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
itemCount: imageList.length,
|
||||
separatorBuilder:
|
||||
(_, __) => const SizedBox(width: 8),
|
||||
itemBuilder: (context, index) {
|
||||
final img = imageList[index];
|
||||
final isSelected = selectedImage == img;
|
||||
return GestureDetector(
|
||||
onTap:
|
||||
() => setState(() => selectedImage = img),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color:
|
||||
isSelected
|
||||
? LightAppColors.confirmButton
|
||||
: Colors.transparent,
|
||||
width: 2,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: ColorFiltered(
|
||||
colorFilter:
|
||||
selectedIndex == 1 &&
|
||||
isSelected == false
|
||||
? ColorFilter.matrix(<double>[
|
||||
0.2126,
|
||||
0.7152,
|
||||
0.0722,
|
||||
0,
|
||||
0,
|
||||
0.2126,
|
||||
0.7152,
|
||||
0.0722,
|
||||
0,
|
||||
0,
|
||||
0.2126,
|
||||
0.7152,
|
||||
0.0722,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
])
|
||||
: ColorFilter.mode(
|
||||
Colors.transparent,
|
||||
BlendMode.dstOut,
|
||||
),
|
||||
child: Image.asset(
|
||||
img,
|
||||
width: 100,
|
||||
height: 100,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SizedBox(
|
||||
width: 350,
|
||||
height: 50,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildToggleButton(
|
||||
text: 'Item',
|
||||
isSelected: selectedIndex == 0,
|
||||
onTap: () => _onToggleTap(0),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: _buildToggleButton(
|
||||
text: 'Shop',
|
||||
isSelected: selectedIndex == 1,
|
||||
onTap: () => _onToggleTap(1),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: const Divider(thickness: 1.2, height: 2),
|
||||
),
|
||||
FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child:
|
||||
selectedIndex == 0
|
||||
? Item(
|
||||
title: "Bosse Swivel Chair - Nature",
|
||||
brand: "Papadatos",
|
||||
dimensions: "L 59 cm | D 69 cm | H 89 cm",
|
||||
colour:
|
||||
"Navy Blue, Burnt Sienna, Mustard Yellow, Olive Green",
|
||||
material:
|
||||
" Cover: Polyester, Frame construction: Plywood Lacquered, Foot/Base: Oak Solid wood Lacquered, Upholstering: 28 kg/m³ Polyurethane",
|
||||
description:
|
||||
"A dining chair which swivels through 360 degrees offers a number of advantages. It allows easy movement and flexibility when sitting, which increases comfort and makes it easier to reach different areas around the table. A swivel chair in the dining room also makes it easier to sit down and get up, even where space is a little limited. This largely eliminates the hassle of moving dining chairs around. In addition, the swivel function encourages dynamic interaction during meals or conversations.",
|
||||
)
|
||||
: Shop(
|
||||
shopName: "Chattels & More",
|
||||
star: 3.6,
|
||||
place: "Mall of the Emirates، City Centre Mirdif",
|
||||
branches: [
|
||||
"Mall of the Emirates، City Centre Mirdif",
|
||||
"UEA",
|
||||
],
|
||||
|
||||
workingHours: [
|
||||
WorkingHours(
|
||||
day: 'mo',
|
||||
shifts: [Shift(openAt: '01:00', closeAt: '23:00')],
|
||||
),
|
||||
WorkingHours(
|
||||
day: 'tu',
|
||||
shifts: [Shift(openAt: '09:00', closeAt: '17:00')],
|
||||
),
|
||||
WorkingHours(
|
||||
day: 'fr',
|
||||
shifts: [
|
||||
Shift(openAt: '09:00', closeAt: '12:00'),
|
||||
Shift(openAt: '14:00', closeAt: '18:00'),
|
||||
],
|
||||
),
|
||||
],
|
||||
facilities: "White Glove Delivery Service",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildToggleButton({
|
||||
required String text,
|
||||
required bool isSelected,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
height: 50,
|
||||
color: Colors.white,
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color:
|
||||
isSelected
|
||||
? LightAppColors.primary
|
||||
: LightAppColors.productDetailDivider,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isSelected)
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: SvgPicture.asset(
|
||||
Assets.icons.shape.path,
|
||||
height: 5,
|
||||
color: LightAppColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:lba/data/model/workingHours.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
import 'package:lba/widgets/customCard.dart';
|
||||
import 'package:lba/widgets/dividerTitle.dart';
|
||||
import 'package:lba/widgets/openChecker.dart';
|
||||
import 'package:lba/widgets/rate.dart';
|
||||
import 'package:maps_launcher/maps_launcher.dart';
|
||||
|
||||
class Shop extends StatefulWidget {
|
||||
final String shopName;
|
||||
final double star;
|
||||
final String place;
|
||||
final List<String> branches;
|
||||
final List<WorkingHours> workingHours;
|
||||
final String facilities;
|
||||
|
||||
const Shop({
|
||||
super.key,
|
||||
required this.shopName,
|
||||
required this.star,
|
||||
required this.place,
|
||||
required this.branches,
|
||||
required this.workingHours,
|
||||
required this.facilities,
|
||||
});
|
||||
|
||||
@override
|
||||
State<Shop> createState() => _ShopState();
|
||||
}
|
||||
|
||||
class _ShopState extends State<Shop> {
|
||||
late String selectedPlace;
|
||||
bool isActiveOffer = true;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
selectedPlace = widget.place;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final now = DateTime.now();
|
||||
final schedule = IsOpenChecker.getTodaySchedule(widget.workingHours);
|
||||
final isOpen = IsOpenChecker.isOpenNow(widget.workingHours);
|
||||
|
||||
String timeRange = '';
|
||||
if (isOpen && schedule.shifts.isNotEmpty) {
|
||||
for (final shift in schedule.shifts) {
|
||||
timeRange +=
|
||||
'${formatTime12Hour(shift.openAt)} - ${formatTime12Hour(shift.closeAt)} ';
|
||||
}
|
||||
}
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.shop.path,
|
||||
color: Colors.black,
|
||||
height: 25,
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
widget.shopName,
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 17),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Row(
|
||||
children: [
|
||||
CustomStarRating(rating: widget.star),
|
||||
SizedBox(width: 5),
|
||||
Text(
|
||||
widget.star.toString(),
|
||||
style: TextStyle(color: LightAppColors.productDetailDivider),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.location.path,
|
||||
color: Colors.black,
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Text(
|
||||
selectedPlace,
|
||||
style: TextStyle(
|
||||
color: LightAppColors.productDetailDivider,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
PopupMenuButton<String>(
|
||||
color: Colors.white,
|
||||
icon: SvgPicture.asset(
|
||||
Assets.icons.arrowDown.path,
|
||||
color: Colors.black,
|
||||
height: 20,
|
||||
),
|
||||
onSelected: (String newPlace) {
|
||||
setState(() {
|
||||
selectedPlace = newPlace;
|
||||
});
|
||||
},
|
||||
itemBuilder: (BuildContext context) {
|
||||
return widget.branches.map((String branch) {
|
||||
return PopupMenuItem<String>(
|
||||
value: branch,
|
||||
child: Text(branch),
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(Assets.icons.clock.path),
|
||||
SizedBox(width: 5),
|
||||
Text(
|
||||
isOpen ? 'Open Now' : 'Closed',
|
||||
style: TextStyle(color: isOpen ? Colors.green : Colors.red),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Container(
|
||||
color: LightAppColors.productDetailDivider,
|
||||
width: 1,
|
||||
height: 13,
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Text(
|
||||
timeRange,
|
||||
style: TextStyle(color: LightAppColors.productDetailDivider),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
DividerTitleWidget(title: "Facilities"),
|
||||
SizedBox(
|
||||
height: 50,
|
||||
child: ListView.builder(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: 1,
|
||||
itemBuilder: (context, index) {
|
||||
return Row(
|
||||
children: [
|
||||
SvgPicture.asset(Assets.icons.tick.path),
|
||||
SizedBox(width: 5),
|
||||
Text(
|
||||
widget.facilities,
|
||||
style: TextStyle(
|
||||
color: LightAppColors.productDetailDivider,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: LightAppColors.confirmButton,
|
||||
minimumSize: const Size(double.infinity, 48),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
MapsLauncher.launchCoordinates(25.2399, 55.2744);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.routing2.path,
|
||||
color: Colors.black,
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Text(
|
||||
"Direction",
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
Text(
|
||||
"List of offers",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Container(
|
||||
height: 45,
|
||||
width: 150,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: const Color.fromARGB(17, 77, 77, 77),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isActiveOffer = true;
|
||||
});
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: Container(
|
||||
height: 35,
|
||||
width: 70,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: isActiveOffer ? Colors.white : Colors.transparent,
|
||||
),
|
||||
child: Center(child: Text("Active")),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isActiveOffer = false;
|
||||
});
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: Container(
|
||||
height: 35,
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: !isActiveOffer ? Colors.white : Colors.transparent,
|
||||
),
|
||||
child: Center(child: Text("Old")),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
SizedBox(
|
||||
height: 160,
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
shrinkWrap: true,
|
||||
itemCount: 2,
|
||||
itemBuilder: (context, index) {
|
||||
return CustomCard(
|
||||
title: "Calamaro Table Lamp",
|
||||
description: "Elegant lighting with a modern twist.",
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
|
||||
Widget buildWrappedInfo(String label, String value) {
|
||||
List<String> lines = value.split('\n');
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
style: TextStyle(color: LightAppColors.productDetailDivider),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '$label ',
|
||||
style: TextStyle(color: LightAppColors.confirmButton),
|
||||
),
|
||||
TextSpan(
|
||||
text: lines.first,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (lines.length > 1)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: Text(
|
||||
lines.skip(1).join('\n'),
|
||||
style: TextStyle(color: LightAppColors.productDetailDivider),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
|
||||
class CustomCard extends StatelessWidget {
|
||||
final String title;
|
||||
final String description;
|
||||
|
||||
const CustomCard({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 320, // عرض کمی افزایش یافت
|
||||
margin: const EdgeInsets.symmetric(horizontal: 5),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
offset: Offset(2, 2),
|
||||
blurRadius: 6,
|
||||
spreadRadius: 1,
|
||||
),
|
||||
],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: LightAppColors.nearbyPopup,
|
||||
border: Border.all(color: Colors.white, width: 4.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(11),
|
||||
),
|
||||
child: Image.asset(
|
||||
Assets.images.image.path,
|
||||
width: 80,
|
||||
height: 80,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Flexible(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(color: Colors.black),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
description,
|
||||
style: TextStyle(
|
||||
color: LightAppColors.nearbyPopuphint,
|
||||
fontSize: 15,
|
||||
),
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.icons.mDSPublicTWTag.path,
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
"(15%) 43 - 36.55 AED",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class DividerTitleWidget extends StatelessWidget {
|
||||
|
||||
final String title;
|
||||
|
||||
const DividerTitleWidget({
|
||||
super.key,
|
||||
required this.title,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(fontSize: 15),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Expanded(
|
||||
child: Divider(color: Colors.grey, thickness: 2),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import 'package:intl/intl.dart';
|
||||
import 'package:lba/data/model/workingHours.dart';
|
||||
|
||||
class IsOpenChecker {
|
||||
static const Map<String, String> _dayMap = {
|
||||
'monday': 'mo',
|
||||
'tuesday': 'tu',
|
||||
'wednesday': 'we',
|
||||
'thursday': 'th',
|
||||
'friday': 'fr',
|
||||
'saturday': 'sa',
|
||||
'sunday': 'su',
|
||||
};
|
||||
|
||||
static bool isOpenNow(List<WorkingHours> workingHours) {
|
||||
final now = DateTime.now();
|
||||
final todayKey = _dayMap[DateFormat('EEEE').format(now).toLowerCase()] ?? '';
|
||||
|
||||
final todaySchedule = workingHours.firstWhere(
|
||||
(day) => day.day.toLowerCase() == todayKey,
|
||||
orElse: () => WorkingHours(day: todayKey, shifts: []),
|
||||
);
|
||||
|
||||
if (todaySchedule.shifts.isEmpty) return false;
|
||||
|
||||
for (final shift in todaySchedule.shifts) {
|
||||
if (_isTimeBetween(now, shift.openAt, shift.closeAt)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static WorkingHours getTodaySchedule(List<WorkingHours> workingHours) {
|
||||
final now = DateTime.now();
|
||||
final todayKey = _dayMap[DateFormat('EEEE').format(now).toLowerCase()] ?? '';
|
||||
|
||||
return workingHours.firstWhere(
|
||||
(day) => day.day.toLowerCase() == todayKey,
|
||||
orElse: () => WorkingHours(day: todayKey, shifts: []),
|
||||
);
|
||||
}
|
||||
|
||||
static bool _isTimeBetween(DateTime now, String open, String close) {
|
||||
try {
|
||||
final openTime = _parseTime(open);
|
||||
final closeTime = _parseTime(close);
|
||||
final nowTime = Duration(hours: now.hour, minutes: now.minute);
|
||||
|
||||
if (closeTime <= openTime) {
|
||||
// شیفت شبانه (مثلاً 22:00 تا 02:00)
|
||||
return nowTime >= openTime || nowTime <= closeTime;
|
||||
}
|
||||
|
||||
return nowTime >= openTime && nowTime <= closeTime;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Duration _parseTime(String time) {
|
||||
final parts = time.split(':');
|
||||
final hour = int.parse(parts[0]);
|
||||
final minute = int.parse(parts[1]);
|
||||
return Duration(hours: hour, minutes: minute);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String formatTime12Hour(String time24) {
|
||||
try {
|
||||
final parts = time24.split(':');
|
||||
final hour = int.parse(parts[0]);
|
||||
final minute = int.parse(parts[1]);
|
||||
|
||||
final dateTime = DateTime(0, 1, 1, hour, minute);
|
||||
final formatter = DateFormat('hh:mm a');
|
||||
return formatter.format(dateTime);
|
||||
} catch (_) {
|
||||
return time24;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
|
||||
class OrderType extends StatelessWidget {
|
||||
String icon;
|
||||
String typename;
|
||||
bool fill;
|
||||
|
||||
OrderType({super.key, required this.icon, required this.typename});
|
||||
OrderType({super.key, required this.icon, required this.typename,required this.fill});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -13,6 +15,7 @@ class OrderType extends StatelessWidget {
|
|||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
border: Border.all(color: Color.fromARGB(255, 76, 175, 80), width: 1.0),
|
||||
color: fill==false?Colors.transparent:LightAppColors.fillOrder
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(6, 2, 6, 2),
|
||||
|
|
@ -20,14 +23,14 @@ class OrderType extends StatelessWidget {
|
|||
children: [
|
||||
SvgPicture.asset(
|
||||
icon,
|
||||
color: Color.fromARGB(255, 95, 95, 95),
|
||||
color: fill==false? Color.fromARGB(255, 95, 95, 95):LightAppColors.fillOrderText,
|
||||
height: 17,
|
||||
),
|
||||
SizedBox(width: 2),
|
||||
Text(
|
||||
typename,
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 95, 95, 95),
|
||||
color: fill==false? Color.fromARGB(255, 95, 95, 95):LightAppColors.fillOrderText,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12
|
||||
),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
|
||||
class CustomStarRating extends StatelessWidget {
|
||||
final double rating;
|
||||
final int starCount;
|
||||
final double size;
|
||||
|
||||
const CustomStarRating({
|
||||
super.key,
|
||||
required this.rating,
|
||||
this.starCount = 5,
|
||||
this.size = 20.0,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> stars = [];
|
||||
|
||||
double remaining = rating;
|
||||
|
||||
for (int i = 0; i < starCount; i++) {
|
||||
if (remaining >= 1) {
|
||||
stars.add(_buildStar(Assets.icons.starFill.path));
|
||||
remaining -= 1;
|
||||
} else if (remaining >= 0.5) {
|
||||
stars.add(_buildStar(Assets.icons.starHalf.path));
|
||||
remaining = 0;
|
||||
} else {
|
||||
stars.add(_buildStar(Assets.icons.star.path));
|
||||
}
|
||||
}
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: stars,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStar(String asset) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||
child: SvgPicture.asset(
|
||||
asset,
|
||||
width: size,
|
||||
height: size,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:lba/gen/assets.gen.dart';
|
||||
import 'package:lba/res/colors.dart';
|
||||
import 'package:lba/widgets/buildWarpedInfo.dart';
|
||||
import 'package:lba/widgets/rate.dart';
|
||||
|
||||
class Reviews extends StatelessWidget {
|
||||
|
||||
final String name;
|
||||
final String comment;
|
||||
final double rate;
|
||||
final int yesCount;
|
||||
final int noCount;
|
||||
final String date;
|
||||
|
||||
const Reviews({
|
||||
super.key,
|
||||
required this.name,
|
||||
required this.comment,
|
||||
required this.rate,
|
||||
required this.yesCount,
|
||||
required this.noCount,
|
||||
required this.date,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(name),
|
||||
SizedBox(width: 2),
|
||||
Image.asset(Assets.images.usa.path),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
"Verified Buyer",
|
||||
style: TextStyle(color: LightAppColors.confirmButton),
|
||||
),
|
||||
],
|
||||
),
|
||||
CustomStarRating(rating: rate),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 7),
|
||||
buildWrappedInfo(
|
||||
"",
|
||||
comment,
|
||||
),
|
||||
SizedBox(height: 10,),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(Assets.icons.like.path),
|
||||
SizedBox(width: 1,),
|
||||
Text("Yes (${yesCount.toString()})",style: TextStyle(
|
||||
color: LightAppColors.hint,
|
||||
),),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10,),
|
||||
InkWell(
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(Assets.icons.dislike.path),
|
||||
SizedBox(width: 1,),
|
||||
Text("No (${noCount.toString()})",style: TextStyle(
|
||||
color: LightAppColors.hint,
|
||||
),),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(date,style: TextStyle(
|
||||
color: LightAppColors.hint
|
||||
),)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 5,),
|
||||
Divider(thickness: 1.2, height: 2),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,14 @@
|
|||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <maps_launcher/maps_launcher_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) maps_launcher_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "MapsLauncherPlugin");
|
||||
maps_launcher_plugin_register_with_registrar(maps_launcher_registrar);
|
||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
maps_launcher
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
|
|
|||
|
|
@ -7,10 +7,14 @@ import Foundation
|
|||
|
||||
import geolocator_apple
|
||||
import location
|
||||
import maps_launcher
|
||||
import shared_preferences_foundation
|
||||
import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
|
||||
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
|
||||
MapsLauncherPlugin.register(with: registry.registrar(forPlugin: "MapsLauncherPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
}
|
||||
|
|
|
|||
72
pubspec.lock
|
|
@ -568,6 +568,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
maps_launcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: maps_launcher
|
||||
sha256: dac4c609720211fa6336b5903d917fe45e545c6b5665978efc3db2a3f436b1ae
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0+1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -917,6 +925,70 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.1"
|
||||
url_launcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher
|
||||
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.1"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.16"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.3"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_linux
|
||||
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
url_launcher_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
url_launcher_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_platform_interface
|
||||
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
url_launcher_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_windows
|
||||
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ dependencies:
|
|||
flutter_map: ^8.1.1
|
||||
latlong2: ^0.9.1
|
||||
location: ^8.0.0
|
||||
maps_launcher: ^3.0.0+1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
|
|
@ -7,8 +7,14 @@
|
|||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <geolocator_windows/geolocator_windows.h>
|
||||
#include <maps_launcher/maps_launcher_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
GeolocatorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("GeolocatorWindows"));
|
||||
MapsLauncherPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("MapsLauncherPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
geolocator_windows
|
||||
maps_launcher
|
||||
url_launcher_windows
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
|
|
|||