Merge pull request #49 from SyncrowIOT/feature/space-management
Feature/space management
5
assets/icons/1G_touch_switch.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="33" height="37" viewBox="0 0 33 37" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M31.3624 36.0701L29.1794 36.7543H17.2683H16.5003H15.7323H1.02393C0.458416 36.7543 0 36.2438 0 35.6139V1.1404C0 0.510558 0.458416 0 1.02393 0H15.7316H16.6015H17.2877H29.2267L31.5672 1.1404C32.1327 1.1404 32.5911 1.65096 32.5911 2.2808L32.3863 34.9297C32.3863 35.5595 31.9279 36.0701 31.3624 36.0701Z" fill="#D1D1D1"/>
|
||||
<path d="M31.9741 0H28.9023C29.4679 0 29.9263 0.510558 29.9263 1.1404V35.6139C29.9263 36.2438 29.4679 36.7543 28.9023 36.7543H31.9741C32.5397 36.7543 32.9981 36.2438 32.9981 35.6139V1.1404C32.9981 0.510558 32.5397 0 31.9741 0Z" fill="#A0A0A0"/>
|
||||
<path opacity="0.6" d="M17.1376 17.6795V19.0479C17.1376 19.2762 17.074 19.4606 16.9973 19.5737C16.9596 19.6292 16.9244 19.6597 16.9006 19.6745C16.8789 19.688 16.8678 19.6883 16.8642 19.6883H13.461C13.4573 19.6883 13.4462 19.688 13.4245 19.6745C13.4007 19.6597 13.3655 19.6292 13.3278 19.5737C13.2511 19.4606 13.1875 19.2762 13.1875 19.0479V17.6795C13.1875 17.4512 13.2511 17.2669 13.3278 17.1537C13.3655 17.0982 13.4007 17.0678 13.4245 17.0529C13.4462 17.0394 13.4573 17.0391 13.461 17.0391H16.8642C16.8678 17.0391 16.8789 17.0394 16.9006 17.0529C16.9244 17.0678 16.9596 17.0982 16.9973 17.1537C17.074 17.2669 17.1376 17.4512 17.1376 17.6795Z" stroke="#023DFE" stroke-opacity="0.6"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
11
assets/icons/1_Gang_switch_icon.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="1Gang switch">
|
||||
<path id="Vector" d="M47.5178 49.0692L44.2102 50H26.1635H24.9999H23.8364H1.55138C0.694554 50 0 49.3054 0 48.4486V1.55138C0 0.694554 0.694554 0 1.55138 0H23.8353H25.1532H26.1929H44.2819L47.8281 1.55138C48.6849 1.55138 49.3794 2.24594 49.3794 3.10277L49.0692 47.5178C49.0692 48.3746 48.3746 49.0692 47.5178 49.0692Z" fill="#E9E9E9"/>
|
||||
<g id="Group">
|
||||
<path id="Vector_2" d="M48.4486 0H43.7944C44.6513 0 45.3458 0.694554 45.3458 1.55138V48.4486C45.3458 49.3054 44.6513 50 43.7944 50H48.4486C49.3054 50 50 49.3054 50 48.4486V1.55138C50 0.694554 49.3054 0 48.4486 0Z" fill="#D1D1D1"/>
|
||||
</g>
|
||||
<g id="Group_2">
|
||||
<path id="Vector_3" opacity="0.6" d="M26.7188 39.7899V41.6516C26.7188 42.5084 26.1941 43.203 25.5469 43.203H20.3906C19.7434 43.203 19.2188 42.5084 19.2188 41.6516V39.7899C19.2188 38.9331 19.7434 38.2385 20.3906 38.2385H25.5469C26.1941 38.2385 26.7188 38.9331 26.7188 39.7899Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
6
assets/icons/2G_touch_switch.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M34.207 35.3238L31.8259 35.9938H18.8345H17.9969H17.1593H1.11681C0.499994 35.9938 0 35.4939 0 34.877V1.11681C0 0.499994 0.499994 0 1.11681 0H17.1585H18.1072H18.8557H31.8775L34.4303 1.11681C35.0471 1.11681 35.5471 1.6168 35.5471 2.23361L35.3238 34.207C35.3238 34.8238 34.8238 35.3238 34.207 35.3238Z" fill="#D1D1D1"/>
|
||||
<path d="M34.8895 0H31.5391C32.1559 0 32.6559 0.499994 32.6559 1.11681V34.877C32.6559 35.4939 32.1559 35.9938 31.5391 35.9938H34.8895C35.5063 35.9938 36.0063 35.4939 36.0063 34.877V1.11681C36.0063 0.499994 35.5063 0 34.8895 0Z" fill="#A0A0A0"/>
|
||||
<path opacity="0.6" d="M14.7975 17.3141V18.6542C14.7975 18.8641 14.7327 19.0351 14.6515 19.1426C14.5705 19.2498 14.4958 19.271 14.4539 19.271H10.742C10.7002 19.271 10.6255 19.2498 10.5445 19.1426C10.4633 19.0351 10.3984 18.8641 10.3984 18.6542V17.3141C10.3984 17.1042 10.4633 16.9332 10.5445 16.8257C10.6255 16.7185 10.7002 16.6973 10.742 16.6973H14.4539C14.4958 16.6973 14.5705 16.7185 14.6515 16.8257C14.7327 16.9332 14.7975 17.1042 14.7975 17.3141Z" stroke="#023DFE" stroke-opacity="0.6"/>
|
||||
<path opacity="0.6" d="M23.7975 17.3141V18.6542C23.7975 18.8641 23.7327 19.0351 23.6515 19.1426C23.5705 19.2498 23.4958 19.271 23.4539 19.271H19.742C19.7002 19.271 19.6255 19.2498 19.5445 19.1426C19.4633 19.0351 19.3984 18.8641 19.3984 18.6542V17.3141C19.3984 17.1042 19.4633 16.9332 19.5445 16.8257C19.6255 16.7185 19.7002 16.6973 19.742 16.6973H23.4539C23.4958 16.6973 23.5705 16.7185 23.6515 16.8257C23.7327 16.9332 23.7975 17.1042 23.7975 17.3141Z" stroke="#023DFE" stroke-opacity="0.6"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
7
assets/icons/2_Gang_Switch_icon.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M47.5178 49.0692L44.2102 50H26.1635H24.9999H23.8364H1.55138C0.694554 50 0 49.3054 0 48.4486V1.55138C0 0.694554 0.694554 0 1.55138 0H23.8353H25.1532H26.1929H44.2819L47.8281 1.55138C48.6849 1.55138 49.3794 2.24594 49.3794 3.10277L49.0692 47.5178C49.0692 48.3746 48.3746 49.0692 47.5178 49.0692Z" fill="#E9E9E9"/>
|
||||
<path d="M48.4487 0H43.7946C44.6514 0 45.3459 0.694554 45.3459 1.55138V48.4486C45.3459 49.3054 44.6514 50 43.7946 50H48.4487C49.3055 50 50.0001 49.3054 50.0001 48.4486V1.55138C50.0001 0.694554 49.3055 0 48.4487 0Z" fill="#D1D1D1"/>
|
||||
<path opacity="0.6" d="M15.0356 39.7899V41.6516C15.0356 42.5084 14.511 43.203 13.8638 43.203H8.70752C8.06029 43.203 7.53564 42.5084 7.53564 41.6516V39.7899C7.53564 38.9331 8.06029 38.2385 8.70752 38.2385H13.8638C14.511 38.2385 15.0356 38.9331 15.0356 39.7899Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
<path opacity="0.6" d="M32.5356 39.7899V41.6516C32.5356 42.5084 33.0603 43.203 33.7075 43.203H38.8638C39.511 43.203 40.0356 42.5084 40.0356 41.6516V39.7899C40.0356 38.9331 39.511 38.2385 38.8638 38.2385H33.7075C33.0603 38.2385 32.5356 38.9331 32.5356 39.7899Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
<path d="M23.8367 0H26.1637V50H23.8367V0Z" fill="#D1D1D1"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
7
assets/icons/3G_touch_switch.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M34.2128 35.3298L31.8314 36H18.8377H17.9999H17.1622H1.117C0.500079 36 0 35.4999 0 34.883V1.117C0 0.500079 0.500079 0 1.117 0H17.1614H18.1103H18.8589H31.883L34.4362 1.117C35.0531 1.117 35.5532 1.61708 35.5532 2.23399L35.3298 34.2128C35.3298 34.8297 34.8297 35.3298 34.2128 35.3298Z" fill="#D1D1D1"/>
|
||||
<path d="M34.8901 0H31.5391C32.156 0 32.6561 0.500079 32.6561 1.117V34.883C32.6561 35.4999 32.156 36 31.5391 36H34.8901C35.507 36 36.007 35.4999 36.007 34.883V1.117C36.007 0.500079 35.507 0 34.8901 0Z" fill="#A0A0A0"/>
|
||||
<path opacity="0.6" d="M9.4 17.3172V18.6576C9.4 18.8675 9.33513 19.0385 9.25391 19.1461C9.17289 19.2533 9.09813 19.2746 9.05625 19.2746H5.34375C5.30187 19.2746 5.22711 19.2533 5.14609 19.1461C5.06487 19.0385 5 18.8675 5 18.6576V17.3172C5 17.1073 5.06487 16.9362 5.14609 16.8287C5.22711 16.7215 5.30187 16.7002 5.34375 16.7002H9.05625C9.09813 16.7002 9.17289 16.7215 9.25391 16.8287C9.33513 16.9362 9.4 17.1073 9.4 17.3172Z" stroke="#023DFE" stroke-opacity="0.6"/>
|
||||
<path opacity="0.6" d="M18.4 17.3172V18.6576C18.4 18.8675 18.3351 19.0385 18.2539 19.1461C18.1729 19.2533 18.0981 19.2746 18.0563 19.2746H14.3438C14.3019 19.2746 14.2271 19.2533 14.1461 19.1461C14.0649 19.0385 14 18.8675 14 18.6576V17.3172C14 17.1073 14.0649 16.9362 14.1461 16.8287C14.2271 16.7215 14.3019 16.7002 14.3438 16.7002H18.0563C18.0981 16.7002 18.1729 16.7215 18.2539 16.8287C18.3351 16.9362 18.4 17.1073 18.4 17.3172Z" stroke="#023DFE" stroke-opacity="0.6"/>
|
||||
<path opacity="0.6" d="M27.4 17.3172V18.6576C27.4 18.8675 27.3351 19.0385 27.2539 19.1461C27.1729 19.2533 27.0981 19.2746 27.0563 19.2746H23.3438C23.3019 19.2746 23.2271 19.2533 23.1461 19.1461C23.0649 19.0385 23 18.8675 23 18.6576V17.3172C23 17.1073 23.0649 16.9362 23.1461 16.8287C23.2271 16.7215 23.3019 16.7002 23.3438 16.7002H27.0563C27.0981 16.7002 27.1729 16.7215 27.2539 16.8287C27.3351 16.9362 27.4 17.1073 27.4 17.3172Z" stroke="#023DFE" stroke-opacity="0.6"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
9
assets/icons/3_Gang_switch_icon.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M47.5178 49.0692L44.2102 50H26.1635H24.9999H23.8364H1.55138C0.694554 50 0 49.3054 0 48.4486V1.55138C0 0.694554 0.694554 0 1.55138 0H23.8353H25.1532H26.1929H44.2819L47.8281 1.55138C48.6849 1.55138 49.3794 2.24594 49.3794 3.10277L49.0692 47.5178C49.0692 48.3746 48.3746 49.0692 47.5178 49.0692Z" fill="#E9E9E9"/>
|
||||
<path d="M48.4487 0H43.7946C44.6514 0 45.3459 0.694554 45.3459 1.55138V48.4486C45.3459 49.3054 44.6514 50 43.7946 50H48.4487C49.3055 50 50.0001 49.3054 50.0001 48.4486V1.55138C50.0001 0.694554 49.3055 0 48.4487 0Z" fill="#D1D1D1"/>
|
||||
<path opacity="0.6" d="M10.8008 39.7899V41.6516C10.8008 42.5084 10.2761 43.203 9.62891 43.203H4.47266C3.82543 43.203 3.30078 42.5084 3.30078 41.6516V39.7899C3.30078 38.9331 3.82543 38.2385 4.47266 38.2385H9.62891C10.2761 38.2385 10.8008 38.9331 10.8008 39.7899Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
<path opacity="0.6" d="M34.5508 39.7899V41.6516C34.5508 42.5084 35.0754 43.203 35.7227 43.203H40.8789C41.5261 43.203 42.0508 42.5084 42.0508 41.6516V39.7899C42.0508 38.9331 41.5261 38.2385 40.8789 38.2385H35.7227C35.0754 38.2385 34.5508 38.9331 34.5508 39.7899Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
<path opacity="0.6" d="M18.8281 39.7899V41.6516C18.8281 42.5084 19.3528 43.203 20 43.203H25.1562C25.8035 43.203 26.3281 42.5084 26.3281 41.6516V39.7899C26.3281 38.9331 25.8035 38.2385 25.1562 38.2385H20C19.3528 38.2385 18.8281 38.9331 18.8281 39.7899Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||
<path d="M28.9062 0H31.2333V50H28.9062V0Z" fill="#D1D1D1"/>
|
||||
<path d="M13.9648 0H16.2919V50H13.9648V0Z" fill="#D1D1D1"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
3
assets/icons/add_icon.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="13" height="12" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector" d="M11.4453 4.94531H7.55469V1.05469C7.55469 0.472195 7.08249 0 6.5 0C5.91751 0 5.44531 0.472195 5.44531 1.05469V4.94531H1.55469C0.972195 4.94531 0.5 5.41751 0.5 6C0.5 6.58249 0.972195 7.05469 1.55469 7.05469H5.44531V10.9453C5.44531 11.5278 5.91751 12 6.5 12C7.08249 12 7.55469 11.5278 7.55469 10.9453V7.05469H11.4453C12.0278 7.05469 12.5 6.58249 12.5 6C12.5 5.41751 12.0278 4.94531 11.4453 4.94531Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 557 B |
3
assets/icons/bbq_icon.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="30" height="50" viewBox="0 0 30 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M28.3688 23.3912H27.5223C27.5275 23.3345 27.5305 23.277 27.5305 23.2187V21.8714C27.5305 20.9686 26.8806 20.234 26.082 20.234H25.0949C24.7371 20.234 24.447 20.5619 24.447 20.9664C24.447 21.3709 24.7371 21.6988 25.0949 21.6988H26.082C26.1661 21.6988 26.2346 21.7762 26.2346 21.8714V23.2187C26.2346 23.3138 26.1661 23.3912 26.082 23.3912H13.9437C13.8595 23.3912 13.791 23.3139 13.791 23.2187V21.8714C13.791 21.7763 13.8594 21.6988 13.9437 21.6988H22.0372C22.3951 21.6988 22.6852 21.3709 22.6852 20.9664C22.6852 20.5619 22.3951 20.234 22.0372 20.234H13.9437C13.145 20.234 12.4952 20.9685 12.4952 21.8714V23.2187C12.4952 23.277 12.4981 23.3345 12.5034 23.3912H6.90109C6.86074 23.2443 6.8083 23.1035 6.74567 22.9696L21.9263 5.80955C22.4776 5.18631 22.4776 4.17235 21.9263 3.54911L21.2299 2.7619C19.6544 0.980855 17.5595 0 15.3312 0C13.1029 0 11.008 0.980856 9.43243 2.762L8.61197 3.68944L8.13216 3.14706C7.53174 2.46835 6.59319 2.42489 6.03977 3.05038L3.36752 6.07107C2.81419 6.69656 2.85254 7.75759 3.45305 8.43629L3.93286 8.97868L3.11232 9.90621C-0.0587459 13.4909 -0.13667 19.266 2.87552 22.9605C2.71138 23.3075 2.61808 23.7034 2.61808 24.1236C2.61808 25.2372 3.27189 26.1812 4.16828 26.4916C4.17286 26.6187 4.17942 26.7454 4.18849 26.8712H1.81222C0.813025 26.8712 0 27.7901 0 28.9197C0 30.0492 0.812939 30.9681 1.81222 30.9681H5.35927C6.43855 32.9854 8.16723 34.5113 10.2156 35.1723L8.23539 43.8391C8.14589 44.2308 8.35427 44.6303 8.7007 44.7314C8.75504 44.7473 8.80955 44.7548 8.8632 44.7548C9.15148 44.7548 9.41463 44.5356 9.49005 44.2054L11.4875 35.4627C11.8204 35.5086 12.1591 35.5327 12.5028 35.5327H12.9258L10.0915 47.9378C10.0112 48.2895 9.73125 48.535 9.41074 48.535C9.35157 48.535 9.29204 48.5264 9.23382 48.5093C9.05179 48.4562 8.89888 48.326 8.80342 48.1429C8.70795 47.9598 8.68117 47.7456 8.72825 47.5398L8.98276 46.4258C9.07226 46.0341 8.86389 45.6346 8.51746 45.5335C8.17069 45.4323 7.81752 45.6678 7.72811 46.0595L7.4736 47.1734C7.34004 47.7581 7.4158 48.3666 7.68716 48.8868C7.95843 49.407 8.39263 49.7767 8.90968 49.9276C9.07365 49.9756 9.24228 49.9999 9.41083 49.9999C10.3223 49.9999 11.1182 49.3025 11.3463 48.3042L12.3025 44.1193H21.6497L21.9389 45.3812C21.7311 45.8213 21.6129 46.3233 21.6129 46.8562C21.6129 48.5896 22.8605 50 24.3941 50C25.9277 50 27.1753 48.5896 27.1753 46.8562C27.1753 45.6953 26.6154 44.6801 25.7853 44.1356L23.731 35.1716C25.8851 34.4755 27.6853 32.8227 28.7482 30.6478C28.7728 30.607 28.7937 30.5633 28.8107 30.5172C29.4309 29.1994 29.783 27.697 29.783 26.103V24.9897C29.7829 24.1082 29.1485 23.3912 28.3688 23.3912ZM4.28378 7.10681L6.95594 4.08621C6.98272 4.05614 7.10842 4.06141 7.21581 4.1828L7.69562 4.72518L4.84913 7.94284L4.36931 7.40046C4.28741 7.30788 4.27333 7.21579 4.271 7.18054C4.26884 7.14694 4.27385 7.11804 4.28378 7.10681ZM4.02858 10.9419L10.3487 3.79774C11.6796 2.29335 13.4491 1.46484 15.3312 1.46484C17.2133 1.46484 18.9828 2.29335 20.3136 3.79774L21.01 4.58494C21.0561 4.63699 21.0561 4.72176 21.01 4.77381L5.82941 21.9339C5.52436 21.7514 5.17698 21.6476 4.80852 21.6476C4.44318 21.6476 4.09882 21.7497 3.79568 21.9292C1.28412 18.8072 1.36144 13.9569 4.02858 10.9419ZM1.81214 29.5033C1.52748 29.5033 1.29578 29.2415 1.29578 28.9197C1.29578 28.5979 1.52739 28.336 1.81214 28.336H4.39756C4.48378 28.7356 4.59229 29.1254 4.72204 29.5033H1.81214ZM4.80852 25.1349C4.31523 25.1349 3.91394 24.6812 3.91394 24.1236C3.91394 23.566 4.31532 23.1124 4.80852 23.1124C5.30182 23.1124 5.7031 23.5661 5.7031 24.1236C5.70319 24.6812 5.30182 25.1349 4.80852 25.1349ZM12.6371 42.6542L13.0008 41.0625H20.9491L21.3139 42.6542H12.6371ZM13.3355 39.5977L14.2643 35.5327H19.6819L20.6135 39.5977H13.3355ZM25.8794 46.856C25.8794 47.7817 25.213 48.535 24.394 48.535C23.575 48.535 22.9086 47.7817 22.9086 46.856C22.9086 45.9301 23.575 45.1769 24.394 45.1769C25.213 45.1769 25.8794 45.9301 25.8794 46.856ZM24.3497 43.7133C23.8558 43.7221 23.393 43.8769 22.9933 44.1415L21.0204 35.5328H21.4407C21.7853 35.5328 22.1251 35.5085 22.4589 35.4625L24.3497 43.7133ZM21.4407 34.0678H12.5028C10.2373 34.0678 8.2195 32.8517 6.92968 30.9681H27.0139C25.724 32.8517 23.7062 34.0678 21.4407 34.0678ZM27.811 29.5033H6.13246C5.74535 28.5804 5.51028 27.5609 5.46501 26.4859C6.14862 26.2427 6.68865 25.6301 6.90109 24.856H28.3688C28.434 24.856 28.4869 24.9158 28.4869 24.9895V26.1028C28.4869 27.3187 28.2438 28.4714 27.811 29.5033Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
18
assets/icons/building_icon.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<svg width="51" height="50" viewBox="0 0 51 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.0222 13.4482H19.9519V16.3779H17.0222V13.4482Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M17.0222 20.1724H19.9519V23.1021H17.0222V20.1724Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M30.4719 20.1724H33.4016V23.1021H30.4719V20.1724Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M37.1965 20.1724H40.1262V23.1021H37.1965V20.1724Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M30.4719 26.8975H33.4016V29.8271H30.4719V26.8975Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M37.1965 26.8975H40.1262V29.8271H37.1965V26.8975Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M30.4719 33.6216H33.4016V36.5513H30.4719V33.6216Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M37.1965 33.6216H40.1262V36.5513H37.1965V33.6216Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M30.4719 40.3455H33.4016V43.2751H30.4719V40.3455Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M37.1965 40.3455H40.1262V43.2751H37.1965V40.3455Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M10.2979 20.1724H13.2275V23.1021H10.2979V20.1724Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M17.0222 26.8975H19.9519V29.8271H17.0222V26.8975Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M10.2979 26.8975H13.2275V29.8271H10.2979V26.8975Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M17.0222 33.6216H19.9519V36.5513H17.0222V33.6216Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M10.2979 33.6216H13.2275V36.5513H10.2979V33.6216Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M46.8497 47.0701V13.4484H26.6768V6.45972L23.3146 7.02007V-0.000244141H6.93623V9.74985L3.57412 10.3102V47.0701H0.211914V49.9998H50.2119V47.0701H46.8497ZM43.92 16.3781V47.0701H26.6768V16.3781H43.92ZM9.86592 2.92944H20.3849V7.50835L9.86592 9.26157V2.92944ZM6.50381 12.792L23.7471 9.91812V13.4484V47.0701H19.9524V40.3458H10.2984V47.0701H6.50381V12.792ZM17.0228 47.0701H13.2281V43.2754H17.0228V47.0701Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
9
assets/icons/delete.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg width="16" height="20" viewBox="0 0 16 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.807 19.9998H3.50041C2.16417 19.9998 1.08093 18.9165 1.08093 17.5804V4.51562H14.2263V17.5804C14.2263 18.9165 13.1432 19.9998 11.807 19.9998Z" fill="#D8D8D8"/>
|
||||
<path d="M1.08093 4.51562V5.48335H12.3716C12.8168 5.48335 13.178 5.84438 13.178 6.2898V17.3384C13.178 18.2292 12.4558 18.9513 11.565 18.9513H2.45196C2.05416 18.9513 1.67894 18.8547 1.34781 18.6844C1.74913 19.4652 2.56213 19.9998 3.50041 19.9998H11.807C13.1432 19.9998 14.2263 18.9165 14.2263 17.5803V4.51562H1.08093Z" fill="#BABABA"/>
|
||||
<path d="M14.2668 1.77417H10.7439L10.1633 0.612956C9.97426 0.234837 9.59416 0 9.17148 0H6.136C5.71317 0 5.33322 0.234837 5.14416 0.612956L4.56355 1.77417H1.04069C0.595282 1.77417 0.234253 2.1352 0.234253 2.58061V3.70978C0.234253 4.15504 0.595282 4.51622 1.04069 4.51622H14.2668C14.7122 4.51622 15.0732 4.15504 15.0732 3.70978V2.58077C15.0732 2.1352 14.7122 1.77417 14.2668 1.77417ZM5.68509 0.8835C5.771 0.71153 5.94374 0.604869 6.136 0.604869H9.17148C9.3636 0.604869 9.53633 0.71153 9.62224 0.8835L10.0676 1.77417H5.23984L5.68509 0.8835Z" fill="#757575"/>
|
||||
<path d="M14.2668 1.77441H12.9764C13.4218 1.77441 13.783 2.13544 13.783 2.58086V3.71003C13.783 4.15529 13.4218 4.51647 12.9764 4.51647H14.2668C14.7122 4.51647 15.0733 4.15529 15.0733 3.71003V2.58101C15.0733 2.13544 14.7122 1.77441 14.2668 1.77441Z" fill="#595959"/>
|
||||
<path d="M11.3634 17.5C10.918 17.5 10.557 17.139 10.557 16.6935V9.15312C10.557 8.70771 10.918 8.34668 11.3634 8.34668C11.8089 8.34668 12.1699 8.70771 12.1699 9.15312V16.6935C12.1699 17.139 11.8089 17.5 11.3634 17.5Z" fill="#757575"/>
|
||||
<path d="M3.94405 17.5C4.3893 17.5 4.75049 17.139 4.75049 16.6935V9.15312C4.75049 8.70771 4.3893 8.34668 3.94405 8.34668C3.49863 8.34668 3.13745 8.70771 3.13745 9.15312V16.6935C3.13745 17.139 3.49863 17.5 3.94405 17.5Z" fill="#757575"/>
|
||||
<path d="M7.65367 17.5C7.20826 17.5 6.84723 17.139 6.84723 16.6935V9.15312C6.84723 8.70771 7.20826 8.34668 7.65367 8.34668C8.09908 8.34668 8.46011 8.70771 8.46011 9.15312V16.6935C8.46011 17.139 8.09908 17.5 7.65367 17.5Z" fill="#757575"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/icons/desk_icon.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
3
assets/icons/desk_icon.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M48.291 25.6836H34.8732V23.666H39.5059C40.7174 23.666 41.7031 22.6804 41.7031 21.4688V12.418C41.7031 11.2063 40.7174 10.2207 39.5059 10.2207H25.8467C24.6352 10.2207 23.6494 11.2063 23.6494 12.418V15.5756L20.5188 14.6216C19.7096 14.4092 19.5266 13.5235 19.6035 12.797C20.6912 11.8364 21.3791 10.4331 21.3791 8.87139V3.37383C21.3791 1.51357 19.8656 0 18.0052 0H14.2766C12.4162 0 10.9026 1.51357 10.9026 3.37383V8.87129C10.9026 10.4736 11.6266 11.9094 12.7637 12.871C12.8421 13.583 12.6316 14.4282 11.8487 14.6363L7.70937 15.899C5.68281 16.5165 4.32129 18.3549 4.32129 20.4736V23.4863C4.32129 23.8908 4.64912 24.2188 5.05371 24.2188C5.4583 24.2188 5.78613 23.8908 5.78613 23.4863V20.4736C5.78613 19.0038 6.73057 17.7285 8.13652 17.3002L9.72246 16.8164L12.755 19.4111C13.0198 19.6377 13.3474 19.7488 13.6738 19.7488C14.0667 19.7488 14.458 19.5879 14.7358 19.2739L15.4084 18.5143V25.6836H10.6746V24.4149C10.6746 24.0105 10.3468 23.6825 9.94219 23.6825C9.5376 23.6825 9.20977 24.0105 9.20977 24.4149V25.6836H1.70898C0.766699 25.6836 0 26.4503 0 27.3926V29.834C0 30.7763 0.766699 31.543 1.70898 31.543H3.6623V49.2676C3.6623 49.6722 3.99014 50 4.39473 50C4.79932 50 5.12715 49.6722 5.12715 49.2676V31.543H48.291C49.2333 31.543 50 30.7763 50 29.834V27.3926C50 26.4503 49.2333 25.6836 48.291 25.6836ZM25.1143 16.5637C25.1143 16.5615 25.1143 16.5593 25.1143 16.5571V12.418C25.1143 12.0141 25.4428 11.6855 25.8467 11.6855H39.5059C39.9098 11.6855 40.2383 12.0141 40.2383 12.418V21.4688C40.2383 21.8727 39.9098 22.2012 39.5059 22.2012H34.8732V20.5566C34.8732 19.345 33.8875 18.3594 32.676 18.3594C31.4645 18.3594 30.4787 19.345 30.4787 20.5566V22.2012H25.8467C25.4428 22.2012 25.1143 21.8727 25.1143 21.4688V16.5637ZM33.4084 22.9373V25.6836H31.9436V20.5566C31.9436 20.1527 32.2721 19.8242 32.676 19.8242C33.0799 19.8242 33.4084 20.1527 33.4084 20.5566V22.9298C33.4084 22.9311 33.4082 22.9322 33.4082 22.9336C33.4082 22.935 33.4084 22.936 33.4084 22.9373ZM30.4787 23.666V25.6836H28.1006V23.666H30.4787ZM23.6494 17.1069V21.4688C23.6494 22.6804 24.6352 23.666 25.8467 23.666H26.6357V25.6836H23.0719V24.4149C23.0719 24.0105 22.744 23.6825 22.3395 23.6825C21.9349 23.6825 21.607 24.0105 21.607 24.4149V25.6836H16.8732V18.4802L17.6097 19.2925C17.8902 19.602 18.2729 19.76 18.658 19.76C18.9826 19.76 19.3091 19.6477 19.5772 19.4191L22.6482 16.8019L23.6494 17.1069ZM20.0921 16.0229L20.9848 16.2949L18.6631 18.2735L17.2884 16.7571L19.2561 15.6011C19.5074 15.7871 19.7892 15.9307 20.0921 16.0229ZM12.3676 3.37383C12.3676 2.32119 13.224 1.46484 14.2767 1.46484H18.0053C19.0579 1.46484 19.9144 2.32129 19.9144 3.37383V5.36426C18.5104 4.47334 16.8104 4.25869 15.2243 4.78125L12.3677 5.72236L12.3676 3.37383ZM12.3676 8.87129V7.26465L15.6825 6.17256C16.8846 5.77656 18.1759 5.95478 19.2257 6.66133L19.9143 7.12471V8.87139C19.9143 10.9521 18.2215 12.6447 16.1408 12.6447C14.0602 12.6447 12.3676 10.952 12.3676 8.87129ZM13.6709 18.2669L11.3835 16.3098L12.2757 16.0376C12.5794 15.9451 12.8609 15.8018 13.1113 15.6167L15.0085 16.7562L13.6709 18.2669ZM14.0172 14.4521C14.1114 14.2237 14.1749 13.9836 14.2054 13.7373C14.8046 13.9765 15.4573 14.1095 16.1408 14.1095C16.856 14.1095 17.5378 13.965 18.1594 13.7045C18.1888 13.9565 18.2528 14.2021 18.3488 14.4352L16.1449 15.73L14.0172 14.4521ZM48.5352 29.834C48.5352 29.9687 48.4257 30.0781 48.291 30.0781H1.70898C1.57432 30.0781 1.46484 29.9687 1.46484 29.834V27.3926C1.46484 27.2579 1.57432 27.1484 1.70898 27.1484H48.291C48.4257 27.1484 48.5352 27.2579 48.5352 27.3926V29.834ZM45.6057 33.3756C45.2011 33.3756 44.8732 33.7034 44.8732 34.108V49.2676C44.8732 49.6722 45.2011 50 45.6057 50C46.0103 50 46.3381 49.6722 46.3381 49.2676V34.108C46.3381 33.7034 46.0103 33.3756 45.6057 33.3756Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
4
assets/icons/door_icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="34" height="50" viewBox="0 0 34 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.8731 25.9231H11.9239C11.4474 25.9231 11.0613 26.3093 11.0613 26.7857C11.0613 27.2621 11.4474 27.6483 11.9239 27.6483H14.8731C15.3496 27.6483 15.7357 27.2621 15.7357 26.7857C15.7357 26.3093 15.3495 25.9231 14.8731 25.9231Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M32.4738 2.50441H19.749V0.862619C19.749 0.594651 19.6244 0.341819 19.4119 0.178636C19.1992 0.0153551 18.923 -0.0400159 18.6641 0.0292222L1.42329 4.62677C1.04565 4.72745 0.782959 5.06944 0.782959 5.46026V8.24649C0.782959 8.72285 1.16909 9.10908 1.64555 9.10908C2.12202 9.10908 2.50815 8.72285 2.50815 8.24649V6.12306L18.0237 1.98547V48.0851L2.50815 44.9819V11.1539C2.50815 10.6775 2.12202 10.2913 1.64555 10.2913C1.16909 10.2913 0.782959 10.6775 0.782959 11.1539V45.6892C0.782959 46.1004 1.0731 46.4544 1.47641 46.535L18.7172 49.9832C18.7733 49.9944 18.8299 50 18.8863 50C19.0841 50 19.2776 49.932 19.4332 49.8045C19.633 49.6406 19.7489 49.3958 19.7489 49.1374V47.4958H27.6986C28.1752 47.4958 28.5612 47.1096 28.5612 46.6332C28.5612 46.1568 28.1751 45.7706 27.6986 45.7706H19.7489V43.3094H28.2871C28.7636 43.3094 29.1497 42.9232 29.1497 42.4468V7.55352C29.1497 7.07715 28.7636 6.69093 28.2871 6.69093H19.7489V4.2296H31.611V45.7702H30.3803C29.9038 45.7702 29.5177 46.1565 29.5177 46.6328C29.5177 47.1092 29.9039 47.4954 30.3803 47.4954H32.4736C32.9502 47.4954 33.3362 47.1092 33.3362 46.6328V3.36701C33.3364 2.89064 32.9502 2.50441 32.4738 2.50441ZM27.4246 8.41612V41.5839H19.7491V8.41612H27.4246Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
28
assets/icons/door_lock.svg
Normal file
@ -0,0 +1,28 @@
|
||||
<svg width="38" height="50" viewBox="0 0 38 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Door Lock">
|
||||
<path id="Vector" d="M20.9677 0H1.6129C0.722121 0 0 0.722121 0 1.6129V48.3871C0 49.2779 0.722121 50 1.6129 50H20.9677C21.8585 50 22.5806 49.2779 22.5806 48.3871V1.6129C22.5806 0.722121 21.8585 0 20.9677 0Z" fill="#7A838B"/>
|
||||
<path id="Vector_2" d="M8.87097 47.5806C7.15989 47.5806 5.5189 46.9009 4.30899 45.691C3.09908 44.4811 2.41935 42.8401 2.41935 41.129V0H1.6129C1.18513 0 0.774887 0.16993 0.472409 0.472408C0.169931 0.774886 0 1.18513 0 1.6129V48.3871C0 48.8149 0.169931 49.2251 0.472409 49.5276C0.774887 49.8301 1.18513 50 1.6129 50H20.9677C21.3955 50 21.8058 49.8301 22.1082 49.5276C22.4107 49.2251 22.5806 48.8149 22.5806 48.3871V47.5806H8.87097Z" fill="#5D6972"/>
|
||||
<path id="Vector_3" d="M7.25808 46.7742C10.3758 46.7742 12.9032 44.2468 12.9032 41.129C12.9032 38.0113 10.3758 35.4839 7.25808 35.4839C4.14034 35.4839 1.61292 38.0113 1.61292 41.129C1.61292 44.2468 4.14034 46.7742 7.25808 46.7742Z" fill="#5D6972"/>
|
||||
<path id="Vector_4" d="M8.87099 45.1612C11.9887 45.1612 14.5162 42.6337 14.5162 39.516C14.5162 36.3983 11.9887 33.8708 8.87099 33.8708C5.75325 33.8708 3.22583 36.3983 3.22583 39.516C3.22583 42.6337 5.75325 45.1612 8.87099 45.1612Z" fill="#D6E4E8"/>
|
||||
<path id="Vector_5" d="M33.871 36.2903H9.67747C7.8959 36.2903 6.45166 37.7345 6.45166 39.5161C6.45166 41.2977 7.8959 42.7419 9.67747 42.7419H33.871C35.6526 42.7419 37.0968 41.2977 37.0968 39.5161C37.0968 37.7345 35.6526 36.2903 33.871 36.2903Z" fill="#D6E4E8"/>
|
||||
<path id="Vector_6" d="M36.2901 40.3224H12.0966C11.6109 40.3258 11.1309 40.2187 10.6927 40.0093C10.2545 39.7999 9.86966 39.4936 9.56729 39.1135C9.26492 38.7334 9.05293 38.2896 8.94735 37.8156C8.84178 37.3415 8.84538 36.8497 8.95788 36.3772C8.19061 36.5591 7.51654 37.0157 7.06305 37.6608C6.60956 38.3059 6.40805 39.0947 6.49661 39.8783C6.58517 40.6618 6.95767 41.3858 7.5437 41.9134C8.12974 42.441 8.88872 42.7357 9.67723 42.7417H33.8708C34.6003 42.7404 35.3078 42.4918 35.8778 42.0366C36.4479 41.5814 36.8468 40.9464 37.0095 40.2353C36.7738 40.2914 36.5324 40.3206 36.2901 40.3224Z" fill="#BACED3"/>
|
||||
<g id="Group">
|
||||
<path id="Vector_7" d="M4.83873 8.06443C5.72952 8.06443 6.45164 7.34231 6.45164 6.45153C6.45164 5.56074 5.72952 4.83862 4.83873 4.83862C3.94795 4.83862 3.22583 5.56074 3.22583 6.45153C3.22583 7.34231 3.94795 8.06443 4.83873 8.06443Z" fill="#62B5E8"/>
|
||||
<path id="Vector_8" d="M11.2905 8.06443C12.1813 8.06443 12.9034 7.34231 12.9034 6.45153C12.9034 5.56074 12.1813 4.83862 11.2905 4.83862C10.3997 4.83862 9.67761 5.56074 9.67761 6.45153C9.67761 7.34231 10.3997 8.06443 11.2905 8.06443Z" fill="#62B5E8"/>
|
||||
<path id="Vector_9" d="M17.7422 8.06443C18.633 8.06443 19.3551 7.34231 19.3551 6.45153C19.3551 5.56074 18.633 4.83862 17.7422 4.83862C16.8514 4.83862 16.1293 5.56074 16.1293 6.45153C16.1293 7.34231 16.8514 8.06443 17.7422 8.06443Z" fill="#62B5E8"/>
|
||||
<path id="Vector_10" d="M4.83898 14.5161C5.72976 14.5161 6.45188 13.794 6.45188 12.9032C6.45188 12.0124 5.72976 11.2903 4.83898 11.2903C3.9482 11.2903 3.22607 12.0124 3.22607 12.9032C3.22607 13.794 3.9482 14.5161 4.83898 14.5161Z" fill="#62B5E8"/>
|
||||
<path id="Vector_11" d="M11.2905 14.5161C12.1813 14.5161 12.9034 13.794 12.9034 12.9032C12.9034 12.0124 12.1813 11.2903 11.2905 11.2903C10.3997 11.2903 9.67761 12.0124 9.67761 12.9032C9.67761 13.794 10.3997 14.5161 11.2905 14.5161Z" fill="#62B5E8"/>
|
||||
<path id="Vector_12" d="M17.7422 14.5161C18.633 14.5161 19.3551 13.794 19.3551 12.9032C19.3551 12.0124 18.633 11.2903 17.7422 11.2903C16.8514 11.2903 16.1293 12.0124 16.1293 12.9032C16.1293 13.794 16.8514 14.5161 17.7422 14.5161Z" fill="#62B5E8"/>
|
||||
<path id="Vector_13" d="M4.83898 20.9677C5.72976 20.9677 6.45188 20.2456 6.45188 19.3548C6.45188 18.4641 5.72976 17.7419 4.83898 17.7419C3.9482 17.7419 3.22607 18.4641 3.22607 19.3548C3.22607 20.2456 3.9482 20.9677 4.83898 20.9677Z" fill="#62B5E8"/>
|
||||
<path id="Vector_14" d="M11.2905 20.9677C12.1813 20.9677 12.9034 20.2456 12.9034 19.3548C12.9034 18.4641 12.1813 17.7419 11.2905 17.7419C10.3997 17.7419 9.67761 18.4641 9.67761 19.3548C9.67761 20.2456 10.3997 20.9677 11.2905 20.9677Z" fill="#62B5E8"/>
|
||||
<path id="Vector_15" d="M17.7422 20.9677C18.633 20.9677 19.3551 20.2456 19.3551 19.3548C19.3551 18.4641 18.633 17.7419 17.7422 17.7419C16.8514 17.7419 16.1293 18.4641 16.1293 19.3548C16.1293 20.2456 16.8514 20.9677 17.7422 20.9677Z" fill="#62B5E8"/>
|
||||
</g>
|
||||
<path id="Vector_16" d="M4.83875 25.8064H14.5162V32.258H4.83875V25.8064Z" fill="#5D6972"/>
|
||||
<path id="Vector_17" d="M6.45166 24.1936H16.1291V30.6452H6.45166V24.1936Z" fill="#D6E4E8"/>
|
||||
<path id="Vector_18" d="M8.06456 25.8065V24.1936H6.45166V30.6452H16.1291V29.0323H11.2904C10.4348 29.0323 9.61434 28.6925 9.00938 28.0875C8.40442 27.4825 8.06456 26.662 8.06456 25.8065Z" fill="#BACED3"/>
|
||||
<path id="Vector_19" d="M29.0322 33.0644C29.923 33.0644 30.6451 32.3423 30.6451 31.4515C30.6451 30.5607 29.923 29.8386 29.0322 29.8386C28.1414 29.8386 27.4193 30.5607 27.4193 31.4515C27.4193 32.3423 28.1414 33.0644 29.0322 33.0644Z" fill="#6DBC53"/>
|
||||
<path id="Vector_20" d="M35.242 26.3225C35.3174 26.248 35.3774 26.1594 35.4185 26.0618C35.4597 25.9641 35.4812 25.8593 35.4818 25.7533C35.4824 25.6473 35.4621 25.5422 35.422 25.4441C35.382 25.346 35.323 25.2567 35.2485 25.1814C34.4359 24.3576 33.4677 23.7034 32.4002 23.257C31.3326 22.8105 30.187 22.5806 29.0299 22.5806C27.8728 22.5806 26.7272 22.8105 25.6597 23.257C24.5921 23.7034 23.624 24.3576 22.8114 25.1814C22.7369 25.2567 22.6779 25.3459 22.6379 25.444C22.5979 25.5421 22.5776 25.6471 22.5781 25.753C22.5787 25.8589 22.6001 25.9637 22.6412 26.0614C22.6822 26.159 22.7421 26.2476 22.8174 26.3221C22.8927 26.3966 22.9819 26.4556 23.08 26.4956C23.1781 26.5356 23.2831 26.5559 23.389 26.5553C23.495 26.5548 23.5997 26.5334 23.6974 26.4923C23.795 26.4512 23.8836 26.3914 23.9581 26.3161C24.6207 25.6438 25.4102 25.11 26.2809 24.7456C27.1516 24.3813 28.0861 24.1936 29.0299 24.1936C29.9738 24.1936 30.9082 24.3813 31.7789 24.7456C32.6496 25.11 33.4392 25.6438 34.1017 26.3161C34.2521 26.4681 34.4567 26.5542 34.6705 26.5554C34.8844 26.5566 35.0899 26.4728 35.242 26.3225Z" fill="#6DBC53"/>
|
||||
<path id="Vector_21" d="M20.3871 23.9453C20.4604 24.0217 20.5481 24.0829 20.6451 24.1254C20.7421 24.168 20.8465 24.191 20.9524 24.1932C21.0583 24.1953 21.1636 24.1766 21.2622 24.1381C21.3609 24.0996 21.451 24.042 21.5274 23.9687C23.5515 22.0423 26.2388 20.9679 29.0331 20.9679C31.8273 20.9679 34.5146 22.0423 36.5387 23.9687C36.6141 24.0464 36.7044 24.1082 36.8043 24.1504C36.9041 24.1925 37.0114 24.214 37.1197 24.2138C37.2281 24.2135 37.3353 24.1914 37.4349 24.1488C37.5345 24.1061 37.6245 24.0439 37.6995 23.9657C37.7746 23.8876 37.8331 23.7951 37.8715 23.6938C37.91 23.5925 37.9277 23.4845 37.9236 23.3762C37.9194 23.268 37.8934 23.1617 37.8473 23.0636C37.8011 22.9656 37.7356 22.8779 37.6548 22.8058C35.3304 20.5915 32.2433 19.3564 29.0331 19.3564C25.8228 19.3564 22.7357 20.5915 20.4113 22.8058C20.2571 22.9537 20.1679 23.1568 20.1634 23.3705C20.1589 23.5842 20.2393 23.7909 20.3871 23.9453Z" fill="#6DBC53"/>
|
||||
<path id="Vector_22" d="M32.2583 28.8364C32.4158 28.8365 32.5699 28.7904 32.7015 28.7039C32.8331 28.6174 32.9366 28.4942 32.999 28.3496C33.0614 28.205 33.0802 28.0453 33.0529 27.8902C33.0256 27.7351 32.9534 27.5913 32.8454 27.4767C32.3597 26.9501 31.7701 26.5298 31.1138 26.2423C30.4576 25.9548 29.7489 25.8064 29.0325 25.8064C28.316 25.8064 27.6074 25.9548 26.9511 26.2423C26.2949 26.5298 25.7053 26.9501 25.2196 27.4767C25.0729 27.6324 24.994 27.84 25.0004 28.0539C25.0067 28.2677 25.0978 28.4703 25.2535 28.617C25.4092 28.7638 25.6168 28.8426 25.8306 28.8363C26.0445 28.8299 26.2471 28.7389 26.3938 28.5832C26.7286 28.2165 27.1362 27.9236 27.5905 27.7233C28.0448 27.5229 28.5359 27.4194 29.0325 27.4194C29.529 27.4194 30.0201 27.5229 30.4745 27.7233C30.9288 27.9236 31.3364 28.2165 31.6712 28.5832C31.7466 28.6632 31.8376 28.7269 31.9386 28.7704C32.0395 28.814 32.1483 28.8364 32.2583 28.8364Z" fill="#6DBC53"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.8 KiB |
35
assets/icons/door_sensor.svg
Normal file
@ -0,0 +1,35 @@
|
||||
<svg width="38" height="47" viewBox="0 0 38 47" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_5442_18595)">
|
||||
<g filter="url(#filter1_i_5442_18595)">
|
||||
<path d="M5 7.15639C5 4.66815 6.82886 2.53419 9.30515 2.29062C13.3497 1.89279 16.6065 1.91012 20.6058 2.30139C23.094 2.54481 24.9399 4.68366 24.9399 7.18371V33.6749C24.9399 36.1374 23.1483 38.2593 20.7006 38.529C16.6673 38.9735 13.3539 38.9769 9.24395 38.5259C6.79422 38.2571 5 36.1349 5 33.6705V7.15639Z" fill="#EAF6FF"/>
|
||||
</g>
|
||||
<path d="M22.049 24.6587C22.1741 24.6587 22.2992 24.611 22.3947 24.5155C22.5856 24.3246 22.5856 24.0151 22.3947 23.8242C20.7605 22.1901 20.7605 19.5311 22.3947 17.897C22.5856 17.706 22.5856 17.3965 22.3947 17.2056C22.2037 17.0148 21.8943 17.0148 21.7034 17.2056C19.688 19.221 19.688 22.5002 21.7034 24.5156C21.7988 24.611 21.9239 24.6587 22.049 24.6587Z" fill="#8AC9FE"/>
|
||||
<path d="M23.0772 22.7595C23.1822 22.7595 23.2872 22.7195 23.3673 22.6394C23.5274 22.4792 23.5274 22.2195 23.3672 22.0594C23.047 21.7392 22.8707 21.3134 22.8707 20.8604C22.8707 20.4076 23.047 19.9818 23.3672 19.6616C23.5274 19.5014 23.5274 19.2417 23.3673 19.0816C23.207 18.9214 22.9473 18.9214 22.7873 19.0815C22.3121 19.5567 22.0504 20.1885 22.0504 20.8604C22.0504 21.5325 22.312 22.1642 22.7873 22.6394C22.8673 22.7194 22.9723 22.7595 23.0772 22.7595Z" fill="#8AC9FE"/>
|
||||
<path d="M15.837 31.6211L15.837 33.4829C15.837 33.8534 15.5367 34.1538 15.1661 34.1538C14.7955 34.1538 14.4952 33.8534 14.4952 33.4829L14.4952 31.6211C14.4952 31.2505 14.7955 30.9502 15.1661 30.9502C15.5367 30.9502 15.837 31.2505 15.837 31.6211Z" fill="#B3DAFE"/>
|
||||
<path d="M25.8903 10.5772C25.8903 9.69265 26.4679 8.89349 27.3345 8.71634C28.6715 8.44303 29.7509 8.4541 31.0716 8.72152C31.9473 8.89886 32.5369 9.70267 32.5369 10.5962V32.0694C32.5369 32.9344 31.9848 33.7213 31.1421 33.9165C29.784 34.231 28.6723 34.2337 27.2885 33.9148C26.4442 33.7202 25.8903 32.9329 25.8903 32.0664V10.5772Z" fill="#EAF6FF"/>
|
||||
<path d="M28.2773 24.6579C28.1523 24.6579 28.0271 24.6102 27.9316 24.5148C27.7407 24.3238 27.7407 24.0144 27.9316 23.8235C29.5658 22.1893 29.5658 19.5304 27.9316 17.8962C27.7407 17.7053 27.7407 17.3958 27.9316 17.2049C28.1226 17.0141 28.4321 17.0141 28.623 17.2049C30.6383 19.2203 30.6383 22.4995 28.623 24.5149C28.5275 24.6102 28.4024 24.6579 28.2773 24.6579Z" fill="#8AC9FE"/>
|
||||
<path d="M27.2491 22.7588C27.1441 22.7588 27.0392 22.7187 26.9591 22.6386C26.7989 22.4785 26.7989 22.2187 26.9591 22.0586C27.2793 21.7384 27.4557 21.3126 27.4557 20.8597C27.4557 20.4069 27.2793 19.9811 26.9591 19.6609C26.7989 19.5007 26.7989 19.241 26.9591 19.0809C27.1193 18.9206 27.379 18.9207 27.5391 19.0808C28.0142 19.556 28.276 20.1877 28.276 20.8597C28.276 21.5318 28.0143 22.1635 27.5391 22.6387C27.4591 22.7187 27.3541 22.7588 27.2491 22.7588Z" fill="#8AC9FE"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_5442_18595" x="0.5" y="0.5" width="36.5369" height="45.8633" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="3"/>
|
||||
<feGaussianBlur stdDeviation="2.25"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.07 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5442_18595"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5442_18595" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_i_5442_18595" x="4" y="2" width="20.9399" height="36.8633" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="-1"/>
|
||||
<feGaussianBlur stdDeviation="1.5"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.538295 0 0 0 0 0.538295 0 0 0 0 0.538295 0 0 0 0.3 0"/>
|
||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_5442_18595"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 4.2 KiB |
4
assets/icons/edit.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.10573 4.33603C7.94393 4.33603 7.81275 4.4672 7.81275 4.629V8.92602C7.81275 9.19526 7.5937 9.41431 7.32445 9.41431H1.07425C0.805006 9.41431 0.585956 9.19526 0.585956 8.92602V2.67582C0.585956 2.40657 0.805006 2.18752 1.07425 2.18752H5.37127C5.53307 2.18752 5.66425 2.05634 5.66425 1.89454C5.66425 1.73274 5.53307 1.60156 5.37127 1.60156H1.07425C0.48191 1.60156 0 2.08347 0 2.67582V8.92602C0 9.51836 0.48191 10.0003 1.07425 10.0003H7.32445C7.9168 10.0003 8.39871 9.51836 8.39871 8.92602V4.629C8.39871 4.4672 8.26753 4.33603 8.10573 4.33603Z" fill="#999999"/>
|
||||
<path d="M9.8001 0.752358L9.24764 0.199899C8.98113 -0.066633 8.54744 -0.066633 8.28087 0.199899L3.86134 4.61946C3.82044 4.66036 3.79256 4.71245 3.7812 4.76917L3.50496 6.15029C3.48576 6.24634 3.51582 6.34564 3.5851 6.4149C3.64059 6.47039 3.71533 6.50073 3.79225 6.50073C3.81137 6.50073 3.83059 6.49885 3.84969 6.49504L5.23081 6.2188C5.28753 6.20746 5.33963 6.17956 5.38053 6.13867L9.8001 1.71913C9.8001 1.71913 9.80012 1.71913 9.80012 1.71911C10.0666 1.4526 10.0666 1.01891 9.8001 0.752358ZM5.02893 5.66162L4.16574 5.83428L4.3384 4.97109L7.93559 1.37384L8.62616 2.06441L5.02893 5.66162ZM9.38577 1.3048L9.04049 1.65008L8.34992 0.959513L8.69518 0.614248C8.73327 0.576161 8.79523 0.576142 8.83331 0.614229L9.38575 1.16669C9.42386 1.20476 9.42386 1.26673 9.38577 1.3048Z" fill="#999999"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
135
assets/icons/garage_opener.svg
Normal file
@ -0,0 +1,135 @@
|
||||
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.90083 15.1252H43.099V45.7919H2.90083V15.1252Z" fill="url(#paint0_linear_5440_13841)"/>
|
||||
<path d="M2.90982 24.6665H17.3177V45.9979H2.90982V24.6665Z" fill="url(#paint1_linear_5440_13841)"/>
|
||||
<g clip-path="url(#clip0_5440_13841)">
|
||||
<path d="M2.90982 23.208H43.0902V35.5198H2.90982V23.208Z" fill="url(#paint2_linear_5440_13841)"/>
|
||||
<path d="M2.97646 14.5054H43.1137V19.2858H2.97646V14.5054Z" fill="url(#paint3_linear_5440_13841)"/>
|
||||
<path d="M2.97646 18.2937H43.1137V23.0741H2.97646V18.2937Z" fill="url(#paint4_linear_5440_13841)"/>
|
||||
<path d="M2.97646 22.1721H43.1137V26.9525H2.97646V22.1721Z" fill="url(#paint5_linear_5440_13841)"/>
|
||||
<path d="M2.97646 25.9019H43.1137V30.6822H2.97646V25.9019Z" fill="url(#paint6_linear_5440_13841)"/>
|
||||
<path d="M2.97646 29.6899H43.1137V34.4703H2.97646V29.6899Z" fill="url(#paint7_linear_5440_13841)"/>
|
||||
<path d="M2.97646 33.5684H43.1137V38.3488H2.97646V33.5684Z" fill="url(#paint8_linear_5440_13841)"/>
|
||||
<path d="M2.97646 37.3567H43.1137V42.1371H2.97646V37.3567Z" fill="url(#paint9_linear_5440_13841)"/>
|
||||
<path d="M2.97646 41.145H43.1137V45.9254H2.97646V41.145Z" fill="url(#paint10_linear_5440_13841)"/>
|
||||
</g>
|
||||
<path d="M43.9487 11.4238L27.5098 1.16353C26.2669 0.387843 24.6335 0 23 0C21.3665 0 19.7331 0.387843 18.4902 1.16353L2.05133 11.4238C0.775325 12.2202 0 13.6181 0 15.1223V43.1393C0 44.7192 1.28078 46 2.86075 46C3.67233 46 4.33031 45.342 4.33031 44.5304V19.1662C4.33031 17.4977 5.68298 16.1451 7.35143 16.1451H38.6486C40.3171 16.1451 41.6697 17.4977 41.6697 19.1662V44.5304C41.6697 45.342 42.3277 46 43.1393 46C44.7192 46 46 44.7192 46 43.1393V15.1223C46 13.6181 45.2247 12.2202 43.9487 11.4238Z" fill="url(#paint11_linear_5440_13841)"/>
|
||||
<path d="M43.9487 11.4238L27.5098 1.16353C26.2669 0.387843 24.6335 0 23 0C21.3665 0 19.7331 0.387843 18.4902 1.16353L2.05133 11.4238C0.775325 12.2202 0 13.6181 0 15.1223V19.4515C0 17.9474 0.775325 16.5495 2.05133 15.753L18.4902 5.49267C19.7331 4.71699 21.3665 4.32914 23 4.32914C24.6335 4.32914 26.2669 4.71699 27.5098 5.49267L43.9487 15.7529C45.2247 16.5494 46 17.9473 46 19.4514V15.1223C46 13.6181 45.2247 12.2202 43.9487 11.4238Z" fill="url(#paint12_linear_5440_13841)"/>
|
||||
<path d="M17.8604 10.225H28.1394C28.7214 10.225 29.1932 9.75314 29.1932 9.17119C29.1932 8.58916 28.7214 8.11743 28.1394 8.11743H17.8604C17.2784 8.11743 16.8067 8.58925 16.8067 9.17119C16.8067 9.75314 17.2785 10.225 17.8604 10.225Z" fill="url(#paint13_linear_5440_13841)"/>
|
||||
<path d="M17.8604 14.1061H28.1394C28.7214 14.1061 29.1932 13.6342 29.1932 13.0523C29.1932 12.4703 28.7214 11.9985 28.1394 11.9985H17.8604C17.2784 11.9985 16.8067 12.4704 16.8067 13.0523C16.8067 13.6342 17.2785 14.1061 17.8604 14.1061Z" fill="url(#paint14_linear_5440_13841)"/>
|
||||
<path d="M46 19.4528V43.1401C46 43.9303 45.6798 44.6455 45.1621 45.1632C44.6444 45.681 43.9291 46.0012 43.139 46.0012C42.3272 46.0012 41.6697 45.3436 41.6697 44.5319V19.1669C41.6697 17.4992 40.3167 16.1463 38.6481 16.1463H7.35188C5.68326 16.1463 4.33031 17.4992 4.33031 19.1669V44.5319C4.33031 44.9377 4.16616 45.3048 3.90008 45.5709C3.634 45.837 3.2669 46.0012 2.86102 46.0012C1.28078 46.0012 0 44.7204 0 43.1401V19.4528C0 17.9484 0.775686 16.5503 2.05106 15.7539L18.4902 5.4941C19.7331 4.71841 21.3665 4.33057 23 4.33057C24.6335 4.33057 26.2669 4.71841 27.5098 5.4941L43.9489 15.7539C45.2243 16.5503 46 17.9484 46 19.4528Z" fill="url(#paint15_linear_5440_13841)"/>
|
||||
<path d="M23.0904 1.80591C20.4573 1.80591 17.9048 2.56374 15.7087 3.99758C15.125 4.37866 14.9608 5.16075 15.3419 5.74441L17.4195 7.82857C17.3425 8.10421 17.3789 8.41007 17.547 8.66893L19.4795 10.6277C19.4069 10.8494 19.4308 11.1006 19.5668 11.3121L21.6297 13.3334C21.4927 13.8399 21.6217 14.4034 22.0194 14.8011L23.364 16.1458H38.6486C40.3172 16.1458 41.6698 17.4984 41.6698 19.1669V34.4516L46.0001 38.7819V19.5336L30.4719 3.99758C28.2759 2.56383 25.7234 1.80591 23.0904 1.80591Z" fill="url(#paint16_linear_5440_13841)"/>
|
||||
<path d="M26.2823 10.1142C25.3034 9.4853 24.1685 9.15283 23.0003 9.15283C21.8322 9.15283 20.6974 9.48529 19.7184 10.1141C19.3451 10.354 19.237 10.8509 19.4767 11.224C19.7165 11.5971 20.2134 11.7053 20.5866 11.4656C21.306 11.0035 22.1407 10.7591 23.0003 10.7591C23.86 10.7591 24.6947 11.0035 25.4141 11.4656C25.5485 11.552 25.6987 11.5932 25.8475 11.5932C26.1117 11.5932 26.3705 11.4628 26.5239 11.224C26.7637 10.851 26.6555 10.354 26.2823 10.1142Z" fill="url(#paint17_linear_5440_13841)"/>
|
||||
<path d="M28.2399 7.15312C26.6796 6.13968 24.8678 5.604 23.0002 5.604C21.1326 5.604 19.3207 6.13968 17.7604 7.15303C17.2821 7.46367 17.1462 8.10325 17.4569 8.58156C17.7676 9.05987 18.4072 9.1957 18.8854 8.88507C20.11 8.08972 21.5329 7.66931 23.0002 7.66931C24.4675 7.66931 25.8904 8.08972 27.1149 8.88507C27.2887 8.9979 27.4837 9.05184 27.6764 9.05184C28.0144 9.05184 28.3456 8.88606 28.5434 8.58156C28.8541 8.10325 28.7183 7.46376 28.2399 7.15312Z" fill="url(#paint18_linear_5440_13841)"/>
|
||||
<path d="M30.3818 3.91003C28.1858 2.47618 25.6333 1.71826 23.0002 1.71826C20.3671 1.71826 17.8146 2.47609 15.6185 3.90994C15.0349 4.29102 14.8706 5.07311 15.2517 5.65676C15.6328 6.24042 16.4149 6.40467 16.9985 6.02359C18.7832 4.85844 20.8585 4.24258 23.0002 4.24258C25.1419 4.24258 27.2172 4.85844 29.0018 6.02368C29.2147 6.16267 29.454 6.22915 29.6907 6.22915C30.1027 6.22915 30.5066 6.02765 30.7487 5.65685C31.1297 5.0732 30.9655 4.29111 30.3818 3.91003Z" fill="url(#paint19_linear_5440_13841)"/>
|
||||
<path d="M23 15.1546C23.8365 15.1546 24.5146 14.4765 24.5146 13.6401C24.5146 12.8036 23.8365 12.1255 23 12.1255C22.1635 12.1255 21.4854 12.8036 21.4854 13.6401C21.4854 14.4765 22.1635 15.1546 23 15.1546Z" fill="url(#paint20_linear_5440_13841)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_5440_13841" x1="22.9999" y1="26.6975" x2="22.9999" y2="42.9091" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#62DBFB"/>
|
||||
<stop offset="0.1912" stop-color="#57D5FA"/>
|
||||
<stop offset="0.5232" stop-color="#3BC5F7"/>
|
||||
<stop offset="0.954" stop-color="#0DABF2"/>
|
||||
<stop offset="1" stop-color="#08A9F1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_5440_13841" x1="7.93726" y1="35.3322" x2="3.33726" y2="35.3322" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#0593FC" stop-opacity="0"/>
|
||||
<stop offset="0.6831" stop-color="#0389FC" stop-opacity="0.683"/>
|
||||
<stop offset="1" stop-color="#0182FC"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_5440_13841" x1="23" y1="30.559" x2="23" y2="24.425" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#0593FC" stop-opacity="0"/>
|
||||
<stop offset="0.6831" stop-color="#0389FC" stop-opacity="0.683"/>
|
||||
<stop offset="1" stop-color="#0182FC"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_5440_13841" x1="23.0451" y1="16.3093" x2="23.0451" y2="18.8364" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#017297"/>
|
||||
<stop offset="1" stop-color="#024C67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_5440_13841" x1="23.0451" y1="20.0976" x2="23.0451" y2="22.6247" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#017297"/>
|
||||
<stop offset="1" stop-color="#024C67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_5440_13841" x1="23.0451" y1="23.976" x2="23.0451" y2="26.5032" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#017297"/>
|
||||
<stop offset="1" stop-color="#024C67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_5440_13841" x1="23.0451" y1="27.7058" x2="23.0451" y2="30.2329" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#017297"/>
|
||||
<stop offset="1" stop-color="#024C67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_5440_13841" x1="23.0451" y1="31.4939" x2="23.0451" y2="34.021" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#017297"/>
|
||||
<stop offset="1" stop-color="#024C67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_5440_13841" x1="23.0451" y1="35.3723" x2="23.0451" y2="37.8994" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#017297"/>
|
||||
<stop offset="1" stop-color="#024C67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_5440_13841" x1="23.0451" y1="39.1606" x2="23.0451" y2="41.6877" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#017297"/>
|
||||
<stop offset="1" stop-color="#024C67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_5440_13841" x1="23.0451" y1="42.9489" x2="23.0451" y2="45.4761" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#017297"/>
|
||||
<stop offset="1" stop-color="#024C67"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_5440_13841" x1="10.4052" y1="6.49746" x2="31.8719" y2="44.7406" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EAF9FA"/>
|
||||
<stop offset="1" stop-color="#B3DAFE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_5440_13841" x1="23" y1="-6.67325" x2="23" y2="20.2765" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#7BACDF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#7BACDF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint13_linear_5440_13841" x1="22.9999" y1="9.94381" x2="22.9999" y2="8.00306" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EAF9FA"/>
|
||||
<stop offset="1" stop-color="#B3DAFE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint14_linear_5440_13841" x1="22.9999" y1="13.8249" x2="22.9999" y2="11.8842" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EAF9FA"/>
|
||||
<stop offset="1" stop-color="#B3DAFE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint15_linear_5440_13841" x1="15.8981" y1="17.0691" x2="11.749" y2="8.86121" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#7BACDF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#7BACDF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint16_linear_5440_13841" x1="34.6406" y1="18.1076" x2="21.7425" y2="0.338961" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#7BACDF" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#7BACDF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint17_linear_5440_13841" x1="22.3544" y1="8.94195" x2="23.4558" y2="12.0935" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#AEFFD1"/>
|
||||
<stop offset="0.1201" stop-color="#A3F9CB"/>
|
||||
<stop offset="0.3288" stop-color="#87EAB9"/>
|
||||
<stop offset="0.6012" stop-color="#59D19D"/>
|
||||
<stop offset="0.9235" stop-color="#19AF77"/>
|
||||
<stop offset="1" stop-color="#09A76D"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint18_linear_5440_13841" x1="22.0741" y1="4.65406" x2="23.3286" y2="9.21302" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#AEFFD1"/>
|
||||
<stop offset="0.1201" stop-color="#A3F9CB"/>
|
||||
<stop offset="0.3288" stop-color="#87EAB9"/>
|
||||
<stop offset="0.6012" stop-color="#59D19D"/>
|
||||
<stop offset="0.9235" stop-color="#19AF77"/>
|
||||
<stop offset="1" stop-color="#09A76D"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint19_linear_5440_13841" x1="22.0308" y1="1.42034" x2="23.377" y2="6.34649" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#AEFFD1"/>
|
||||
<stop offset="0.1201" stop-color="#A3F9CB"/>
|
||||
<stop offset="0.3288" stop-color="#87EAB9"/>
|
||||
<stop offset="0.6012" stop-color="#59D19D"/>
|
||||
<stop offset="0.9235" stop-color="#19AF77"/>
|
||||
<stop offset="1" stop-color="#09A76D"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint20_linear_5440_13841" x1="21.5313" y1="12.1714" x2="23.9638" y2="14.6039" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#AEFFD1"/>
|
||||
<stop offset="0.1201" stop-color="#A3F9CB"/>
|
||||
<stop offset="0.3288" stop-color="#87EAB9"/>
|
||||
<stop offset="0.6012" stop-color="#59D19D"/>
|
||||
<stop offset="0.9235" stop-color="#19AF77"/>
|
||||
<stop offset="1" stop-color="#09A76D"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_5440_13841">
|
||||
<rect width="40.2039" height="31.4199" fill="white" transform="translate(2.90982 14.5054)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
3
assets/icons/gym_icon.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="50" height="30" viewBox="0 0 50 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M46.9297 10.1854H46.1628V8.09995C46.1628 5.69517 44.2063 3.73882 41.8016 3.73882H40.7138C40.2521 2.02515 38.6854 0.76001 36.8278 0.76001C34.6087 0.76001 32.8033 2.56528 32.8033 4.78442V11.4443H17.1966V4.78442C17.1966 2.56528 15.3912 0.76001 13.1722 0.76001C11.3147 0.76001 9.74795 2.02515 9.28633 3.73882H8.19844C5.79365 3.73882 3.83721 5.69517 3.83721 8.09995V10.1854H3.07031C1.37734 10.1854 0 11.5628 0 13.2557V16.7332C0 18.4261 1.37734 19.8034 3.07031 19.8034H3.8373V21.8999C3.8373 24.3047 5.79375 26.2611 8.19854 26.2611H9.28643C9.74805 27.9748 11.3148 29.2399 13.1723 29.2399C15.3914 29.2399 17.1967 27.4346 17.1967 25.2155V18.5556H30.5755C30.9801 18.5556 31.3079 18.2278 31.3079 17.8232C31.3079 17.4186 30.9801 17.0908 30.5755 17.0908H17.1966V12.909H32.8033V25.2156C32.8033 27.4347 34.6087 29.24 36.8278 29.24C38.6854 29.24 40.2521 27.9748 40.7138 26.2612H41.8016C44.2063 26.2612 46.1628 24.3048 46.1628 21.9V19.8035H46.9297C48.6227 19.8035 50 18.4262 50 16.7332V13.2558C50 11.5627 48.6227 10.1854 46.9297 10.1854ZM3.8373 18.3387H3.07031C2.18506 18.3387 1.46484 17.6184 1.46484 16.7332V13.2558C1.46484 12.3706 2.18506 11.6503 3.07031 11.6503H3.8373V18.3387ZM15.7317 25.2156C15.7317 26.6269 14.5835 27.7751 13.1722 27.7751C11.7607 27.7751 10.6126 26.6269 10.6126 25.2156V10.4378C10.6126 10.0333 10.2847 9.70542 9.88018 9.70542C9.47568 9.70542 9.14775 10.0333 9.14775 10.4378V24.7964H8.19854C6.60147 24.7964 5.30215 23.4971 5.30215 21.9001V8.09985C5.30215 6.50278 6.60147 5.20356 8.19854 5.20356H9.14775V7.19302C9.14775 7.59761 9.47568 7.92544 9.88018 7.92544C10.2847 7.92544 10.6126 7.59761 10.6126 7.19302V4.78433C10.6126 3.373 11.7608 2.22476 13.1722 2.22476C14.5836 2.22476 15.7317 3.373 15.7317 4.78433V25.2156ZM39.3875 25.2156C39.3875 26.6269 38.2393 27.7751 36.8278 27.7751C35.4164 27.7751 34.2682 26.6269 34.2682 25.2156V4.78433C34.2682 3.373 35.4164 2.22476 36.8278 2.22476C38.2393 2.22476 39.3875 3.373 39.3875 4.78433V25.2156ZM44.6979 21.9C44.6979 23.497 43.3986 24.7963 41.8016 24.7963H40.8523V5.20356H41.8016C43.3986 5.20356 44.6979 6.50288 44.6979 8.09985V21.9ZM48.5352 16.7332C48.5352 17.6184 47.8149 18.3386 46.9297 18.3386H46.1628V11.6502H46.9297C47.8149 11.6502 48.5352 12.3705 48.5352 13.2557V16.7332Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
4
assets/icons/icon_edit_icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.8414 6.50355C3.08411 6.50355 3.28087 6.70031 3.28087 6.94302V13.3885C3.28087 13.7924 3.60945 14.121 4.01332 14.121H13.3886C13.7925 14.121 14.1211 13.7924 14.1211 13.3885V4.01324C14.1211 3.60936 13.7925 3.28079 13.3886 3.28079H6.9431C6.7004 3.28079 6.50363 3.08403 6.50363 2.84132C6.50363 2.59862 6.7004 2.40186 6.9431 2.40186H13.3886C14.2771 2.40186 15 3.12472 15 4.01324V13.3885C15 14.2771 14.2771 14.9999 13.3886 14.9999H4.01332C3.1248 14.9999 2.40194 14.2771 2.40194 13.3885V6.94302C2.40194 6.70031 2.5987 6.50355 2.8414 6.50355Z" fill="#999999"/>
|
||||
<path d="M0.299726 1.12854L1.12842 0.299849C1.52818 -0.0999495 2.17871 -0.0999495 2.57857 0.299849L9.20787 6.92918C9.26922 6.99053 9.31103 7.06867 9.32808 7.15375L9.74244 9.22543C9.77124 9.36952 9.72615 9.51847 9.62223 9.62236C9.539 9.70559 9.42688 9.75109 9.3115 9.75109C9.28282 9.75109 9.25399 9.74828 9.22534 9.74257L7.15366 9.32821C7.06858 9.31118 6.99044 9.26935 6.92909 9.208L0.299726 2.57869C0.299726 2.57869 0.299697 2.57869 0.299697 2.57866C-0.100072 2.17889 -0.100072 1.52836 0.299726 1.12854ZM7.45648 8.49243L8.75127 8.75142L8.49228 7.45663L3.0965 2.06076L2.06064 3.09662L7.45648 8.49243ZM0.92122 1.9572L1.43915 2.47512L2.475 1.43927L1.9571 0.921372C1.89997 0.864242 1.80704 0.864212 1.74991 0.921343L0.921249 1.75003C0.86409 1.80713 0.864089 1.9001 0.92122 1.9572Z" fill="#999999"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
4
assets/icons/location_icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="75" height="75" viewBox="0 0 75 75" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M37.4987 13.667C35.4448 13.667 33.468 14.2849 31.7821 15.4538C31.2838 15.7994 31.1578 16.4865 31.5007 16.9887C31.8438 17.4908 32.5258 17.6177 33.0242 17.2723C34.3431 16.3578 35.8903 15.8744 37.4987 15.8744C41.8572 15.8744 45.403 19.4468 45.403 23.838C45.403 28.2292 41.8572 31.8018 37.4987 31.8018C33.1402 31.8018 29.5944 28.2292 29.5944 23.838C29.5944 22.5426 29.8929 21.3078 30.4816 20.1678C30.7608 19.627 30.5522 18.9606 30.0155 18.6794C29.4787 18.3983 28.8176 18.6082 28.5382 19.149C27.796 20.5863 27.4036 22.2078 27.4036 23.838C27.4037 29.4464 31.9323 34.0091 37.4987 34.0091C43.0651 34.0091 47.5937 29.4464 47.5937 23.838C47.5937 18.2297 43.0651 13.667 37.4987 13.667Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M74.9158 73.4723L64.1047 47.3007C63.9348 46.8892 63.5359 46.6211 63.0935 46.6211H52.32C54.4155 43.765 56.1597 40.9201 57.5218 38.1268C59.9359 33.1765 61.1598 28.369 61.1598 23.8377C61.1596 10.6935 50.546 0 37.4999 0C24.4539 0 13.8402 10.6935 13.8402 23.8375C13.8402 28.3689 15.0641 33.1765 17.4781 38.1267C18.8402 40.92 20.5843 43.765 22.68 46.621H11.9065C11.4641 46.621 11.0651 46.8892 10.8953 47.3005L3.52829 65.1344C3.29582 65.6972 3.56008 66.3432 4.11862 66.5773C4.25632 66.635 4.3987 66.6624 4.53903 66.6624C4.96823 66.6624 5.37561 66.4066 5.55066 65.9826L6.60183 63.4378H14.0588L10.1945 72.7926H2.73772L3.85788 70.0808C4.09035 69.518 3.8261 68.872 3.26755 68.6379C2.70871 68.4034 2.0677 68.67 1.83537 69.2326L0.0841524 73.4723C-0.056619 73.8129 -0.019119 74.202 0.184201 74.5087C0.387229 74.8156 0.729123 75 1.09533 75H73.9045C74.2706 75 74.6126 74.8156 74.8158 74.5087C75.019 74.202 75.0566 73.8129 74.9158 73.4723ZM16.031 23.8375C16.031 11.9105 25.6619 2.20723 37.4999 2.20723C49.3379 2.20723 58.9688 11.9106 58.9688 23.8375C58.9688 28.839 57.244 36.8312 49.265 47.0159C49.2569 47.0254 49.2497 47.0355 49.2421 47.0454C48.8346 47.5649 48.4112 48.0901 47.9705 48.6211C43.5859 53.9036 39.1489 57.761 37.4998 59.1315C35.8555 57.7657 31.4394 53.9276 27.0579 48.6552C26.6062 48.1116 26.1729 47.5742 25.7558 47.0424C25.7491 47.0339 25.7428 47.0251 25.7358 47.0168C17.7571 36.8328 16.031 28.8409 16.031 23.8375ZM12.637 48.8284H20.0941L17.3741 55.4125H9.91721L12.637 48.8284ZM19.0424 72.7928L25.8893 56.2184L45.3737 72.7928H19.0424ZM48.7697 72.7928L26.1595 53.5594C25.8926 53.3322 25.5341 53.2471 25.1951 53.33C24.8558 53.4127 24.5758 53.6537 24.4417 53.9785L16.6697 72.7926H12.5675L16.7125 62.7582C16.8532 62.4176 16.8157 62.0287 16.6124 61.7218C16.4094 61.4149 16.0674 61.2305 15.7011 61.2305H7.51399L9.00549 57.6196H18.1048C18.5472 57.6196 18.9462 57.3514 19.116 56.9401L22.467 48.8282H24.368C24.6981 49.2428 25.0335 49.6575 25.3779 50.072C31.03 56.8733 36.5954 61.2398 36.8296 61.4225C37.0271 61.5765 37.2635 61.6532 37.4999 61.6532C37.7363 61.6532 37.9729 61.5763 38.1702 61.4225C38.299 61.3222 40.0389 59.9563 42.5169 57.6198H54.9213C55.5263 57.6198 56.0167 57.1257 56.0167 56.5162C56.0167 55.9066 55.5263 55.4125 54.9213 55.4125H44.7745C46.2932 53.874 47.9532 52.0802 49.6221 50.0722C49.9665 49.6576 50.3021 49.2431 50.632 48.8284H62.3629L65.0826 55.4125H59.3028C58.6978 55.4125 58.2074 55.9066 58.2074 56.5162C58.2074 57.1257 58.6977 57.6198 59.3028 57.6198H65.9944L67.4859 61.2306H44.917C44.4598 61.2306 44.0508 61.5166 43.8907 61.9481C43.7309 62.3796 43.8537 62.8658 44.1989 63.1677L55.2048 72.7928H48.7697ZM58.5469 72.7928L47.8501 63.438H68.3979L72.2623 72.7928H58.5469Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
6
assets/icons/parking_icon.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="51" height="50" viewBox="0 0 51 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M32.0481 20.6052C32.0481 17.6436 29.6386 15.2341 26.677 15.2341H19.3528C18.8135 15.2341 18.3762 15.6714 18.3762 16.2107V24.9998C18.3762 25.539 18.8135 25.9763 19.3528 25.9763H26.677C29.6386 25.9763 32.0481 23.5668 32.0481 20.6052ZM20.3293 17.1873H26.677C28.5617 17.1873 30.095 18.7206 30.095 20.6052C30.095 22.4899 28.5617 24.0232 26.677 24.0232H20.3293V17.1873Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M37.907 20.6052C37.907 14.4127 32.869 9.37476 26.6765 9.37476H13.4929C12.9537 9.37476 12.5164 9.81206 12.5164 10.3513V39.6482C12.5164 40.1875 12.9537 40.6248 13.4929 40.6248H19.3523C19.8916 40.6248 20.3289 40.1875 20.3289 39.6482V31.8357H26.6765C32.869 31.8357 37.907 26.7977 37.907 20.6052ZM19.3523 29.8826C18.813 29.8826 18.3757 30.3199 18.3757 30.8591V38.6716H14.4695V11.3279H26.6765C31.792 11.3279 35.9539 15.4897 35.9539 20.6052C35.9539 25.7208 31.792 29.8826 26.6765 29.8826H19.3523Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M25.2119 49.9998C25.7513 49.9998 26.1885 49.5625 26.1885 49.0232C26.1885 48.4839 25.7513 48.0466 25.2119 48.0466C24.6726 48.0466 24.2354 48.4839 24.2354 49.0232C24.2354 49.5625 24.6726 49.9998 25.2119 49.9998Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M46.3057 -0.000244141H4.11816C1.96426 -0.000244141 0.211914 1.7521 0.211914 3.90601V46.0935C0.211914 48.2474 1.96426 49.9998 4.11816 49.9998H20.8174C21.3566 49.9998 21.7939 49.5625 21.7939 49.0232C21.7939 48.4839 21.3566 48.0466 20.8174 48.0466H4.11816C3.04121 48.0466 2.16504 47.1705 2.16504 46.0935V3.90601C2.16504 2.82905 3.04121 1.95288 4.11816 1.95288H46.3057C47.3826 1.95288 48.2588 2.82905 48.2588 3.90601V46.0935C48.2588 47.1705 47.3826 48.0466 46.3057 48.0466H29.6064C29.0672 48.0466 28.6299 48.4839 28.6299 49.0232C28.6299 49.5625 29.0672 49.9998 29.6064 49.9998H46.3057C48.4596 49.9998 50.2119 48.2474 50.2119 46.0935V3.90601C50.2119 1.7521 48.4596 -0.000244141 46.3057 -0.000244141Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
5
assets/icons/pool_icon.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="51" height="40" viewBox="0 0 51 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M49.8891 26.9381C49.5548 26.7112 49.0988 26.7988 48.8707 27.1324C48.8093 27.2223 47.3338 29.3345 44.6242 29.3345C41.9146 29.3345 40.4392 27.2223 40.3792 27.1348C40.1093 26.7072 39.4304 26.7077 39.1608 27.1354C39.146 27.1574 37.6537 29.3346 34.9199 29.3346C32.6284 29.3346 31.2198 27.8243 30.8033 27.3051V15.9333H49.478C49.8834 15.9333 50.2119 15.6048 50.2119 15.1994C50.2119 14.7941 49.8834 14.4655 49.478 14.4655H43.5765V9.11693C43.5765 4.2646 39.6757 0.279264 34.881 0.232877C32.5221 0.209147 30.2976 1.11364 28.618 2.77701C27.8048 3.58238 27.1703 4.51773 26.7301 5.53521C25.3736 2.44605 22.3229 0.267154 18.7851 0.232877C18.756 0.232584 18.7269 0.232486 18.6978 0.232486C16.3712 0.232486 14.181 1.13414 12.5221 2.77701C10.8422 4.44077 9.91691 6.65591 9.91691 9.0143V14.4656H1.00151C0.596138 14.4656 0.267623 14.7942 0.267623 15.1995C0.267623 15.6049 0.596138 15.9334 1.00151 15.9334H9.91691V18.8315C9.91691 19.2368 10.2454 19.5653 10.6508 19.5653C11.0562 19.5653 11.3847 19.2368 11.3847 18.8315V9.0143C11.3847 7.05053 12.1554 5.20581 13.555 3.81978C14.9541 2.43424 16.805 1.67721 18.7711 1.70055C22.7641 1.73912 26.0129 5.06616 26.0129 9.11693V14.4655H24.1579V9.0143C24.1579 6.05532 21.7514 3.60669 18.7936 3.55601C18.7624 3.55552 18.7315 3.55523 18.7004 3.55523C17.284 3.55523 15.9419 4.10923 14.9124 5.12124C13.8493 6.16626 13.2397 7.61577 13.2397 9.09809V28.7945C12.2613 28.3032 11.6343 27.6096 11.3846 27.2967V21.7668C11.3846 21.3614 11.0561 21.0329 10.6507 21.0329C10.2453 21.0329 9.91681 21.3614 9.91681 21.7668V27.3041C9.49885 27.8253 8.09045 29.3345 5.79983 29.3345C3.09017 29.3345 1.61479 27.2223 1.55483 27.1348C1.32866 26.7985 0.872699 26.7093 0.536372 26.9353C0.200045 27.1614 0.11069 27.6174 0.336861 27.9538C0.414986 28.0701 2.29232 30.8023 5.79974 30.8023C8.19768 30.8023 9.83361 29.5254 10.6536 28.6803C11.4736 29.5254 13.1097 30.8023 15.5075 30.8023C17.9049 30.8023 19.539 29.5261 20.3583 28.6806C21.1785 29.5259 22.8143 30.8023 25.2117 30.8023C27.6096 30.8023 29.2456 29.5254 30.0656 28.6803C30.8856 29.5254 32.5216 30.8023 34.9195 30.8023C37.3168 30.8023 38.9509 29.5261 39.7702 28.6806C40.5905 29.5259 42.2263 30.8023 44.6236 30.8023C48.1312 30.8023 50.0084 28.0701 50.0865 27.9538C50.3125 27.6183 50.2235 27.1649 49.8891 26.9381ZM14.7074 21.033H26.0129V23.0877H14.7074V21.033ZM26.0129 19.5652H14.7074V15.9333H26.0129V19.5652ZM15.9414 6.16802C16.7105 5.41196 17.7143 5.00562 18.7684 5.02359C20.9309 5.06069 22.6902 6.85092 22.6902 9.01439V14.4657H14.7075V9.09818C14.7074 8.00678 15.1572 6.93881 15.9414 6.16802ZM20.9671 27.1348C20.6974 26.7096 20.0219 26.7093 19.7503 27.1331C19.689 27.2229 18.2169 29.3345 15.5078 29.3345C15.2274 29.3345 14.9611 29.3109 14.7074 29.2703V24.5554H26.0129V29.2702C25.7591 29.3108 25.4926 29.3345 25.212 29.3345C22.5024 29.3345 21.0269 27.2223 20.9671 27.1348ZM27.4805 28.7942V9.0143C27.4805 7.05053 28.2512 5.20581 29.6508 3.81978C31.05 2.43424 32.901 1.67721 34.8668 1.70055C38.86 1.73912 42.1087 5.06616 42.1087 9.11693V14.4655H40.2537V12.8342C40.2537 12.4288 39.9252 12.1003 39.5199 12.1003C39.1145 12.1003 38.786 12.4288 38.786 12.8342V14.4655H30.8032V9.09799C30.8032 8.00668 31.253 6.93872 32.0372 6.16782C32.8063 5.41177 33.8082 5.00542 34.8642 5.02339C37.0267 5.0605 38.786 6.85073 38.786 9.0142V9.89877C38.786 10.3041 39.1145 10.6327 39.5199 10.6327C39.9252 10.6327 40.2537 10.3041 40.2537 9.89877V9.0142C40.2537 6.05522 37.8473 3.6066 34.8895 3.55591C34.8582 3.55543 34.8274 3.55513 34.7962 3.55513C33.3798 3.55513 32.0378 4.10913 31.0083 5.12114C29.9453 6.16616 29.3355 7.61567 29.3355 9.09799V27.2957C29.0851 27.6098 28.4581 28.3032 27.4805 28.7942Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M20.3612 38.299C17.6516 38.299 16.1762 36.1868 16.1162 36.0993C15.8468 35.6742 15.1717 35.6738 14.8998 36.0969C14.8384 36.1869 13.3629 38.2991 10.6533 38.2991C7.94379 38.2991 6.4683 36.1869 6.40834 36.0994C6.18217 35.763 5.72621 35.6737 5.38989 35.8999C5.05356 36.1259 4.96421 36.5819 5.19038 36.9182C5.2685 37.0345 7.14574 39.7668 10.6533 39.7668C13.0512 39.7668 14.6871 38.4898 15.5071 37.6447C16.3272 38.4898 17.9632 39.7668 20.3611 39.7668C20.7665 39.7668 21.095 39.4382 21.095 39.0329C21.095 38.6275 20.7666 38.299 20.3612 38.299Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M45.0344 35.9023C44.6997 35.6758 44.244 35.7639 44.0161 36.0977C43.9548 36.1876 42.4828 38.2992 39.7736 38.2992C37.064 38.2992 35.5886 36.187 35.5286 36.0995C35.2589 35.6721 34.5804 35.6722 34.3107 36.0995C34.2958 36.1215 32.8 38.2992 30.0656 38.2992C27.356 38.2992 25.8806 36.187 25.8206 36.0995C25.551 35.6742 24.8754 35.6739 24.6038 36.0977C24.598 36.1062 24.0058 36.963 22.9133 37.6006C22.5633 37.8049 22.4452 38.2544 22.6496 38.6044C22.8539 38.9543 23.3032 39.0723 23.6534 38.8682C24.3275 38.4747 24.8488 38.0172 25.2112 37.6442C26.031 38.4893 27.6671 39.767 30.0656 39.767C32.4636 39.767 34.0995 38.49 34.9195 37.6449C35.7396 38.49 37.3756 39.767 39.7734 39.767C43.2814 39.767 45.1552 37.0341 45.2332 36.9178C45.4586 36.582 45.3691 36.1288 45.0344 35.9023Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 5.0 KiB |
43
assets/icons/power_clamp.svg
Normal file
@ -0,0 +1,43 @@
|
||||
<svg width="43" height="49" viewBox="0 0 43 49" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M35.0973 48.4922H7.91913C6.83924 48.4922 5.96387 47.6168 5.96387 46.5369V35.1964L21.4593 35.2942L37.0525 35.1964L37.1503 36.5651V46.6347C37.1503 46.8037 37.1289 46.9677 37.0885 47.1241C36.8713 47.9671 36.0081 48.4922 35.0973 48.4922Z" fill="#8D9CA8"/>
|
||||
<path d="M37.1502 36.5633V35.0968L21.5569 34.8524L5.86597 35.0968V46.6329C5.86597 47.7128 6.74134 48.5881 7.82123 48.5881H35.1949C36.1057 48.5881 36.8687 47.9645 37.086 47.1217H8.31004C7.7701 47.1217 7.33241 46.684 7.33241 46.1441V37.5409C7.33241 37.001 7.7701 36.5633 8.31004 36.5633H37.1502Z" fill="#7A8C98"/>
|
||||
<path d="M18.4773 44.5817H17.6952C17.1552 44.5817 16.7175 44.144 16.7175 43.604V35.1964H19.4549L19.5527 36.5651V43.213L19.4549 43.604C19.4549 44.144 19.0172 44.5817 18.4773 44.5817Z" fill="#CCF49F"/>
|
||||
<path d="M11.634 44.5817H10.8519C10.312 44.5817 9.87427 44.144 9.87427 43.604V35.1964H12.6116L12.7094 36.5651V43.213L12.6116 43.604C12.6116 44.144 12.1739 44.5817 11.634 44.5817Z" fill="#CCF49F"/>
|
||||
<path d="M25.3208 44.5817H24.5387C23.9987 44.5817 23.561 44.144 23.561 43.604V35.1964H26.2984L26.3962 36.5651V43.213L26.2984 43.604C26.2984 44.144 25.8607 44.5817 25.3208 44.5817Z" fill="#CCF49F"/>
|
||||
<path d="M32.1643 44.5817H31.3822C30.8422 44.5817 30.4045 44.144 30.4045 43.604V35.1964H33.1419L33.2397 36.5651V43.213L33.1419 43.604C33.1419 44.144 32.7042 44.5817 32.1643 44.5817Z" fill="#CCF49F"/>
|
||||
<path d="M19.5528 36.5647V35.0982L18.0863 34.8049L16.6199 35.0982V43.7014C16.6199 44.2413 17.0576 44.679 17.5975 44.679H18.5751C19.1151 44.679 19.5528 44.2413 19.5528 43.7014V43.2126H18.3796C18.2176 43.2126 18.0863 43.0813 18.0863 42.9193V36.858C18.0863 36.696 18.2176 36.5647 18.3796 36.5647H19.5528Z" fill="#B3E59F"/>
|
||||
<path d="M12.7093 36.5647V35.0982L11.2428 34.8049L9.77637 35.0982V43.7014C9.77637 44.2413 10.2141 44.679 10.754 44.679H11.7316C12.2716 44.679 12.7093 44.2413 12.7093 43.7014V43.2126H11.5361C11.3741 43.2126 11.2428 43.0813 11.2428 42.9193V36.858C11.2428 36.696 11.3741 36.5647 11.5361 36.5647H12.7093Z" fill="#B3E59F"/>
|
||||
<path d="M26.396 36.5647V35.0982L24.9296 34.8049L23.4631 35.0982V43.7014C23.4631 44.2413 23.9008 44.679 24.4408 44.679H25.4184C25.9583 44.679 26.396 44.2413 26.396 43.7014V43.2126H25.2229C25.0609 43.2126 24.9296 43.0813 24.9296 42.9193V36.858C24.9296 36.696 25.0609 36.5647 25.2229 36.5647H26.396Z" fill="#B3E59F"/>
|
||||
<path d="M33.2395 36.5647V35.0982L31.7731 34.8049L30.3066 35.0982V43.7014C30.3066 44.2413 30.7443 44.679 31.2843 44.679H32.2619C32.8018 44.679 33.2395 44.2413 33.2395 43.7014V43.2126H32.0664C31.9044 43.2126 31.7731 43.0813 31.7731 42.9193V36.858C31.7731 36.696 31.9044 36.5647 32.0664 36.5647H33.2395Z" fill="#B3E59F"/>
|
||||
<path d="M33.2393 38.0315H10.2649L9.87387 38.1293C9.33393 38.1293 8.89624 38.5669 8.89624 39.1069V39.889C8.89624 40.4289 9.33393 40.8666 9.87387 40.8666H33.1415C33.6814 40.8666 34.1191 40.4289 34.1191 39.889L34.2169 39.4979V39.0091C34.2169 38.4692 33.7792 38.0315 33.2393 38.0315Z" fill="#B6C4CF"/>
|
||||
<path d="M10.5586 39.4979C10.3966 39.4979 10.2653 39.3666 10.2653 39.2047V38.0315H9.77646C9.23651 38.0315 8.79883 38.4692 8.79883 39.0091V39.9868C8.79883 40.5267 9.23651 40.9644 9.77646 40.9644H33.2396C33.7796 40.9644 34.2172 40.5267 34.2172 39.9868V39.4979H10.5586Z" fill="#9FACBA"/>
|
||||
<path d="M39.8875 34.9999H3.03079C1.41096 34.9999 0.0979004 33.6869 0.0979004 32.067V3.03139C0.0979004 1.94602 0.589746 0.900544 1.46619 0.393349C1.89762 0.143662 2.39866 0.000732422 2.93303 0.000732422H39.9853C41.6051 0.000732422 42.9181 1.31379 42.9181 2.93363V32.1648C42.9181 32.6992 42.7752 33.2002 42.5255 33.6316C42.0183 34.5081 40.9729 34.9999 39.8875 34.9999Z" fill="#B6C4CF"/>
|
||||
<path d="M3.17007 33.6317C2.22919 33.6317 1.46645 32.869 1.46645 31.9281V0.394531C0.590098 0.901726 0 1.84876 0 2.93412V32.1653C0 33.7851 1.31306 35.0982 2.93289 35.0982H39.9851C41.0705 35.0982 42.0175 34.5081 42.5247 33.6317H3.17007Z" fill="#9FACBA"/>
|
||||
<path d="M38.9098 32.0665H4.00839C3.46845 32.0665 3.03076 31.6288 3.03076 31.0889V4.0085C3.03076 3.46855 3.46845 3.03087 4.00839 3.03087L4.39945 2.93311H39.0076C39.5475 2.93311 39.9852 3.37079 39.9852 3.91074V30.6978L39.8875 31.0889C39.8875 31.6288 39.4498 32.0665 38.9098 32.0665Z" fill="#F8F7F7"/>
|
||||
<path d="M4.88812 30.6978C4.6182 30.6978 4.39931 30.4789 4.39931 30.209V2.93311H3.91049C3.37055 2.93311 2.93286 3.37079 2.93286 3.91074V31.1866C2.93286 31.7266 3.37055 32.1643 3.91049 32.1643H39.0075C39.5474 32.1643 39.9851 31.7266 39.9851 31.1866V30.6978H4.88812Z" fill="#E8E8E8"/>
|
||||
<path d="M34.7058 21.5088H8.30971C7.49984 21.5088 6.84326 20.8522 6.84326 20.0424V16.1319C6.84326 15.322 7.49984 14.6654 8.30971 14.6654H34.7058C35.5156 14.6654 36.1722 15.322 36.1722 16.1319V20.0424C36.1722 20.8522 35.5156 21.5088 34.7058 21.5088Z" fill="#B6C4CF"/>
|
||||
<path d="M34.7058 13.9323H8.30978C7.09683 13.9323 6.11011 14.919 6.11011 16.1319V20.0424C6.11011 21.2554 7.09683 22.2421 8.30978 22.2421H34.7058C35.9188 22.2421 36.9055 21.2554 36.9055 20.0424V16.1319C36.9055 14.919 35.9188 13.9323 34.7058 13.9323ZM20.0414 15.3987H22.9742C23.3792 15.3987 23.7075 15.727 23.7075 16.1319V20.0424C23.7075 20.4474 23.3792 20.7757 22.9742 20.7757H20.0414C19.6364 20.7757 19.3081 20.4474 19.3081 20.0424V16.1319C19.3081 15.727 19.6364 15.3987 20.0414 15.3987ZM17.1085 20.7757H14.1756C13.7706 20.7757 13.4423 20.4474 13.4423 20.0424V16.1319C13.4423 15.727 13.7706 15.3987 14.1756 15.3987H17.1085C17.5134 15.3987 17.8417 15.727 17.8417 16.1319V20.0424C17.8417 20.4474 17.5134 20.7757 17.1085 20.7757ZM25.9071 15.3987H28.84C29.245 15.3987 29.5733 15.727 29.5733 16.1319V20.0424C29.5733 20.4474 29.245 20.7757 28.84 20.7757H25.9071C25.5022 20.7757 25.1739 20.4474 25.1739 20.0424V16.1319C25.1739 15.727 25.5022 15.3987 25.9071 15.3987ZM7.57655 20.0424V16.1319C7.57655 15.727 7.90484 15.3987 8.30978 15.3987H11.2427C11.6476 15.3987 11.9759 15.727 11.9759 16.1319V20.0424C11.9759 20.4474 11.6476 20.7757 11.2427 20.7757H8.30978C7.90484 20.7757 7.57655 20.4474 7.57655 20.0424ZM35.439 20.0424C35.439 20.4474 35.1108 20.7757 34.7058 20.7757H31.7729C31.368 20.7757 31.0397 20.4474 31.0397 20.0424V16.1319C31.0397 15.727 31.368 15.3987 31.7729 15.3987H34.7058C35.1108 15.3987 35.439 15.727 35.439 16.1319V20.0424Z" fill="#9FACBA"/>
|
||||
<path d="M16.6196 12.4656H14.6644C14.2594 12.4656 13.9312 12.1373 13.9312 11.7324C13.9312 11.3274 14.2594 10.9991 14.6644 10.9991H16.6196C17.0246 10.9991 17.3529 11.3274 17.3529 11.7324C17.3529 12.1373 17.0246 12.4656 16.6196 12.4656Z" fill="#E8E8E8"/>
|
||||
<path d="M22.4858 12.4656H20.5306C20.1257 12.4656 19.7974 12.1373 19.7974 11.7324C19.7974 11.3274 20.1257 10.9991 20.5306 10.9991H22.4858C22.8908 10.9991 23.2191 11.3274 23.2191 11.7324C23.2191 12.1373 22.8908 12.4656 22.4858 12.4656Z" fill="#E8E8E8"/>
|
||||
<path d="M28.3516 12.4656H26.3963C25.9914 12.4656 25.6631 12.1373 25.6631 11.7324C25.6631 11.3274 25.9914 10.9991 26.3963 10.9991H28.3516C28.7565 10.9991 29.0848 11.3274 29.0848 11.7324C29.0848 12.1373 28.7565 12.4656 28.3516 12.4656Z" fill="#E8E8E8"/>
|
||||
<path d="M34.2168 12.4656H32.2615C31.8566 12.4656 31.5283 12.1373 31.5283 11.7324C31.5283 11.3274 31.8566 10.9991 32.2615 10.9991H34.2168C34.6217 10.9991 34.95 11.3274 34.95 11.7324C34.95 12.1373 34.6217 12.4656 34.2168 12.4656Z" fill="#E8E8E8"/>
|
||||
<path d="M10.7534 12.4656H8.79816C8.39323 12.4656 8.06494 12.1373 8.06494 11.7324C8.06494 11.3274 8.39323 10.9991 8.79816 10.9991H10.7534C11.1584 10.9991 11.4867 11.3274 11.4867 11.7324C11.4867 12.1373 11.1584 12.4656 10.7534 12.4656Z" fill="#E8E8E8"/>
|
||||
<path d="M22.9748 26.8854C22.9748 26.0755 22.3182 25.4189 21.5083 25.4189C21.3064 25.4189 21.1139 25.4598 20.9388 25.5336C20.4117 25.756 20.1396 26.2775 20.1396 26.8854C20.1396 27.6953 20.6985 28.2541 21.5083 28.2541C22.1157 28.2541 22.6369 27.9825 22.8595 27.4562C22.9337 27.2807 22.9748 27.0879 22.9748 26.8854Z" fill="#DF646E"/>
|
||||
<path d="M17.1088 26.8854C17.1088 26.0755 16.4522 25.4189 15.6424 25.4189C15.4404 25.4189 15.2479 25.4598 15.0728 25.5336C14.5458 25.756 14.2737 26.2775 14.2737 26.8854C14.2737 27.6953 14.8325 28.2541 15.6424 28.2541C16.2498 28.2541 16.7709 27.9825 16.9935 27.4562C17.0678 27.2807 17.1088 27.0879 17.1088 26.8854Z" fill="#DF646E"/>
|
||||
<path d="M11.2428 26.8854C11.2428 26.0755 10.5863 25.4189 9.7764 25.4189C9.57442 25.4189 9.38192 25.4598 9.20683 25.5336C8.67979 25.756 8.40771 26.2775 8.40771 26.8854C8.40771 27.6953 8.96653 28.2541 9.7764 28.2541C10.3838 28.2541 10.905 27.9825 11.1276 27.4562C11.2018 27.2807 11.2428 27.0879 11.2428 26.8854Z" fill="#DF646E"/>
|
||||
<path d="M28.84 26.8854C28.84 26.0755 28.1834 25.4189 27.3736 25.4189C27.1716 25.4189 26.9791 25.4598 26.804 25.5336C26.277 25.756 26.0049 26.2775 26.0049 26.8854C26.0049 27.6953 26.5637 28.2541 27.3736 28.2541C27.981 28.2541 28.5021 27.9825 28.7248 27.4562C28.799 27.2807 28.84 27.0879 28.84 26.8854Z" fill="#DF646E"/>
|
||||
<path d="M34.706 26.8854C34.706 26.0755 34.0494 25.4189 33.2395 25.4189C33.0376 25.4189 32.8451 25.4598 32.67 25.5336C32.1429 25.756 31.8708 26.2775 31.8708 26.8854C31.8708 27.6953 32.4297 28.2541 33.2395 28.2541C33.8469 28.2541 34.3681 27.9825 34.5907 27.4562C34.6649 27.2807 34.706 27.0879 34.706 26.8854Z" fill="#DF646E"/>
|
||||
<path d="M22.2901 27.5693C21.4802 27.5693 20.8236 26.9128 20.8236 26.1029C20.8236 25.9009 20.8645 25.7084 20.9384 25.5333C20.4114 25.7556 20.0415 26.2771 20.0415 26.885C20.0415 27.6949 20.6981 28.3514 21.508 28.3514C22.1158 28.3514 22.6373 27.9815 22.8596 27.4546C22.6845 27.5285 22.492 27.5693 22.2901 27.5693Z" fill="#DC4955"/>
|
||||
<path d="M16.4241 27.5693C15.6142 27.5693 14.9576 26.9128 14.9576 26.1029C14.9576 25.9009 14.9985 25.7084 15.0724 25.5333C14.5455 25.7556 14.1755 26.2771 14.1755 26.885C14.1755 27.6949 14.8321 28.3514 15.642 28.3514C16.2499 28.3514 16.7713 27.9815 16.9937 27.4546C16.8186 27.5285 16.6261 27.5693 16.4241 27.5693Z" fill="#DC4955"/>
|
||||
<path d="M10.5581 27.5693C9.74825 27.5693 9.09168 26.9128 9.09168 26.1029C9.09168 25.9009 9.13254 25.7084 9.20645 25.5333C8.67951 25.7556 8.30957 26.2771 8.30957 26.885C8.30957 27.6949 8.96615 28.3514 9.77602 28.3514C10.3839 28.3514 10.9054 27.9815 11.1277 27.4546C10.9526 27.5285 10.7601 27.5693 10.5581 27.5693Z" fill="#DC4955"/>
|
||||
<path d="M28.156 27.5693C27.3462 27.5693 26.6896 26.9128 26.6896 26.1029C26.6896 25.9009 26.7304 25.7084 26.8044 25.5333C26.2774 25.7556 25.9075 26.2771 25.9075 26.885C25.9075 27.6949 26.564 28.3514 27.3739 28.3514C27.9818 28.3514 28.5033 27.9815 28.7256 27.4546C28.5505 27.5285 28.358 27.5693 28.156 27.5693Z" fill="#DC4955"/>
|
||||
<path d="M34.0213 27.5693C33.2114 27.5693 32.5548 26.9128 32.5548 26.1029C32.5548 25.9009 32.5957 25.7084 32.6696 25.5333C32.1426 25.7556 31.7727 26.2771 31.7727 26.885C31.7727 27.6949 32.4293 28.3514 33.2392 28.3514C33.847 28.3514 34.3685 27.9815 34.5908 27.4546C34.4157 27.5285 34.2232 27.5693 34.0213 27.5693Z" fill="#DC4955"/>
|
||||
<path d="M22.5835 8.0641H18.3797C17.9748 8.0641 17.6465 7.73581 17.6465 7.33088C17.6465 6.92594 17.9748 6.59766 18.3797 6.59766H22.5835C22.9885 6.59766 23.3167 6.92594 23.3167 7.33088C23.3167 7.73581 22.9885 8.0641 22.5835 8.0641Z" fill="#E8E8E8"/>
|
||||
<path d="M15.4461 8.0641H8.3094C7.90446 8.0641 7.57617 7.73581 7.57617 7.33088C7.57617 6.92594 7.90446 6.59766 8.3094 6.59766H15.4461C15.851 6.59766 16.1793 6.92594 16.1793 7.33088C16.1793 7.73581 15.851 8.0641 15.4461 8.0641Z" fill="#E8E8E8"/>
|
||||
<path d="M35.8791 5.86548H33.5328C33.3708 5.86548 33.2395 5.99677 33.2395 6.15877V8.50508C33.2395 8.66708 33.3708 8.79837 33.5328 8.79837H35.8791C36.0411 8.79837 36.1724 8.66708 36.1724 8.50508V6.15877C36.1724 5.99677 36.0411 5.86548 35.8791 5.86548Z" fill="#B6C4CF"/>
|
||||
<path d="M9.77619 19.3075C9.37126 19.3075 9.04297 18.9792 9.04297 18.5743V17.5966C9.04297 17.1917 9.37126 16.8634 9.77619 16.8634C10.1811 16.8634 10.5094 17.1917 10.5094 17.5966V18.5743C10.5094 18.9792 10.1811 19.3075 9.77619 19.3075Z" fill="#9FACBA"/>
|
||||
<path d="M15.6417 19.3075C15.2367 19.3075 14.9084 18.9792 14.9084 18.5743V17.5966C14.9084 17.1917 15.2367 16.8634 15.6417 16.8634C16.0466 16.8634 16.3749 17.1917 16.3749 17.5966V18.5743C16.3749 18.9792 16.0466 19.3075 15.6417 19.3075Z" fill="#9FACBA"/>
|
||||
<path d="M21.5079 19.3075C21.1029 19.3075 20.7747 18.9792 20.7747 18.5743V17.5966C20.7747 17.1917 21.1029 16.8634 21.5079 16.8634C21.9128 16.8634 22.2411 17.1917 22.2411 17.5966V18.5743C22.2411 18.9792 21.9128 19.3075 21.5079 19.3075Z" fill="#9FACBA"/>
|
||||
<path d="M27.3736 19.3075C26.9687 19.3075 26.6404 18.9792 26.6404 18.5743V17.5966C26.6404 17.1917 26.9687 16.8634 27.3736 16.8634C27.7785 16.8634 28.1068 17.1917 28.1068 17.5966V18.5743C28.1068 18.9792 27.7785 19.3075 27.3736 19.3075Z" fill="#9FACBA"/>
|
||||
<path d="M33.2398 19.3075C32.8349 19.3075 32.5066 18.9792 32.5066 18.5743V17.5966C32.5066 17.1917 32.8349 16.8634 33.2398 16.8634C33.6447 16.8634 33.973 17.1917 33.973 17.5966V18.5743C33.973 18.9792 33.6447 19.3075 33.2398 19.3075Z" fill="#9FACBA"/>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
19
assets/icons/presence_sensor.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M29.8828 33.7891H20.1172C17.9599 33.7891 16.2109 32.0401 16.2109 29.8828V20.1172C16.2109 17.9599 17.9599 16.2109 20.1172 16.2109H29.8828C32.0401 16.2109 33.7891 17.9599 33.7891 20.1172V29.8828C33.7891 32.0401 32.0401 33.7891 29.8828 33.7891Z" fill="#7E8596"/>
|
||||
<path d="M25 29.8828V20.1172C25 17.9599 26.7489 16.2109 28.9062 16.2109H20.1172C17.9599 16.2109 16.2109 17.9599 16.2109 20.1172V29.8828C16.2109 32.0401 17.9599 33.7891 20.1172 33.7891H28.9062C26.7489 33.7891 25 32.0401 25 29.8828Z" fill="#636978"/>
|
||||
<path d="M25 21.0938L23.0469 25L25 28.9062H28.9062V21.0938H25Z" fill="#FFF04A"/>
|
||||
<path d="M21.0938 21.0938H25V28.9062H21.0938V21.0938Z" fill="#FFDA45"/>
|
||||
<path d="M35.7065 5.89941C35.5191 5.89941 35.3316 5.82793 35.1886 5.68496C32.4671 2.96357 28.8489 1.46484 25.0002 1.46484C21.1516 1.46484 17.5333 2.96357 14.8117 5.68496C14.5256 5.9709 14.0619 5.971 13.7759 5.68486C13.4899 5.39883 13.4899 4.93506 13.7759 4.64912C16.7742 1.65107 20.7603 0 25.0002 0C29.2401 0 33.2262 1.65107 36.2245 4.64902C36.5105 4.93516 36.5105 5.39883 36.2245 5.68477C36.0814 5.82793 35.8939 5.89941 35.7065 5.89941Z" fill="#87C7FF"/>
|
||||
<path d="M32.138 9.46831C31.9506 9.46831 31.7631 9.39683 31.6201 9.25386C29.8518 7.48569 27.5009 6.51196 25.0004 6.51196C22.4998 6.51196 20.1488 7.48579 18.3806 9.25386C18.0946 9.53989 17.6308 9.53979 17.3449 9.25376C17.0589 8.96772 17.0589 8.50395 17.3449 8.21802C19.3897 6.17329 22.1086 5.04712 25.0005 5.04712C27.8923 5.04712 30.611 6.17319 32.6558 8.21802C32.942 8.50405 32.942 8.96782 32.6559 9.25376C32.5129 9.39683 32.3254 9.46831 32.138 9.46831Z" fill="#87C7FF"/>
|
||||
<path d="M28.5688 13.0374C28.3813 13.0374 28.1938 12.9659 28.0508 12.8229C26.3687 11.1406 23.6313 11.1406 21.9491 12.8229C21.6631 13.1089 21.1993 13.1089 20.9134 12.8229C20.6273 12.5368 20.6273 12.0731 20.9134 11.7871C23.1668 9.53386 26.8333 9.53386 29.0867 11.7871C29.3728 12.0732 29.3728 12.5369 29.0867 12.8229C28.9437 12.9659 28.7562 13.0374 28.5688 13.0374Z" fill="#87C7FF"/>
|
||||
<path d="M25 50C20.7601 50 16.7741 48.349 13.7759 45.351C13.4899 45.0649 13.4899 44.6012 13.7759 44.3153C14.062 44.0291 14.5257 44.0292 14.8117 44.3152C17.5332 47.0364 21.1514 48.5352 25 48.5352C28.8487 48.5352 32.467 47.0365 35.1886 44.3151C35.4747 44.029 35.9384 44.0291 36.2244 44.3152C36.5103 44.6012 36.5104 45.065 36.2243 45.3509C33.2261 48.349 29.24 50 25 50Z" fill="#87C7FF"/>
|
||||
<path d="M23.5511 44.8503C23.5166 44.8503 23.4817 44.8479 23.4466 44.8429C21.1254 44.511 19.0154 43.4526 17.3449 41.7821C17.0589 41.496 17.0589 41.0323 17.3449 40.7463C17.6309 40.4602 18.0947 40.4603 18.3806 40.7462C19.8254 42.1909 21.6488 43.1061 23.6539 43.3928C24.0544 43.4501 24.3325 43.8211 24.2753 44.2215C24.223 44.5866 23.9097 44.8503 23.5511 44.8503Z" fill="#87C7FF"/>
|
||||
<path d="M26.4494 44.8505C26.0908 44.8505 25.7775 44.5871 25.7252 44.2217C25.668 43.8212 25.9462 43.4503 26.3466 43.393C28.3517 43.1063 30.1751 42.1911 31.6198 40.7464C31.9059 40.4605 32.3696 40.4605 32.6556 40.7464C32.9416 41.0326 32.9416 41.4962 32.6556 41.7823C30.9852 43.4526 28.8752 44.5111 26.5539 44.8431C26.5189 44.848 26.4838 44.8505 26.4494 44.8505Z" fill="#87C7FF"/>
|
||||
<path d="M25.0001 39.9032C23.5201 39.9032 22.0401 39.3398 20.9134 38.2132C20.6273 37.9271 20.6273 37.4634 20.9134 37.1773C21.1994 36.8914 21.6632 36.8914 21.9491 37.1773C23.6314 38.8597 26.3687 38.8597 28.0508 37.1773C28.3369 36.8914 28.8006 36.8914 29.0866 37.1773C29.3727 37.4635 29.3727 37.9271 29.0866 38.2132C27.9601 39.3399 26.4801 39.9032 25.0001 39.9032Z" fill="#87C7FF"/>
|
||||
<path d="M44.8326 36.4387C44.6452 36.4387 44.4577 36.3673 44.3147 36.2243C44.0286 35.9382 44.0286 35.4745 44.3146 35.1885C47.036 32.467 48.5347 28.8487 48.5347 25.0001C48.5347 21.1514 47.036 17.5331 44.3146 14.8115C44.0286 14.5255 44.0286 14.0617 44.3147 13.7758C44.6007 13.4898 45.0645 13.4897 45.3505 13.7759C48.3485 16.774 49.9996 20.7601 49.9996 25.0001C49.9996 29.2399 48.3485 33.226 45.3506 36.2243C45.2075 36.3672 45.02 36.4387 44.8326 36.4387Z" fill="#87C7FF"/>
|
||||
<path d="M41.2641 32.87C41.0767 32.87 40.8892 32.7985 40.7462 32.6555C40.4601 32.3695 40.4601 31.9057 40.7461 31.6198C42.5142 29.8515 43.488 27.5006 43.488 25.0001C43.488 22.4996 42.5142 20.1486 40.7461 18.3803C40.4601 18.0943 40.4601 17.6305 40.7462 17.3446C41.0323 17.0586 41.496 17.0587 41.782 17.3447C43.8267 19.3895 44.9529 22.1083 44.9529 25.0002C44.9529 27.8921 43.8268 30.6107 41.782 32.6556C41.639 32.7984 41.4515 32.87 41.2641 32.87Z" fill="#87C7FF"/>
|
||||
<path d="M37.6954 29.3014C37.508 29.3014 37.3205 29.2299 37.1774 29.0869C36.8914 28.8008 36.8914 28.3371 37.1774 28.0511C38.8597 26.3688 38.8597 23.6316 37.1774 21.9495C36.8914 21.6634 36.8914 21.1997 37.1774 20.9137C37.4635 20.6277 37.9272 20.6277 38.2133 20.9137C40.4666 23.1671 40.4666 26.8336 38.2133 29.087C38.0703 29.2299 37.8828 29.3014 37.6954 29.3014Z" fill="#87C7FF"/>
|
||||
<path d="M5.16709 36.4386C4.97959 36.4386 4.79219 36.3671 4.64922 36.224C1.65107 33.2258 0 29.2397 0 24.9997C0 20.7599 1.65107 16.7738 4.64902 13.7756C4.93506 13.4895 5.39883 13.4896 5.68477 13.7755C5.9708 14.0615 5.9708 14.5253 5.68477 14.8113C2.96357 17.5328 1.46484 21.1512 1.46484 24.9997C1.46484 28.8484 2.96357 32.4667 5.68496 35.1883C5.971 35.4743 5.971 35.9381 5.68496 36.224C5.54199 36.367 5.35449 36.4386 5.16709 36.4386Z" fill="#87C7FF"/>
|
||||
<path d="M8.73577 32.8702C8.54836 32.8702 8.36086 32.7987 8.2179 32.6556C6.17307 30.6108 5.047 27.892 5.047 25.0001C5.047 22.1083 6.17307 19.3895 8.2179 17.3446C8.50393 17.0586 8.9677 17.0586 9.25364 17.3446C9.53967 17.6307 9.53967 18.0944 9.25364 18.3804C7.48557 20.1486 6.51184 22.4996 6.51184 25.0001C6.51184 27.5006 7.48557 29.8516 9.25374 31.6199C9.53977 31.9059 9.53977 32.3697 9.25374 32.6556C9.11067 32.7986 8.92317 32.8702 8.73577 32.8702Z" fill="#87C7FF"/>
|
||||
<path d="M12.3041 29.3012C12.1167 29.3012 11.9292 29.2297 11.7863 29.0868C9.53284 26.8333 9.53284 23.1668 11.7863 20.9134C12.0723 20.6275 12.5361 20.6275 12.822 20.9134C13.108 21.1996 13.108 21.6632 12.822 21.9493C11.1398 23.6315 11.1398 26.3687 12.822 28.0508C13.108 28.337 13.108 28.8006 12.822 29.0867C12.679 29.2297 12.4915 29.3012 12.3041 29.3012Z" fill="#87C7FF"/>
|
||||
</svg>
|
After Width: | Height: | Size: 6.1 KiB |
4
assets/icons/rounded_add_icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="15.0001" cy="15" r="13.5" fill="#F4F4F4" stroke="#E5E5E5" stroke-width="3"/>
|
||||
<path d="M19.4508 14.0508H15.9493V10.5492C15.9493 10.025 15.5243 9.59998 15 9.59998C14.4758 9.59998 14.0508 10.025 14.0508 10.5492V14.0508H10.5493C10.025 14.0508 9.60004 14.4757 9.60004 15C9.60004 15.5242 10.025 15.9492 10.5493 15.9492H14.0508V19.4508C14.0508 19.975 14.4758 20.4 15 20.4C15.5243 20.4 15.9493 19.975 15.9493 19.4508V15.9492H19.4508C19.9751 15.9492 20.4 15.5242 20.4 15C20.4 14.4757 19.9751 14.0508 19.4508 14.0508Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 660 B |
6
assets/icons/sauna_icon.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="51" height="50" viewBox="0 0 51 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M48.0089 28.43H46.3171L38.0574 21.3137C37.2144 20.5873 36.1474 20.2536 35.0949 20.331L31.7723 15.2471C31.3675 14.628 30.7453 14.2065 30.0202 14.0603C29.2954 13.9139 28.5584 14.0611 27.9457 14.4746L24.9199 16.5151C24.5888 16.7387 24.1669 16.7909 23.7911 16.6551L21.6285 15.8739C20.7576 15.5595 19.7956 15.7034 19.0551 16.2584C18.7267 16.5044 18.6603 16.9698 18.9063 17.2979C19.1524 17.6264 19.6174 17.6927 19.9459 17.4467C20.285 17.1926 20.7256 17.127 21.1242 17.2708L23.2864 18.0521C24.1062 18.3481 25.0271 18.234 25.7503 17.7465L28.7762 15.706C29.0569 15.5164 29.3946 15.4493 29.7264 15.516C30.0587 15.5832 30.344 15.7762 30.5294 16.06L31.0692 16.8863L28.1509 17.7614C27.758 17.8793 27.5353 18.2932 27.6531 18.6861C27.771 19.079 28.1849 19.3018 28.5774 19.1839L30.6114 18.5739L30.0499 19.5101C29.839 19.8618 29.953 20.3176 30.3047 20.5286C30.4241 20.6007 30.5561 20.6346 30.6858 20.6346C30.9384 20.6346 31.1844 20.5061 31.3237 20.2738L32.2613 18.7105L33.5892 20.7422C33.4729 20.7994 33.3584 20.862 33.2463 20.9311L27.2873 24.6054L25.5794 22.1201C24.5766 20.661 22.6524 20.2066 21.1029 21.063L19.3263 22.045C18.8674 22.2983 18.3173 22.3551 17.8169 22.2002L17.0577 21.9656L18.4619 19.6867C18.6771 19.3376 18.5684 18.8803 18.2193 18.6651C17.8703 18.4496 17.4125 18.5583 17.1977 18.9077L15.5925 21.5128L13.967 21.0104C12.371 20.5172 10.6627 21.2397 9.9055 22.7293L7.0063 28.43H3.55741C2.0277 28.43 0.782959 29.6748 0.782959 31.2045V34.2464C0.782959 35.7764 2.0277 37.0208 3.55741 37.0208H5.42815V49.0044C5.42815 49.4145 5.7608 49.7471 6.17088 49.7471H45.395C45.8051 49.7471 46.1378 49.4145 46.1378 49.0044V37.0208H48.0085C49.5386 37.0208 50.783 35.7764 50.783 34.2464V31.2045C50.7833 29.6748 49.5386 28.43 48.0089 28.43ZM30.6588 24.2712V25.8273C30.6588 26.2373 30.9914 26.57 31.4015 26.57C31.8116 26.57 32.1442 26.2373 32.1442 25.8273V24.0309L35.1891 25.228C35.5706 25.3783 36.0017 25.1902 36.152 24.8087C36.3019 24.4269 36.1142 23.9958 35.7323 23.8459L33.0555 22.7934L34.0256 22.1953C34.9949 21.5979 36.2252 21.6955 37.0877 22.4386L44.0416 28.43H29.916L28.1296 25.8307L30.6588 24.2712ZM11.2292 23.4022C11.658 22.5592 12.625 22.1502 13.5287 22.4295L17.3782 23.6193C18.2624 23.8928 19.2344 23.7925 20.0447 23.345L21.8212 22.3631C22.6986 21.8782 23.7877 22.1357 24.3553 22.9616L28.1139 28.43H24.8588L23.7591 25.799C23.6011 25.4206 23.1659 25.2421 22.7878 25.4C22.4094 25.5583 22.2309 25.9932 22.3888 26.3716L23.249 28.43H16.2967L16.2303 27.1094L18.1693 26.3949C18.5542 26.253 18.7515 25.8261 18.6096 25.4416C18.4676 25.0567 18.0408 24.8595 17.6563 25.0014L15.5212 25.788L12.9783 24.4013C12.6181 24.2049 12.1672 24.3376 11.9708 24.6973C11.7743 25.0574 11.9071 25.5087 12.2672 25.7052L14.7407 27.0541L14.8093 28.43H8.67258L11.2292 23.4022ZM6.91361 48.262V45.5093H38.0414C38.4515 45.5093 38.7841 45.1767 38.7841 44.7666C38.7841 44.3565 38.4515 44.0239 38.0414 44.0239H6.91361V41.259H44.6527V44.0239H41.0119C40.6018 44.0239 40.2692 44.3565 40.2692 44.7666C40.2692 45.1767 40.6018 45.5093 41.0119 45.5093H44.6527V48.262H6.91361ZM44.6527 39.7739H6.91361V37.0208H44.6527V39.7739ZM49.2983 34.2464C49.2983 34.9574 48.7196 35.5357 48.0089 35.5357H3.55741C2.84634 35.5357 2.26803 34.9574 2.26803 34.2464V31.2045C2.26803 30.4934 2.84673 29.9151 3.55741 29.9151H48.0089C48.7196 29.9151 49.2983 30.4938 49.2983 31.2045V34.2464Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M15.8016 10.3106C15.2065 10.8489 14.4661 11.5183 14.4661 12.8348C14.4661 13.2449 14.7983 13.5775 15.2084 13.5775C15.6185 13.5775 15.9511 13.2449 15.9511 12.8348C15.9511 12.2073 16.2414 11.9154 16.7976 11.4123C17.3931 10.874 18.1335 10.2045 18.1335 8.88808C18.1335 7.57162 17.3931 6.90213 16.7976 6.36388C16.2414 5.86071 15.9511 5.56927 15.9511 4.94137C15.9511 4.31384 16.2414 4.02202 16.7976 3.51924C17.3931 2.98098 18.1339 2.31149 18.1339 0.995031C18.1339 0.584948 17.8013 0.252686 17.3912 0.252686C16.9811 0.252686 16.6485 0.584948 16.6485 0.995031C16.6485 1.62294 16.3582 1.91438 15.802 2.41754C15.2069 2.95542 14.4661 3.6249 14.4661 4.94137C14.4661 6.25783 15.2065 6.92731 15.8016 7.46557C16.3582 7.96873 16.6485 8.26056 16.6485 8.88808C16.6485 9.51598 16.3582 9.80743 15.8016 10.3106Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M25.2844 10.3106C24.6893 10.8489 23.9485 11.5183 23.9485 12.8348C23.9485 13.2449 24.2811 13.5775 24.6912 13.5775C25.1013 13.5775 25.4339 13.2449 25.4339 12.8348C25.4339 12.2073 25.7242 11.9154 26.2804 11.4123C26.8755 10.874 27.6163 10.2045 27.6163 8.88808C27.6163 7.57162 26.8759 6.90213 26.2804 6.36388C25.7242 5.86071 25.4339 5.56927 25.4339 4.94137C25.4339 4.31384 25.7242 4.02202 26.2804 3.51924C26.8759 2.98098 27.6163 2.31149 27.6163 0.995031C27.6163 0.584948 27.2841 0.252686 26.874 0.252686C26.4639 0.252686 26.1313 0.584948 26.1313 0.995031C26.1313 1.62255 25.841 1.91438 25.2844 2.41754C24.6893 2.95542 23.9485 3.6249 23.9485 4.94137C23.9485 6.25783 24.6893 6.92731 25.2844 7.46557C25.841 7.96873 26.1313 8.26056 26.1313 8.88808C26.1313 9.51598 25.841 9.80743 25.2844 10.3106Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M34.769 10.3106C34.1739 10.8489 33.4331 11.5183 33.4331 12.8348C33.4331 13.2449 33.7654 13.5775 34.1755 13.5775C34.5855 13.5775 34.9182 13.2449 34.9182 12.8348C34.9182 12.2073 35.2085 11.9154 35.765 11.4123C36.3601 10.874 37.101 10.2045 37.101 8.88808C37.101 7.57162 36.3601 6.90213 35.765 6.36388C35.2085 5.86071 34.9182 5.56927 34.9182 4.94137C34.9182 4.31384 35.2085 4.02202 35.765 3.51924C36.3601 2.98098 37.101 2.31149 37.101 0.995031C37.101 0.584948 36.7683 0.252686 36.3582 0.252686C35.9482 0.252686 35.6155 0.584948 35.6155 0.995031C35.6155 1.62255 35.3252 1.91438 34.769 2.41754C34.1735 2.95542 33.4331 3.6249 33.4331 4.94137C33.4331 6.25783 34.1735 6.92731 34.769 7.46557C35.3252 7.96873 35.6155 8.26056 35.6155 8.88808C35.6155 9.51598 35.3252 9.80743 34.769 10.3106Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
19
assets/icons/smart_gateway_icon.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<svg width="50" height="47" viewBox="0 0 50 47" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.42188 46.875C6.61221 46.875 5.95703 46.2198 5.95703 45.4102V42.4805C5.95703 41.6708 6.61221 41.0156 7.42188 41.0156C8.23154 41.0156 8.88672 41.6708 8.88672 42.4805V45.4102C8.88672 46.2198 8.23154 46.875 7.42188 46.875Z" fill="#5C6699"/>
|
||||
<path d="M42.5781 46.875C41.7685 46.875 41.1133 46.2198 41.1133 45.4102V42.4805C41.1133 41.6708 41.7685 41.0156 42.5781 41.0156C43.3878 41.0156 44.043 41.6708 44.043 42.4805V45.4102C44.043 46.2198 43.3878 46.875 42.5781 46.875Z" fill="#404A80"/>
|
||||
<path d="M9.0036 28.4083L0.214533 7.9005C-0.103045 7.15802 0.240314 6.29689 0.984162 5.97785C1.71942 5.66027 2.58631 5.99933 2.90965 6.74748L11.6987 27.2553C12.0163 27.9978 11.6729 28.8589 10.9291 29.1779C10.2014 29.4922 9.33045 29.1652 9.0036 28.4083Z" fill="#5C6699"/>
|
||||
<path d="M39.0701 29.1782C38.3263 28.8591 37.9829 27.998 38.3005 27.2555L47.0895 6.7477C47.4129 5.99956 48.274 5.65766 49.015 5.97807C49.7589 6.29711 50.1022 7.15825 49.7847 7.90073L40.9956 28.4085C40.6686 29.1657 39.7975 29.4923 39.0701 29.1782Z" fill="#404A80"/>
|
||||
<path d="M45.6055 43.9453H4.39453C1.97129 43.9453 0 41.974 0 39.5508V30.7617C0 28.3385 1.97129 26.3672 4.39453 26.3672H45.6055C48.0287 26.3672 50 28.3385 50 30.7617V39.5508C50 41.974 48.0287 43.9453 45.6055 43.9453Z" fill="#C1DCFF"/>
|
||||
<path d="M45.6055 26.3672H25V43.9453H45.6055C48.0287 43.9453 50 41.974 50 39.5508V30.7617C50 28.3385 48.0287 26.3672 45.6055 26.3672Z" fill="#D5E8FE"/>
|
||||
<path d="M26.0295 20.9384C25.8692 20.7782 25.5202 20.5078 24.9995 20.5078C24.4788 20.5078 24.1298 20.7782 23.9695 20.9384C23.3973 21.5105 22.4703 21.5105 21.8981 20.9384C21.326 20.3662 21.326 19.4392 21.8981 18.867C22.3788 18.385 23.423 17.5781 24.9995 17.5781C26.576 17.5781 27.6202 18.385 28.1009 18.867C28.673 19.4392 28.673 20.3662 28.1009 20.9384C27.5287 21.5105 26.6016 21.5106 26.0295 20.9384Z" fill="#80BFFF"/>
|
||||
<path d="M38.4667 8.51445C34.8676 4.9124 30.084 2.92969 24.9999 2.92969C19.9158 2.92969 15.1322 4.9124 11.5331 8.51445C10.9609 9.08662 10.0339 9.08662 9.46172 8.51445C8.88955 7.94229 8.88955 7.01523 9.46172 6.44307C13.6159 2.28887 19.1319 0 24.9999 0C30.8679 0 36.3839 2.28887 40.5381 6.44307C41.1103 7.01523 41.1103 7.94229 40.5381 8.51445C39.9659 9.08662 39.039 9.08662 38.4667 8.51445Z" fill="#80BFFF"/>
|
||||
<path d="M34.3209 12.6558C31.829 10.1624 28.5187 8.78906 24.9997 8.78906C21.4806 8.78906 18.1704 10.1624 15.6785 12.6558C15.1063 13.2279 14.1793 13.2279 13.6071 12.6558C13.0349 12.0836 13.0349 11.1565 13.6071 10.5844C16.6512 7.5374 20.6996 5.85938 24.9997 5.85938C29.2998 5.85938 33.3481 7.5374 36.3923 10.5844C36.9644 11.1565 36.9644 12.0836 36.3923 12.6558C35.8201 13.2279 34.8931 13.2279 34.3209 12.6558Z" fill="#80BFFF"/>
|
||||
<path d="M30.1752 16.7972C27.4057 14.0249 22.5934 14.0249 19.824 16.7972C19.2518 17.3694 18.3248 17.3694 17.7526 16.7972C17.1804 16.2264 17.1804 15.298 17.7526 14.7259C21.6264 10.8492 28.3727 10.8492 32.2466 14.7259C32.8187 15.298 32.8187 16.2264 32.2466 16.7972C31.6744 17.3694 30.7474 17.3694 30.1752 16.7972Z" fill="#80BFFF"/>
|
||||
<path d="M30.8594 38.0859C30.0497 38.0859 29.3945 37.4308 29.3945 36.6211V33.6914C29.3945 32.8817 30.0497 32.2266 30.8594 32.2266C31.669 32.2266 32.3242 32.8817 32.3242 33.6914V36.6211C32.3242 37.4308 31.669 38.0859 30.8594 38.0859Z" fill="#6699FF"/>
|
||||
<path d="M36.7188 38.0859C35.9091 38.0859 35.2539 37.4308 35.2539 36.6211V33.6914C35.2539 32.8817 35.9091 32.2266 36.7188 32.2266C37.5284 32.2266 38.1836 32.8817 38.1836 33.6914V36.6211C38.1836 37.4308 37.5284 38.0859 36.7188 38.0859Z" fill="#6699FF"/>
|
||||
<path d="M42.5781 38.0859C41.7685 38.0859 41.1133 37.4308 41.1133 36.6211V33.6914C41.1133 32.8817 41.7685 32.2266 42.5781 32.2266C43.3878 32.2266 44.043 32.8817 44.043 33.6914V36.6211C44.043 37.4308 43.3878 38.0859 42.5781 38.0859Z" fill="#6699FF"/>
|
||||
<path d="M26.03 20.9384C26.6021 21.5105 27.5291 21.5106 28.1014 20.9384C28.6735 20.3662 28.6735 19.4392 28.1014 18.867C27.6207 18.385 26.5765 17.5781 25 17.5781V20.5078C25.5207 20.5078 25.8697 20.7782 26.03 20.9384Z" fill="#6699FF"/>
|
||||
<path d="M30.1756 16.7973C30.7478 17.3694 31.6747 17.3695 32.247 16.7973C32.8191 16.2265 32.8191 15.298 32.247 14.7259C30.31 12.7875 27.6551 11.8184 25 11.8184V14.718C26.8954 14.718 28.7908 15.4111 30.1756 16.7973Z" fill="#6699FF"/>
|
||||
<path d="M34.3212 12.6558C34.8934 13.2279 35.8203 13.228 36.3926 12.6558C36.9647 12.0836 36.9647 11.1565 36.3926 10.5844C33.3484 7.5374 29.3001 5.85938 25 5.85938V8.78906C28.519 8.78906 31.8293 10.1624 34.3212 12.6558Z" fill="#6699FF"/>
|
||||
<path d="M38.4668 8.51445C39.039 9.08662 39.9659 9.08672 40.5382 8.51445C41.1104 7.94229 41.1104 7.01523 40.5382 6.44307C36.384 2.28887 30.868 0 25 0V2.92969C30.0841 2.92969 34.8677 4.9124 38.4668 8.51445Z" fill="#6699FF"/>
|
||||
</svg>
|
After Width: | Height: | Size: 4.7 KiB |
23
assets/icons/smart_light_icon.svg
Normal file
@ -0,0 +1,23 @@
|
||||
<svg width="44" height="50" viewBox="0 0 44 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Light">
|
||||
<path id="Vector" d="M27.5001 38.2292C28.1251 36.1459 29.3751 34.2709 31.0418 32.8125C34.1668 30.2083 36.146 26.25 36.146 21.875C36.146 13.75 29.3752 7.08328 21.0418 7.49998C13.6459 7.81248 7.60419 14.0625 7.39589 21.4583C7.29169 26.0417 9.27089 30.1042 12.5001 32.8125C14.2709 34.2708 15.5209 36.1458 16.1459 38.2292H27.5001Z" fill="#FFD15C"/>
|
||||
<path id="Vector_2" d="M20.4166 38.4376H21.3541L17.1874 22.9168C17.2916 22.9168 17.3957 22.9168 17.4999 22.9168C18.0207 22.9168 18.5416 22.7085 18.9582 22.2918C19.1665 22.0835 19.3749 21.9793 19.6874 21.9793C19.9999 21.9793 20.2082 22.0835 20.4166 22.2918C21.1458 23.1251 22.3958 23.1251 23.1249 22.2918C23.3332 22.0835 23.5416 21.9793 23.8541 21.9793C24.0624 21.9793 24.3749 22.0835 24.5833 22.2918C25 22.7085 25.4166 22.9168 26.0416 22.9168C26.1458 22.9168 26.2499 22.9168 26.3541 22.9168L22.2916 38.4376H23.2291L27.4999 22.1876C27.4999 21.9793 27.4999 21.7709 27.2916 21.6668C27.0833 21.5626 26.8749 21.6668 26.7708 21.771C26.5625 21.9793 26.3541 22.0835 26.1458 22.0835C25.8333 22.0835 25.625 21.9793 25.3125 21.771C24.8958 21.3543 24.4792 21.146 23.9583 21.146C23.4374 21.146 23.0208 21.3543 22.6041 21.771C22.1874 22.1877 21.5624 22.1877 21.1458 21.771C20.8333 21.3543 20.3125 21.146 19.7916 21.146C19.2708 21.146 18.7499 21.3543 18.4374 21.771C18.2291 21.9793 17.9166 22.0835 17.6041 22.0835C17.3958 22.0835 17.0833 21.9793 16.9791 21.771C16.8749 21.6668 16.6666 21.5627 16.4583 21.6668C16.25 21.771 16.1458 21.9793 16.25 22.1876L20.4166 38.4376Z" fill="white"/>
|
||||
<g id="Group">
|
||||
<path id="Vector_3" d="M18.5416 47.8125C19.0625 49.0625 20.3125 50 21.7708 50C23.2291 50 24.4791 49.0625 25 47.8125H18.5416Z" fill="#344A5E"/>
|
||||
<path id="Vector_4" d="M25.6252 47.9167H18.021C16.9793 47.9167 16.146 47.0834 16.146 46.0417V38.125H27.5002V46.0417C27.5002 47.0833 26.6668 47.9167 25.6252 47.9167Z" fill="#344A5E"/>
|
||||
</g>
|
||||
<g id="Group_2">
|
||||
<path id="Vector_5" d="M27.3958 42.0831H16.1458C15.5208 42.0831 15 41.5623 15 40.9373C15 40.3123 15.5208 39.7915 16.1458 39.7915H27.3958C28.0208 39.7915 28.5416 40.3123 28.5416 40.9373C28.5416 41.5623 28.0208 42.0831 27.3958 42.0831Z" fill="#415A6B"/>
|
||||
<path id="Vector_6" d="M27.3958 45.7291H16.1458C15.5208 45.7291 15 45.2083 15 44.5833C15 43.9583 15.5208 43.4375 16.1458 43.4375H27.3958C28.0208 43.4375 28.5416 43.9583 28.5416 44.5833C28.5416 45.2082 28.0208 45.7291 27.3958 45.7291Z" fill="#415A6B"/>
|
||||
</g>
|
||||
<g id="Group_3">
|
||||
<path id="Vector_7" d="M21.7711 0C21.2503 0 20.7294 0.416699 20.7294 1.0417V4.5834C20.7294 5.1042 21.1461 5.6251 21.7711 5.6251C22.3961 5.6251 22.8128 5.2084 22.8128 4.5834V1.0417C22.8128 0.416699 22.2919 0 21.7711 0Z" fill="#FFD15C"/>
|
||||
<path id="Vector_8" d="M7.81266 6.35403C7.39596 5.93733 6.77096 5.93733 6.35436 6.35403C5.93776 6.77073 5.93766 7.39573 6.35436 7.81233L8.85436 10.3123C9.27106 10.729 9.89606 10.729 10.3127 10.3123C10.7293 9.89563 10.7294 9.27063 10.3127 8.85403L7.81266 6.35403Z" fill="#FFD15C"/>
|
||||
<path id="Vector_9" d="M4.5834 20.729H1.0417C0.520898 20.729 0 21.1457 0 21.7707C0 22.2915 0.416699 22.8124 1.0417 22.8124H4.5834C5.1042 22.8124 5.6251 22.3957 5.6251 21.7707C5.6251 21.2498 5.1042 20.729 4.5834 20.729Z" fill="#FFD15C"/>
|
||||
<path id="Vector_10" d="M8.85439 33.229L6.35439 35.729C5.9377 36.1457 5.9377 36.7707 6.35439 37.1873C6.77109 37.6039 7.39609 37.604 7.8127 37.1873L10.3127 34.6873C10.7294 34.2706 10.7294 33.6456 10.3127 33.229C9.896 32.8124 9.27109 32.8123 8.85439 33.229Z" fill="#FFD15C"/>
|
||||
<path id="Vector_11" d="M34.6878 33.229C34.2711 32.8123 33.6461 32.8123 33.2294 33.229C32.8127 33.6457 32.8127 34.2707 33.2294 34.6873L35.7294 37.1873C36.1461 37.604 36.7711 37.604 37.1877 37.1873C37.6043 36.7706 37.6044 36.1456 37.1877 35.729L34.6878 33.229Z" fill="#FFD15C"/>
|
||||
<path id="Vector_12" d="M42.5003 20.729H38.9586C38.4378 20.729 37.9169 21.1457 37.9169 21.7707C37.9169 22.2915 38.3336 22.8124 38.9586 22.8124H42.5003C43.0211 22.8124 43.542 22.3957 43.542 21.7707C43.5419 21.2498 43.1253 20.729 42.5003 20.729Z" fill="#FFD15C"/>
|
||||
<path id="Vector_13" d="M35.7294 6.35399L33.2294 8.85399C32.8127 9.27069 32.8127 9.89569 33.2294 10.3123C33.6461 10.729 34.2711 10.729 34.6877 10.3123L37.1877 7.81229C37.6044 7.39559 37.6044 6.77059 37.1877 6.35399C36.771 5.93739 36.1461 5.93729 35.7294 6.35399Z" fill="#FFD15C"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
21
assets/icons/smart_thermostat_icon.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Group 299">
|
||||
<circle id="Ellipse 17" cx="40" cy="40" r="38.5" fill="#F4F4F4" stroke="#E5E5E5" stroke-width="3"/>
|
||||
<g id="AC">
|
||||
<path id="Vector" d="M61.4857 25H18.5143C16.5765 25 15 26.5765 15 28.5143V44.1424C15 46.0802 16.5765 47.6567 18.5143 47.6567H61.4857C63.4235 47.6567 65 46.0802 65 44.1424V28.5143C64.9999 26.5766 63.4234 25 61.4857 25Z" fill="#E0E0E0"/>
|
||||
<path id="Vector_2" d="M61.4857 44.4872H18.5143C16.5765 44.4872 15 42.9107 15 40.9729V44.1424C15 46.0803 16.5765 47.6568 18.5143 47.6568H61.4857C63.4235 47.6568 65 46.0803 65 44.1424V40.9729C64.9999 42.9107 63.4234 44.4872 61.4857 44.4872Z" fill="#C4C4C4"/>
|
||||
<path id="Vector_3" d="M58.9941 40.6726H21.0057C20.6004 40.6726 20.2717 41.0011 20.2717 41.4066V46.9229C20.2717 47.3284 20.6004 47.6569 21.0057 47.6569H58.9941C59.3995 47.6569 59.7281 47.3284 59.7281 46.9229V41.4066C59.7281 41.0011 59.3995 40.6726 58.9941 40.6726Z" fill="#66BAEA"/>
|
||||
<path id="Vector_4" d="M20.2717 44.2803V46.9226C20.2717 47.3281 20.6004 47.6566 21.0057 47.6566H58.9941C59.3995 47.6566 59.7281 47.3281 59.7281 46.9226V44.2803H20.2717Z" fill="#3AAAE4"/>
|
||||
<path id="Vector_5" d="M59.7281 43.4307H20.2717V44.8986H59.7281V43.4307Z" fill="#67676B"/>
|
||||
<path id="Vector_6" d="M58.9943 30.968H56.8236C56.4182 30.968 56.0896 30.6394 56.0896 30.234C56.0896 29.8285 56.4182 29.5 56.8236 29.5H58.9943C59.3997 29.5 59.7283 29.8285 59.7283 30.234C59.7283 30.6393 59.3997 30.968 58.9943 30.968Z" fill="#AAAAAA"/>
|
||||
<path id="Vector_7" d="M53.4741 30.968H39.5816C39.1763 30.968 38.8477 30.6394 38.8477 30.234C38.8477 29.8285 39.1763 29.5 39.5816 29.5H53.4741C53.8795 29.5 54.2081 29.8285 54.2081 30.234C54.2081 30.6393 53.8795 30.968 53.4741 30.968Z" fill="#AAAAAA"/>
|
||||
<g id="Group">
|
||||
<path id="Vector_8" d="M26.4393 55.3316C26.2097 55.3316 25.9835 55.2242 25.8403 55.0228C25.6056 54.6924 25.683 54.2341 26.0134 53.9993C28.0496 52.5521 28.0731 50.3762 28.0731 50.3543C28.0731 49.9489 28.4017 49.6204 28.8071 49.6204C29.2125 49.6204 29.5411 49.9489 29.5411 50.3543C29.5411 50.4743 29.5107 53.3146 26.8638 55.1959C26.7348 55.2875 26.5864 55.3316 26.4393 55.3316Z" fill="#66BAEA"/>
|
||||
<path id="Vector_9" d="M34.0626 55.3315C33.6572 55.3315 33.3286 55.003 33.3286 54.5976V50.3543C33.3286 49.9489 33.6572 49.6204 34.0626 49.6204C34.468 49.6204 34.7966 49.9489 34.7966 50.3543V54.5976C34.7966 55.0029 34.468 55.3315 34.0626 55.3315Z" fill="#66BAEA"/>
|
||||
<path id="Vector_10" d="M40.2069 55.3315C39.8015 55.3315 39.4729 55.003 39.4729 54.5976V50.3543C39.4729 49.9489 39.8015 49.6204 40.2069 49.6204C40.6122 49.6204 40.9409 49.9489 40.9409 50.3543V54.5976C40.9409 55.0029 40.6122 55.3315 40.2069 55.3315Z" fill="#66BAEA"/>
|
||||
<path id="Vector_11" d="M53.5611 55.3317C53.4141 55.3317 53.2655 55.2876 53.1365 55.1959C50.4897 53.3146 50.4592 50.4743 50.4592 50.3543C50.4592 49.9489 50.7879 49.6204 51.1932 49.6204C51.5975 49.6204 51.9254 49.9471 51.9272 50.351C51.9284 50.4487 51.9782 52.5716 53.987 53.9993C54.3173 54.2341 54.3949 54.6924 54.16 55.0228C54.0169 55.2242 53.7907 55.3316 53.5611 55.3317Z" fill="#66BAEA"/>
|
||||
<path id="Vector_12" d="M45.9381 55.3315C45.5327 55.3315 45.2041 55.003 45.2041 54.5976V50.3543C45.2041 49.9489 45.5327 49.6204 45.9381 49.6204C46.3434 49.6204 46.6721 49.9489 46.6721 50.3543V54.5976C46.6721 55.0029 46.3434 55.3315 45.9381 55.3315Z" fill="#66BAEA"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
4
assets/icons/stair_icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="51" height="40" viewBox="0 0 51 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M44.258 22.6289H36.8377C35.759 22.6289 34.8846 23.5033 34.8846 24.582C34.8846 25.6607 35.759 26.5352 36.8377 26.5352H39.5443L30.1751 35.9041C29.4123 36.6669 29.4123 37.9035 30.1751 38.6662C30.9378 39.4289 32.1744 39.4291 32.9372 38.6663L42.3065 29.2973V32.0038C42.3065 33.0825 43.1809 33.9569 44.2596 33.9569C45.3383 33.9569 46.2127 33.0825 46.2127 32.0038V24.582C46.2127 24.5817 46.2127 24.5814 46.2127 24.5812C46.2121 23.5198 45.3496 22.6281 44.258 22.6289Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M48.2589 0.761475H36.7355C35.6567 0.761475 34.7823 1.63589 34.7823 2.7146V12.2849H25.212C24.1334 12.2849 23.2589 13.1593 23.2589 14.238V23.8083H13.6886C12.6099 23.8083 11.7354 24.6828 11.7354 25.7615V35.3318H2.16504C1.08633 35.3318 0.211914 36.2062 0.211914 37.2849C0.211914 38.3636 1.08633 39.238 2.16504 39.238H13.6886C14.2065 39.238 14.7034 39.0323 15.0696 38.666C15.4359 38.2998 15.6417 37.8029 15.6417 37.2849L15.6416 27.7146H25.212C25.73 27.7146 26.2269 27.5088 26.5931 27.1425C26.9594 26.7763 27.1651 26.2794 27.1651 25.7615L27.165 16.1912H36.7354C37.2534 16.1912 37.7502 15.9854 38.1164 15.6191C38.4827 15.2529 38.6885 14.756 38.6885 14.238L38.6884 4.66772H48.2588C49.3375 4.66772 50.2119 3.79331 50.2119 2.7146C50.2119 1.63589 49.3375 0.761475 48.2589 0.761475Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
7
assets/icons/steam_room_icon.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="51" height="50" viewBox="0 0 51 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.5871 6.36865C9.39308 6.36865 6.79468 8.96715 6.79468 12.1611C6.79468 15.355 9.39318 17.9535 12.5871 17.9535C15.781 17.9535 18.3795 15.3551 18.3795 12.1611C18.3795 8.96705 15.7811 6.36865 12.5871 6.36865ZM12.5871 15.0237C11.0085 15.0237 9.72443 13.7396 9.72443 12.1611C9.72443 10.5825 11.0086 9.29841 12.5871 9.29841C14.1656 9.29841 15.4498 10.5826 15.4498 12.1611C15.4498 13.7395 14.1657 15.0237 12.5871 15.0237Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M36.9267 45.2119L31.7407 30.5859H21.6915L17.0898 19.6638H9.58004L3.85354 35.2389C3.62209 35.8685 3.57394 36.5404 3.69865 37.1811H0.782959V40.1109H25.5811L30.465 48.2571C31.1311 49.368 32.32 50.0002 33.5488 50.0002C34.0346 50.0002 34.5269 49.9014 34.9953 49.6942C36.702 48.9395 37.5502 46.9707 36.9267 45.2119ZM11.0903 37.1811L12.8348 34.3844L14.3149 37.1811H11.0903ZM33.8103 47.0148C33.5065 47.1491 33.1484 47.0355 32.9778 46.7506L27.2405 37.1811H17.6295L13.043 28.5147L7.84064 36.8552C7.7133 37.0593 7.49376 37.1811 7.25323 37.1811C6.93906 37.1811 6.76269 36.9956 6.68554 36.885C6.60839 36.7744 6.49511 36.5448 6.60341 36.25L11.6244 22.5937H15.145L19.7467 33.5157H29.671L34.1654 46.191C34.2799 46.5142 34.124 46.8761 33.8103 47.0148Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M35.9113 11.0019C35.9113 9.14519 35.1604 8.12632 34.6121 7.38235C34.1583 6.76652 33.8842 6.39473 33.8842 5.50096C33.8842 4.60709 34.1583 4.2354 34.6122 3.61937C35.1603 2.87541 35.9113 1.85654 35.9113 -0.000244141H32.9816C32.9816 0.893527 32.7075 1.26531 32.2537 1.88125C31.7055 2.62521 30.9545 3.64408 30.9545 5.50086C30.9545 7.35755 31.7054 8.37642 32.2537 9.12038C32.7075 9.73622 32.9816 10.108 32.9816 11.0018C32.9816 11.8958 32.7075 12.2676 32.2536 12.8837C31.7054 13.6279 30.9545 14.6469 30.9545 16.5038C30.9545 18.3606 31.7053 19.3796 32.2536 20.1236C32.7075 20.7396 32.9816 21.1115 32.9816 22.0055H35.9113C35.9113 20.1486 35.1605 19.1296 34.6122 18.3855C34.1583 17.7695 33.8842 17.3977 33.8842 16.5037C33.8842 15.6096 34.1583 15.2379 34.6122 14.6218C35.1604 13.8777 35.9113 12.8588 35.9113 11.0019Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M43.3477 11.0016C43.3477 9.14489 42.5968 8.12602 42.0485 7.38206C41.5947 6.76622 41.3206 6.39444 41.3206 5.50067C41.3206 4.6068 41.5947 4.23511 42.0486 3.61908C42.5967 2.87541 43.3477 1.85654 43.3477 -0.000244141H40.418C40.418 0.893527 40.1439 1.26531 39.6901 1.88125C39.1419 2.62521 38.3909 3.64408 38.3909 5.50086C38.3909 7.35755 39.1418 8.37642 39.6901 9.12038C40.1439 9.73622 40.418 10.108 40.418 11.0018C40.418 11.8958 40.1439 12.2676 39.69 12.8837C39.1418 13.6277 38.3909 14.6467 38.3909 16.5035C38.3909 18.3602 39.1417 19.3793 39.69 20.1233C40.1439 20.7393 40.418 21.1112 40.418 22.0052H43.3477C43.3477 20.1483 42.5969 19.1293 42.0486 18.3852C41.5947 17.7692 41.3206 17.3974 41.3206 16.5034C41.3206 15.6093 41.5947 15.2376 42.0486 14.6215C42.5968 13.8774 43.3477 12.8585 43.3477 11.0016Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M50.7829 11.0021C50.7829 9.14543 50.032 8.12656 49.4837 7.3826C49.0298 6.76676 48.7558 6.39498 48.7558 5.5012C48.7558 4.60734 49.0298 4.23565 49.4837 3.61962C50.032 2.87565 50.7829 1.85678 50.7829 0H47.8531C47.8531 0.893771 47.5791 1.26556 47.1253 1.88149C46.577 2.62545 45.826 3.64432 45.826 5.50111C45.826 7.35779 46.5769 8.37666 47.1253 9.12063C47.5791 9.73646 47.8531 10.1082 47.8531 11.002C47.8531 11.8961 47.5791 12.2679 47.1252 12.8839C46.5769 13.628 45.826 14.6469 45.826 16.5037C45.826 18.3605 46.5768 19.3796 47.1252 20.1235C47.5791 20.7396 47.8531 21.1114 47.8531 22.0054H50.7829C50.7829 20.1485 50.0321 19.1296 49.4838 18.3855C49.0298 17.7695 48.7558 17.3977 48.7558 16.5036C48.7558 15.6095 49.0298 15.2379 49.4838 14.6217C50.0321 13.878 50.7829 12.859 50.7829 11.0021Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
4
assets/icons/street_icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="41" height="50" viewBox="0 0 41 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.32348 18.431H8.4427C8.84797 18.431 9.17659 18.1025 9.17659 17.6972C9.17659 17.2918 8.84797 16.9633 8.4427 16.9633H5.32348C4.65141 16.9633 4.10473 16.4165 4.10473 15.7445V7.86633C4.10473 7.19426 4.65151 6.64758 5.32348 6.64758H26.4823C26.8876 6.64758 27.2162 6.31907 27.2162 5.9137C27.2162 5.50833 26.8876 5.17981 26.4823 5.17981H23.5197V1.71C23.5197 0.766941 22.7525 -0.000244141 21.8095 -0.000244141H19.2773C18.3343 -0.000244141 17.5671 0.766941 17.5671 1.71V5.17981H5.32348C3.84213 5.17981 2.63696 6.38489 2.63696 7.86633V15.7445C2.63696 17.2259 3.84213 18.431 5.32348 18.431ZM19.0349 1.71C19.0349 1.57631 19.1436 1.46752 19.2773 1.46752H21.8095C21.9432 1.46752 22.052 1.57631 22.052 1.71V5.17981H19.0349V1.71Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M39.1356 9.65516L33.8736 5.71601C33.412 5.37051 32.8403 5.18018 32.2636 5.18018H29.4186C29.0134 5.18018 28.6848 5.50869 28.6848 5.91406C28.6848 6.31943 29.0134 6.64794 29.4186 6.64794H32.2636C32.5253 6.64794 32.7846 6.73417 32.994 6.89101L38.2561 10.8302C38.5665 11.0626 38.7445 11.4181 38.7445 11.8058C38.7445 12.1936 38.5665 12.5492 38.2561 12.7815L32.994 16.7207C32.7846 16.8775 32.5253 16.9637 32.2636 16.9637H11.3792C10.9739 16.9637 10.6453 17.2922 10.6453 17.6976C10.6453 18.103 10.9739 18.4315 11.3792 18.4315H17.5682V21.6698H7.94851C7.37195 21.6698 6.80017 21.86 6.33855 22.2056L1.07656 26.1446C0.392382 26.6567 0 27.4405 0 28.2951C0 29.1497 0.392382 29.9337 1.07656 30.4457L6.33865 34.3849C6.80027 34.7305 7.37204 34.9207 7.9486 34.9207H17.5683V48.2896C17.5683 49.2326 18.3355 49.9998 19.2785 49.9998H21.8108C22.7537 49.9998 23.5209 49.2327 23.5209 48.2896V34.9208H27.9512C28.3564 34.9208 28.6851 34.5923 28.6851 34.1869C28.6851 33.7815 28.3564 33.453 27.9512 33.453H7.94851C7.68689 33.453 7.42751 33.3666 7.21814 33.21L1.95615 29.2708C1.64579 29.0384 1.46777 28.6828 1.46777 28.2951C1.46777 27.9073 1.64579 27.5518 1.95615 27.3195L7.21814 23.3803C7.42761 23.2236 7.68698 23.1372 7.9486 23.1372H34.8878C35.5598 23.1372 36.1065 23.684 36.1065 24.356V32.2342C36.1065 32.9062 35.5597 33.4529 34.8878 33.4529H30.8865C30.4812 33.4529 30.1526 33.7814 30.1526 34.1868C30.1526 34.5922 30.4812 34.9207 30.8865 34.9207H34.8878C36.3691 34.9207 37.5743 33.7156 37.5743 32.2342V24.356C37.5743 22.8746 36.3691 21.6695 34.8878 21.6695H23.5207V18.4312H32.2636C32.8403 18.4312 33.412 18.2409 33.8736 17.8954L39.1357 13.9562C39.8199 13.4441 40.2123 12.6602 40.2123 11.8056C40.2123 10.9511 39.8198 10.1673 39.1356 9.65516ZM22.053 48.2897C22.053 48.4234 21.9443 48.5322 21.8106 48.5322H19.2783C19.1447 48.5322 19.0359 48.4234 19.0359 48.2897V34.9208H22.053V48.2897ZM22.053 21.6696H19.0359V18.4313H22.053V21.6696Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
4
assets/icons/textfield_search_icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.89883 11.08C-0.632454 8.54864 -0.632402 4.42983 1.89883 1.8985C4.43016 -0.632833 8.54891 -0.632833 11.0802 1.8985C13.2277 4.04599 13.5529 7.23986 12.0568 9.73392C12.0568 9.73392 11.9493 9.91422 12.0945 10.0593C12.9225 10.8872 15.4068 13.3716 15.4068 13.3716C16.0661 14.0308 16.223 14.9527 15.6384 15.5374L15.5377 15.638C14.953 16.2227 14.0311 16.0658 13.3719 15.4065C13.3719 15.4065 10.8929 12.9275 10.0665 12.1012C9.91444 11.9491 9.7342 12.0566 9.7342 12.0566C7.24018 13.5526 4.04632 13.2275 1.89883 11.08ZM9.88161 9.88133C11.752 8.01094 11.752 4.96763 9.88156 3.09724C8.01117 1.22689 4.96786 1.22684 3.09751 3.09724C1.22712 4.96758 1.22712 8.01094 3.09751 9.88133C4.96791 11.7516 8.01117 11.7516 9.88161 9.88133Z" fill="#999999" fill-opacity="0.7"/>
|
||||
<path d="M9.46725 6.10398C9.55431 6.10398 9.6428 6.08687 9.72811 6.05084C10.0689 5.90662 10.2283 5.51345 10.0841 5.17265C9.17763 3.03057 6.69753 2.02532 4.5555 2.93176C4.21475 3.07598 4.05533 3.46915 4.19955 3.80995C4.34382 4.15075 4.73688 4.31007 5.07779 4.16591C6.53924 3.54749 8.2315 4.23338 8.84987 5.69483C8.95806 5.95043 9.20618 6.10398 9.46725 6.10398Z" fill="#999999" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
21
assets/icons/unit_icon.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<svg width="51" height="50" viewBox="0 0 51 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.6549 32.9258C12.1028 33.0644 11.5681 33.2701 11.0654 33.5373L11.8273 34.9767C12.2141 34.7713 12.6254 34.6131 13.0502 34.5063L12.6549 32.9258Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M8.53955 35.7942C8.21768 36.2662 7.9543 36.7768 7.75684 37.3114L9.28184 37.8769C9.43311 37.4671 9.63516 37.0756 9.88213 36.7132L8.53955 35.7942Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M7.51758 38.1304C7.39316 38.6588 7.33008 39.2046 7.33008 39.7526V39.8158H8.95605V39.7526C8.95605 39.3304 9.00449 38.9105 9.1001 38.5046L7.51758 38.1304Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M10.3297 33.9829C9.86269 34.3089 9.43564 34.6913 9.06055 35.1195L10.2823 36.1946C10.571 35.8651 10.8998 35.5708 11.2593 35.3198L10.3297 33.9829Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M22.1123 10.0642V22.6188H28.4109V10.0642H22.1123ZM26.785 20.9894H23.7383V11.6935H26.785V20.9894Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M21.3535 10.7935H19.7275V12.4227H21.3535V10.7935Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M21.3535 15.5801H19.7275V17.1076H21.3535V15.5801Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M21.3535 20.2642H19.7275V21.7917H21.3535V20.2642Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M30.6992 10.7939H29.0732V12.4232H30.6992V10.7939Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M30.6992 15.5801H29.0732V17.1076H30.6992V15.5801Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M30.6992 20.2642H29.0732V21.7917H30.6992V20.2642Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M40.177 20.8755L39.041 22.0412C39.4915 22.482 40.014 22.8262 40.5939 23.0643L41.2104 21.5567C40.8249 21.3983 40.4771 21.1692 40.177 20.8755Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M39.2954 19.2759L37.7021 19.6011C37.8276 20.2189 38.0753 20.7992 38.438 21.326L39.7764 20.4007C39.5388 20.0556 39.3769 19.6772 39.2954 19.2759Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M38.58 32.3945L37.0928 33.0534C37.3451 33.6254 37.7033 34.139 38.1573 34.5799L39.2892 33.4101C38.9861 33.1157 38.7474 32.7739 38.58 32.3945Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M39.7758 33.8L38.8848 35.163C39.4165 35.512 39.9979 35.7482 40.6127 35.865L40.9154 34.2641C40.5115 34.1875 40.128 34.0313 39.7758 33.8Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M47.873 33.502H46.2471V35.8441H47.873V33.502Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M0.211914 -0.000244141V30.4477H14.2363V32.6971C13.9709 32.7008 13.7221 32.718 13.4657 32.75L13.6721 34.3667C13.8592 34.3434 14.057 34.3303 14.2364 34.3265V35.0302H15.8624V28.8184H1.83789V1.62914H15.1482L15.0967 7.1281H33.7484V17.9224H37.6103V18.6353H39.2362V17.9224H40.0492V16.2931H35.3744V14.8675H37.7119V13.899C37.9593 13.987 38.2252 14.0352 38.5022 14.0352C39.8094 14.0352 40.8728 12.9697 40.8728 11.6598C40.8728 10.35 39.8094 9.28444 38.5022 9.28444C38.2251 9.28444 37.9593 9.33278 37.7119 9.42065V8.55375H35.3745V1.62914H36.1317V7.11372H47.8819V1.62914H48.5859V7.81123C46.8282 8.1912 45.4709 9.77215 45.4709 11.6599C45.4709 13.5476 46.8282 15.1287 48.5859 15.5085V16.293H42.2852V21.7893C42.1231 21.7836 41.9612 21.7656 41.8024 21.7346L41.4918 23.3339C41.7527 23.3848 42.0191 23.4123 42.2852 23.4186V23.4213H42.3963H43.1997H43.9111V17.9223H48.5859V28.8184H42.2852V34.3174H41.5737V35.9467H42.2852H43.0981H43.9111V30.4477H48.5859V37.3777H36.9104V46.8108H48.5859V48.3704H29.8867V46.9447H33.8501V33.5028H29.8867V30.4478H36.6957V31.1694C36.6958 31.5011 36.7316 31.8337 36.8025 32.1579L38.391 31.8096C38.3452 31.5995 38.3218 31.3839 38.3217 31.1691V30.4478H39.3379V28.8185H28.2607V48.3705H26.8379V45.3154H17.3867V48.3705H15.8623V40.5294H7.32578V42.1586H14.2363V49.9998H50.2119V46.8109V37.3778V-0.000244141H0.211914ZM19.0127 1.62914H23.5858V3.05479H19.0127V1.62914ZM33.7485 5.49872H16.7382L16.7743 1.62904H17.3867V4.68408H25.2119V1.62914H33.7485V5.49872ZM38.5022 10.9138C38.9128 10.9138 39.2468 11.2486 39.2468 11.6599C39.2468 12.0712 38.9128 12.406 38.5022 12.406C38.0917 12.406 37.7577 12.0712 37.7577 11.6599C37.7577 11.2485 38.0917 10.9138 38.5022 10.9138ZM36.0859 10.183V13.238H35.3745V10.183H36.0859ZM46.256 5.48443H37.7578V1.65125H46.256V5.48443ZM29.8867 35.1322H32.2241V45.3154H29.8867V35.1322ZM25.2119 48.3704H19.0127V46.9447H25.2119V48.3704ZM45.4354 45.1815H38.5364V39.0071H45.4354V45.1815ZM48.5859 45.1815H47.0615V39.0071H48.5859V45.1815ZM48.5859 13.8096C47.7364 13.4743 47.0969 12.6374 47.0969 11.6599C47.0969 10.6824 47.7364 9.84554 48.5859 9.51019V13.8096Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M15.1523 26.4756H2.65234V28.1049H15.1523V26.4756Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M15.9513 13.2549V11.6256V9.28442H2.64355V11.6255V13.2548V17.1567H15.9514V13.2548L15.9513 13.2549ZM14.3253 15.5273H4.26953V13.2548H14.3253V15.5273ZM14.3253 11.6255H4.26953V10.9137H14.3253V11.6255Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
13
assets/icons/villa_icon.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg width="51" height="50" viewBox="0 0 51 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M36.1758 21.3652H37.643V22.7826H36.1758V21.3652Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M30.3071 37.3965H31.7743V38.8627H30.3071V37.3965Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M42.7781 48.5334H44.2453V49.9997H42.7781V48.5334Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M48.647 33.022H50.2119V31.7382L45.3178 27.157H44.2454V16.8931H45.8104V15.6093L40.9163 11.0282H27.427V8.09556H22.9713V11.0281H21.4145L15.6416 4.81909L0.325879 21.2919H5.36515V40.3681C2.70733 40.3681 0.22168 43.4137 0.22168 45.4935V49.9995H41.3111V48.5333H1.68887V46.9598H48.7302V48.5333H45.7126V49.9995H50.1974L50.2119 45.4935C50.0587 44.2414 49.4642 43.1105 48.647 42.2302V33.022ZM47.1798 41.0817C46.7291 40.8325 46.2422 40.6418 45.7293 40.5179V34.4883H27.3728V44.0345H38.9156C38.7306 44.495 38.6028 44.9842 38.5405 45.4935H25.9181V33.022H47.1798V41.0817ZM39.77 42.5682H37.2845V35.9545H44.262V40.3556C42.4447 40.3837 40.8264 41.2423 39.77 42.5682ZM28.84 42.5682V35.9545H35.8174V42.5682H28.84ZM42.7782 24.2244H34.7088V19.8257H42.7782V24.2244ZM42.7782 18.3594H33.2416V25.6906H42.7782V27.1568H39.8917V28.623H44.738L47.8708 31.5556H25.9181V28.623H38.4308V27.1568H25.9181V21.2918H30.9573L26.8675 16.893H42.7782V18.3594ZM24.4384 9.56187H25.9597V11.0281H24.4384V9.56187ZM40.3364 12.4943L43.4692 15.4268H25.5042L22.7777 12.4943H40.3364ZM15.6416 6.9733L27.5913 19.8257H25.5042L21.3204 15.3257L20.2456 16.3238L24.4509 20.8468V45.4935H20.037V33.022H11.2463V45.4935H6.83224V20.8468L15.6415 11.372L19.194 15.1928L20.2688 14.1947L15.6416 9.21793L5.77892 19.8257H3.6919L15.6416 6.9733ZM18.5698 45.4935H12.7135V34.4882H18.5698V45.4935ZM5.36505 41.8507V45.4935H1.75039C2.05938 43.6418 3.51749 42.1748 5.36505 41.8507ZM40.0216 45.4935C40.364 43.4124 42.1758 41.8195 44.3536 41.8195C46.5314 41.8195 48.3431 43.4125 48.6856 45.4935H40.0216Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M15.6355 27.1086C17.6581 27.1086 19.3035 25.4643 19.3035 23.443C19.3035 21.4217 17.6581 19.7773 15.6355 19.7773C13.6129 19.7773 11.9675 21.4217 11.9675 23.443C11.9675 25.4643 13.6129 27.1086 15.6355 27.1086ZM15.6355 21.2436C16.849 21.2436 17.8363 22.2302 17.8363 23.443C17.8363 24.6557 16.8491 25.6424 15.6355 25.6424C14.4219 25.6424 13.4347 24.6557 13.4347 23.443C13.4347 22.2302 14.4219 21.2436 15.6355 21.2436Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M11.9741 29.3569H13.4413V30.8231H11.9741V29.3569Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M14.9082 29.3569H16.3754V30.8231H14.9082V29.3569Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M17.8423 29.3569H19.3095V30.8231H17.8423V29.3569Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M15.636 38.8877H17.1032V40.3539H15.636V38.8877Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M41.2607 5.87106H47.2334C48.8531 5.87106 50.1709 4.55406 50.1709 2.93541C50.1709 1.31675 48.8531 -0.000244141 47.2334 -0.000244141H41.2607C39.641 -0.000244141 38.3232 1.31675 38.3232 2.93541C38.3232 4.55406 39.641 5.87106 41.2607 5.87106ZM41.2607 1.46597H47.2334C48.0442 1.46597 48.7037 2.12515 48.7037 2.93541C48.7037 3.74566 48.0442 4.40484 47.2334 4.40484H41.2607C40.45 4.40484 39.7904 3.74566 39.7904 2.93541C39.7904 2.12515 40.45 1.46597 41.2607 1.46597Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
<path d="M3.14966 5.87106H9.12233C10.7421 5.87106 12.0598 4.55406 12.0598 2.93541C12.0598 1.31675 10.7421 -0.000244141 9.12233 -0.000244141H3.14966C1.52993 -0.000244141 0.212158 1.31675 0.212158 2.93541C0.212158 4.55406 1.52993 5.87106 3.14966 5.87106ZM3.14966 1.46597H9.12233C9.93307 1.46597 10.5926 2.12515 10.5926 2.93541C10.5926 3.74566 9.93307 4.40484 9.12233 4.40484H3.14966C2.33892 4.40484 1.67935 3.74566 1.67935 2.93541C1.67935 2.12515 2.33892 1.46597 3.14966 1.46597Z" fill="#023DFE" fill-opacity="0.7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
8
assets/icons/water_leak_sensor.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg width="37" height="47" viewBox="0 0 37 47" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M36.6443 28.4398C36.6443 38.5501 28.4413 46.7461 18.3224 46.7461C8.20342 46.7461 0.000335693 38.5501 0.000335693 28.4398C0.000335693 19.5029 14.3167 3.8154 17.6394 0.294848C18.0104 -0.0982013 18.6344 -0.0982013 19.0053 0.294848C22.328 3.81549 36.6443 19.5029 36.6443 28.4398Z" fill="#B3DAFE"/>
|
||||
<path d="M19.0053 0.294848C18.6344 -0.0982013 18.0103 -0.0982013 17.6395 0.294848C17.4362 0.510226 17.1913 0.771711 16.9115 1.07373C21.2048 5.70989 33.8227 20.0494 33.8227 28.4397C33.8227 38.0757 26.3713 45.9728 16.9115 46.6925C17.3772 46.7279 17.8476 46.746 18.3224 46.746C28.4413 46.746 36.6444 38.55 36.6444 28.4397C36.6444 19.5029 22.328 3.81549 19.0053 0.294848Z" fill="#8AC9FE"/>
|
||||
<path d="M36.5956 29.7673C31.4893 27.604 25.9554 28.0264 11.6693 31.0136C8.45246 31.6862 4.77213 32.4931 0.695374 33.4537C2.87719 41.1269 9.94258 46.7469 18.3219 46.7469C27.9943 46.7469 35.9152 39.2581 36.5956 29.7673Z" fill="#60B7FF"/>
|
||||
<path d="M36.5952 29.7577C35.7237 29.3885 34.7576 29.0972 33.8165 28.8831C33.7757 30.6664 33.5004 32.3468 32.9709 33.9632L35.2332 35.4927C35.5931 34.6501 35.9231 33.6175 36.1968 32.4139C36.4192 31.4361 36.5371 30.5392 36.5952 29.7577Z" fill="#26A6FE"/>
|
||||
<path d="M25.1626 32.4333C15.5835 30.8556 10.5889 24.7281 0.454312 25.3904C0.162424 26.4676 -9.15527e-05 27.4921 -9.15527e-05 28.44C-9.15527e-05 38.5502 8.20291 46.7462 18.3219 46.7462C27.2128 46.7462 34.6236 40.4186 36.2917 32.025C31.7586 33.0372 28.0498 32.9088 25.1626 32.4333Z" fill="#0593FC"/>
|
||||
<path d="M33.3579 32.5424C31.5943 40.235 24.9815 46.0792 16.9042 46.691C17.3721 46.7268 17.8447 46.745 18.3217 46.745C27.2125 46.745 34.6233 40.4174 36.2915 32.0238C35.2718 32.2515 34.2942 32.4211 33.3579 32.5424Z" fill="#0182FC"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
@ -1,7 +1,7 @@
|
||||
import UIKit
|
||||
import Flutter
|
||||
|
||||
@UIApplicationMain
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
|
125
lib/common/custom_expansion_tile.dart
Normal file
@ -0,0 +1,125 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CustomExpansionTile extends StatefulWidget {
|
||||
final String title;
|
||||
final List<Widget>? children;
|
||||
final bool initiallyExpanded;
|
||||
final bool isSelected; // Add this to track selection
|
||||
final bool? isExpanded; // External control over expansion
|
||||
final ValueChanged<bool>? onExpansionChanged; // Notify when expansion changes
|
||||
final VoidCallback? onItemSelected; // Callback for selecting the item
|
||||
|
||||
CustomExpansionTile({
|
||||
required this.title,
|
||||
this.children,
|
||||
this.initiallyExpanded = false,
|
||||
this.isExpanded, // Allow external control over expansion
|
||||
this.onExpansionChanged, // Notify when expansion changes
|
||||
this.onItemSelected, // Trigger item selection when name is tapped
|
||||
required this.isSelected, // Add this to initialize selection state
|
||||
});
|
||||
|
||||
@override
|
||||
CustomExpansionTileState createState() => CustomExpansionTileState();
|
||||
}
|
||||
|
||||
class CustomExpansionTileState extends State<CustomExpansionTile> {
|
||||
bool _isExpanded = false; // Local expansion state
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_isExpanded = widget.initiallyExpanded;
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(CustomExpansionTile oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
// Sync local state with external control of expansion state
|
||||
if (widget.isExpanded != null && widget.isExpanded != _isExpanded) {
|
||||
setState(() {
|
||||
_isExpanded = widget.isExpanded!;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function to capitalize the first letter of the title
|
||||
String _capitalizeFirstLetter(String text) {
|
||||
if (text.isEmpty) return text;
|
||||
return text[0].toUpperCase() + text.substring(1);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
// Checkbox with independent state management
|
||||
Checkbox(
|
||||
value: false,
|
||||
onChanged: (bool? value) {
|
||||
setState(() {});
|
||||
},
|
||||
side: WidgetStateBorderSide.resolveWith((states) {
|
||||
return const BorderSide(color: ColorsManager.grayBorder);
|
||||
}),
|
||||
fillColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return ColorsManager.grayBorder;
|
||||
} else {
|
||||
return ColorsManager.checkBoxFillColor;
|
||||
}
|
||||
}),
|
||||
checkColor: ColorsManager.whiteColors,
|
||||
),
|
||||
// Expand/collapse icon, now wrapped in a GestureDetector for specific onTap
|
||||
if (widget.children != null && widget.children!.isNotEmpty)
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isExpanded = !_isExpanded;
|
||||
widget.onExpansionChanged?.call(_isExpanded);
|
||||
});
|
||||
},
|
||||
child: Icon(
|
||||
_isExpanded ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_right,
|
||||
color: ColorsManager.lightGrayColor,
|
||||
size: 16.0, // Adjusted size for better alignment
|
||||
),
|
||||
),
|
||||
// The title text, wrapped in GestureDetector to handle selection
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
if (widget.onItemSelected != null) {
|
||||
widget.onItemSelected!();
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
_capitalizeFirstLetter(widget.title),
|
||||
style: TextStyle(
|
||||
color: widget.isSelected
|
||||
? ColorsManager.blackColor // Change color to black when selected
|
||||
: ColorsManager.lightGrayColor, // Gray when not selected
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// The expanded section (children) that shows when the tile is expanded
|
||||
if (_isExpanded && widget.children != null && widget.children!.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 48.0), // Indented children
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: widget.children!,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
78
lib/common/search_bar.dart
Normal file
@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class CustomSearchBar extends StatelessWidget {
|
||||
final TextEditingController? controller;
|
||||
final String hintText;
|
||||
final Function(String)? onSearchChanged; // Callback for search input changes
|
||||
|
||||
const CustomSearchBar({
|
||||
super.key,
|
||||
this.controller,
|
||||
this.hintText = 'Search',
|
||||
this.onSearchChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20.0),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
),
|
||||
onChanged: onSearchChanged, // Call the callback on text change
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: ColorsManager.textFieldGreyColor,
|
||||
hintText: hintText,
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xB2999999),
|
||||
fontSize: 12,
|
||||
fontFamily: 'Aftika',
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 0,
|
||||
letterSpacing: -0.24,
|
||||
),
|
||||
suffixIcon: Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: SvgPicture.asset(
|
||||
Assets.textFieldSearch,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 14,
|
||||
horizontal: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
45
lib/pages/common/buttons/add_space_button.dart
Normal file
@ -0,0 +1,45 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class AddSpaceButton extends StatelessWidget {
|
||||
final VoidCallback onTap;
|
||||
|
||||
const AddSpaceButton({super.key, required this.onTap});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap, // Handle tap event
|
||||
child: Container(
|
||||
width: 120, // Width of the button
|
||||
height: 60, // Height of the button
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20), // Rounded corners
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5), // Shadow color
|
||||
spreadRadius: 5, // Spread radius of the shadow
|
||||
blurRadius: 7, // Blur effect
|
||||
offset: const Offset(0, 3), // Shadow position
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 40, // Size of the inner circle
|
||||
height: 40,
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.boxColor, // Light gray background
|
||||
shape: BoxShape.circle, // Circular shape for the icon container
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.add, // Add icon
|
||||
color: Colors.blue, // Icon color
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
38
lib/pages/common/buttons/cancel_button.dart
Normal file
@ -0,0 +1,38 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CancelButton extends StatelessWidget {
|
||||
final String label;
|
||||
final VoidCallback? onPressed;
|
||||
final double? height; // Optional height parameter for customization
|
||||
final double? borderRadius; // Optional border radius customization
|
||||
final double? width;
|
||||
|
||||
const CancelButton({
|
||||
super.key,
|
||||
required this.label, // Button label
|
||||
required this.onPressed, // Button action
|
||||
this.height = 40, // Default height
|
||||
this.width = 140,
|
||||
this.borderRadius = 10, // Default border radius
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ElevatedButton(
|
||||
onPressed: onPressed,
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(ColorsManager.boxColor), // White background
|
||||
foregroundColor: WidgetStateProperty.all(Colors.black), // Black text color
|
||||
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(borderRadius ?? 10),
|
||||
side: const BorderSide(color: ColorsManager.boxColor), // Black border
|
||||
),
|
||||
),
|
||||
fixedSize: WidgetStateProperty.all(Size(width ?? 50, height ?? 40)), // Set button height
|
||||
),
|
||||
child: Text(label), // Dynamic label
|
||||
);
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ class DefaultButton extends StatelessWidget {
|
||||
this.backgroundColor,
|
||||
this.foregroundColor,
|
||||
this.borderRadius,
|
||||
this.height,
|
||||
this.height = 40,
|
||||
this.padding,
|
||||
this.borderColor,
|
||||
this.elevation,
|
||||
@ -70,14 +70,14 @@ class DefaultButton extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(borderRadius ?? 20),
|
||||
),
|
||||
),
|
||||
fixedSize: WidgetStateProperty.all(
|
||||
const Size.fromHeight(50),
|
||||
),
|
||||
fixedSize: height != null
|
||||
? WidgetStateProperty.all(Size.fromHeight(height!))
|
||||
: null,
|
||||
padding: WidgetStateProperty.all(
|
||||
EdgeInsets.all(padding ?? 10),
|
||||
),
|
||||
minimumSize: WidgetStateProperty.all(
|
||||
const Size.fromHeight(50),
|
||||
const Size.fromHeight(10),
|
||||
),
|
||||
elevation: WidgetStateProperty.all(elevation ?? 0),
|
||||
),
|
||||
|
@ -0,0 +1,22 @@
|
||||
class DeviceTypeModel {
|
||||
final String name;
|
||||
final String icon;
|
||||
|
||||
DeviceTypeModel({required this.name, required this.icon});
|
||||
|
||||
// Factory method for creating a new DeviceTypeModel from JSON
|
||||
factory DeviceTypeModel.fromJson(Map<String, dynamic> json) {
|
||||
return DeviceTypeModel(
|
||||
name: json['name'],
|
||||
icon: json['icon'],
|
||||
);
|
||||
}
|
||||
|
||||
// Convert this model to JSON format
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'icon': icon,
|
||||
};
|
||||
}
|
||||
}
|
@ -74,7 +74,9 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
title: 'Space Management',
|
||||
icon: Assets.spaseManagementIcon,
|
||||
active: true,
|
||||
onPress: (context) {},
|
||||
onPress: (context) {
|
||||
context.go(RoutesConst.spacesManagementPage);
|
||||
},
|
||||
color: ColorsManager.primaryColor,
|
||||
),
|
||||
HomeItemModel(
|
||||
|
259
lib/pages/spaces_management/bloc/space_management_bloc.dart
Normal file
@ -0,0 +1,259 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_state.dart';
|
||||
import 'package:syncrow_web/services/product_api.dart';
|
||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||
|
||||
class SpaceManagementBloc extends Bloc<SpaceManagementEvent, SpaceManagementState> {
|
||||
final CommunitySpaceManagementApi _api;
|
||||
final ProductApi _productApi;
|
||||
|
||||
List<ProductModel>? _cachedProducts;
|
||||
|
||||
SpaceManagementBloc(this._api, this._productApi) : super(SpaceManagementInitial()) {
|
||||
on<LoadCommunityAndSpacesEvent>(_onLoadCommunityAndSpaces);
|
||||
on<UpdateSpacePositionEvent>(_onUpdateSpacePosition);
|
||||
on<CreateCommunityEvent>(_onCreateCommunity);
|
||||
on<SaveSpacesEvent>(_onSaveSpaces);
|
||||
on<FetchProductsEvent>(_onFetchProducts);
|
||||
on<DeleteCommunityEvent>(_onCommunityDelete);
|
||||
on<UpdateCommunityEvent>(_onUpdateCommunity);
|
||||
}
|
||||
|
||||
void _onUpdateCommunity(
|
||||
UpdateCommunityEvent event,
|
||||
Emitter<SpaceManagementState> emit,
|
||||
) async {
|
||||
final previousState = state;
|
||||
try {
|
||||
emit(SpaceManagementLoading());
|
||||
final success = await _api.updateCommunity(event.communityUuid, event.name);
|
||||
if (success) {
|
||||
if (previousState is SpaceManagementLoaded) {
|
||||
final updatedCommunities = List<CommunityModel>.from(previousState.communities);
|
||||
for(var community in updatedCommunities){
|
||||
if(community.uuid == event.communityUuid){
|
||||
community.name = event.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
emit(SpaceManagementLoaded(
|
||||
communities: updatedCommunities,
|
||||
products: previousState.products,
|
||||
selectedCommunity: previousState.selectedCommunity,
|
||||
));
|
||||
|
||||
}
|
||||
} else {
|
||||
emit(const SpaceManagementError('Failed to update the community.'));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(SpaceManagementError('Error updating community: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
void _onFetchProducts(
|
||||
FetchProductsEvent event,
|
||||
Emitter<SpaceManagementState> emit,
|
||||
) async {
|
||||
if (_cachedProducts != null) {
|
||||
// Products are already cached, no need to fetch again
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final products = await _productApi.fetchProducts();
|
||||
_cachedProducts = products; // Cache the products locally
|
||||
} catch (e) {
|
||||
emit(SpaceManagementError('Error fetching products: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
void _onLoadCommunityAndSpaces(
|
||||
LoadCommunityAndSpacesEvent event,
|
||||
Emitter<SpaceManagementState> emit,
|
||||
) async {
|
||||
emit(SpaceManagementLoading());
|
||||
try {
|
||||
if (_cachedProducts == null) {
|
||||
final products = await _productApi.fetchProducts();
|
||||
_cachedProducts = products;
|
||||
}
|
||||
|
||||
// Fetch all communities
|
||||
List<CommunityModel> communities = await _api.fetchCommunities();
|
||||
|
||||
List<CommunityModel> updatedCommunities = await Future.wait(
|
||||
communities.map((community) async {
|
||||
List<SpaceModel> spaces = await _api.getSpaceHierarchy(community.uuid);
|
||||
return CommunityModel(
|
||||
uuid: community.uuid,
|
||||
createdAt: community.createdAt,
|
||||
updatedAt: community.updatedAt,
|
||||
name: community.name,
|
||||
description: community.description,
|
||||
spaces: spaces, // New spaces list
|
||||
region: community.region,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
|
||||
emit(SpaceManagementLoaded(communities: updatedCommunities, products: _cachedProducts ?? []));
|
||||
} catch (e) {
|
||||
emit(SpaceManagementError('Error loading communities and spaces: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
void _onCommunityDelete(
|
||||
DeleteCommunityEvent event,
|
||||
Emitter<SpaceManagementState> emit,
|
||||
) async {
|
||||
try {
|
||||
emit(SpaceManagementLoading());
|
||||
|
||||
final success = await _api.deleteCommunity(event.communityUuid);
|
||||
if (success) {
|
||||
add(LoadCommunityAndSpacesEvent());
|
||||
} else {
|
||||
emit(const SpaceManagementError('Failed to delete the community.'));
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle unexpected errors
|
||||
emit(SpaceManagementError('Error saving spaces: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
void _onUpdateSpacePosition(
|
||||
UpdateSpacePositionEvent event,
|
||||
Emitter<SpaceManagementState> emit,
|
||||
) {}
|
||||
|
||||
void _onCreateCommunity(
|
||||
CreateCommunityEvent event,
|
||||
Emitter<SpaceManagementState> emit,
|
||||
) async {
|
||||
final previousState = state;
|
||||
emit(SpaceManagementLoading());
|
||||
|
||||
try {
|
||||
CommunityModel? newCommunity = await _api.createCommunity(event.name, event.description);
|
||||
|
||||
if (newCommunity != null) {
|
||||
if (previousState is SpaceManagementLoaded) {
|
||||
final updatedCommunities = List<CommunityModel>.from(previousState.communities)
|
||||
..add(newCommunity);
|
||||
emit(SpaceManagementLoaded(
|
||||
communities: updatedCommunities,
|
||||
products: _cachedProducts ?? [],
|
||||
selectedCommunity: newCommunity));
|
||||
}
|
||||
} else {
|
||||
emit(const SpaceManagementError('Error creating community'));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(SpaceManagementError('Error creating community: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
void _onSaveSpaces(
|
||||
SaveSpacesEvent event,
|
||||
Emitter<SpaceManagementState> emit,
|
||||
) async {
|
||||
final previousState = state;
|
||||
emit(SpaceManagementLoading());
|
||||
|
||||
try {
|
||||
final updatedSpaces = await saveSpacesHierarchically(event.spaces, event.communityUuid);
|
||||
emit(SpaceCreationSuccess(spaces: updatedSpaces));
|
||||
add(LoadCommunityAndSpacesEvent());
|
||||
} catch (e) {
|
||||
emit(SpaceManagementError('Error saving spaces: $e'));
|
||||
if (previousState is SpaceManagementLoaded) {
|
||||
emit(previousState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SpaceModel>> saveSpacesHierarchically(
|
||||
List<SpaceModel> spaces, String communityUuid) async {
|
||||
final orderedSpaces = flattenHierarchy(spaces);
|
||||
|
||||
final parentsToDelete = orderedSpaces.where((space) =>
|
||||
space.status == SpaceStatus.deleted &&
|
||||
(space.parent == null || space.parent?.status != SpaceStatus.deleted));
|
||||
|
||||
for (var parent in parentsToDelete) {
|
||||
try {
|
||||
// Ensure parent.uuid is not null before calling the API
|
||||
if (parent.uuid != null) {
|
||||
await _api.deleteSpace(communityUuid, parent.uuid!);
|
||||
}
|
||||
} catch (e) {
|
||||
print(
|
||||
'Error deleting space ${parent.name} (UUID: ${parent.uuid}, Community UUID: $communityUuid): $e');
|
||||
rethrow; // Decide whether to stop execution or continue
|
||||
}
|
||||
}
|
||||
|
||||
for (var space in orderedSpaces) {
|
||||
try {
|
||||
if (space.uuid != null && space.uuid!.isNotEmpty) {
|
||||
final response = await _api.updateSpace(
|
||||
communityId: communityUuid,
|
||||
spaceId: space.uuid!,
|
||||
name: space.name,
|
||||
parentId: space.parent?.uuid,
|
||||
isPrivate: space.isPrivate,
|
||||
position: space.position,
|
||||
icon: space.icon,
|
||||
direction: space.incomingConnection?.direction,
|
||||
products: space.selectedProducts);
|
||||
} else {
|
||||
// Call create if the space does not have a UUID
|
||||
final response = await _api.createSpace(
|
||||
communityId: communityUuid,
|
||||
name: space.name,
|
||||
parentId: space.parent?.uuid,
|
||||
isPrivate: space.isPrivate,
|
||||
position: space.position,
|
||||
icon: space.icon,
|
||||
direction: space.incomingConnection?.direction,
|
||||
products: space.selectedProducts);
|
||||
space.uuid = response?.uuid;
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error creating space ${space.name}: $e');
|
||||
rethrow; // Stop further execution on failure
|
||||
}
|
||||
}
|
||||
return spaces;
|
||||
}
|
||||
|
||||
List<SpaceModel> flattenHierarchy(List<SpaceModel> spaces) {
|
||||
final result = <SpaceModel>{};
|
||||
final topLevelSpaces = spaces.where((space) => space.parent == null);
|
||||
|
||||
void visit(SpaceModel space) {
|
||||
if (!result.contains(space)) {
|
||||
result.add(space);
|
||||
for (var child in spaces.where((s) => s.parent == space)) {
|
||||
visit(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var space in topLevelSpaces) {
|
||||
visit(space);
|
||||
}
|
||||
|
||||
for (var space in spaces) {
|
||||
if (!result.contains(space)) {
|
||||
result.add(space);
|
||||
}
|
||||
}
|
||||
return result.toList(); // Convert back to a list
|
||||
}
|
||||
}
|
108
lib/pages/spaces_management/bloc/space_management_event.dart
Normal file
@ -0,0 +1,108 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; // Import for Offset
|
||||
|
||||
abstract class SpaceManagementEvent extends Equatable {
|
||||
const SpaceManagementEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class LoadCommunityAndSpacesEvent extends SpaceManagementEvent {}
|
||||
|
||||
class DeleteCommunityEvent extends SpaceManagementEvent {
|
||||
final String communityUuid;
|
||||
|
||||
const DeleteCommunityEvent({
|
||||
required this.communityUuid,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [communityUuid];
|
||||
}
|
||||
|
||||
class CreateSpaceEvent extends SpaceManagementEvent {
|
||||
final String name;
|
||||
final String icon;
|
||||
final Offset position;
|
||||
final int? parentIndex;
|
||||
final String? direction;
|
||||
|
||||
const CreateSpaceEvent({
|
||||
required this.name,
|
||||
required this.icon,
|
||||
required this.position,
|
||||
this.parentIndex,
|
||||
this.direction,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [
|
||||
name,
|
||||
icon,
|
||||
position,
|
||||
parentIndex ?? -1, // Use a fallback value if nullable
|
||||
direction ?? '', // Use a fallback value if nullable
|
||||
];
|
||||
}
|
||||
|
||||
class SaveSpacesEvent extends SpaceManagementEvent {
|
||||
final List<SpaceModel> spaces;
|
||||
final String communityUuid;
|
||||
|
||||
const SaveSpacesEvent({
|
||||
required this.spaces,
|
||||
required this.communityUuid,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [spaces, communityUuid];
|
||||
}
|
||||
|
||||
class UpdateSpacePositionEvent extends SpaceManagementEvent {
|
||||
final int index;
|
||||
final Offset newPosition;
|
||||
|
||||
const UpdateSpacePositionEvent(this.index, this.newPosition);
|
||||
|
||||
@override
|
||||
List<Object> get props => [index, newPosition];
|
||||
}
|
||||
|
||||
class CreateCommunityEvent extends SpaceManagementEvent {
|
||||
final String name;
|
||||
final String description;
|
||||
|
||||
const CreateCommunityEvent({
|
||||
required this.name,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [name, description];
|
||||
}
|
||||
|
||||
class FetchProductsEvent extends SpaceManagementEvent {}
|
||||
|
||||
class LoadSpaceHierarchyEvent extends SpaceManagementEvent {
|
||||
final String communityId;
|
||||
|
||||
const LoadSpaceHierarchyEvent({required this.communityId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [communityId];
|
||||
}
|
||||
|
||||
class UpdateCommunityEvent extends SpaceManagementEvent {
|
||||
final String communityUuid;
|
||||
final String name;
|
||||
|
||||
const UpdateCommunityEvent({
|
||||
required this.communityUuid,
|
||||
required this.name,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [communityUuid, name];
|
||||
}
|
42
lib/pages/spaces_management/bloc/space_management_state.dart
Normal file
@ -0,0 +1,42 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
|
||||
abstract class SpaceManagementState extends Equatable {
|
||||
const SpaceManagementState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class SpaceManagementInitial extends SpaceManagementState {}
|
||||
|
||||
class SpaceManagementLoading extends SpaceManagementState {}
|
||||
|
||||
class SpaceManagementLoaded extends SpaceManagementState {
|
||||
final List<CommunityModel> communities;
|
||||
final List<ProductModel> products;
|
||||
CommunityModel? selectedCommunity; // Include products in the state
|
||||
|
||||
SpaceManagementLoaded(
|
||||
{required this.communities, required this.products, this.selectedCommunity});
|
||||
}
|
||||
|
||||
class SpaceCreationSuccess extends SpaceManagementState {
|
||||
final List<SpaceModel> spaces;
|
||||
|
||||
const SpaceCreationSuccess({required this.spaces});
|
||||
|
||||
@override
|
||||
List<Object> get props => [spaces];
|
||||
}
|
||||
|
||||
class SpaceManagementError extends SpaceManagementState {
|
||||
final String errorMessage;
|
||||
|
||||
const SpaceManagementError(this.errorMessage);
|
||||
|
||||
@override
|
||||
List<Object> get props => [errorMessage];
|
||||
}
|
48
lib/pages/spaces_management/model/community_model.dart
Normal file
@ -0,0 +1,48 @@
|
||||
import 'package:syncrow_web/pages/auth/model/region_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
|
||||
class CommunityModel {
|
||||
final String uuid;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
String name;
|
||||
final String description;
|
||||
final RegionModel? region;
|
||||
List<SpaceModel> spaces;
|
||||
|
||||
CommunityModel({
|
||||
required this.uuid,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.spaces,
|
||||
this.region,
|
||||
});
|
||||
|
||||
factory CommunityModel.fromJson(Map<String, dynamic> json) {
|
||||
return CommunityModel(
|
||||
uuid: json['uuid'],
|
||||
createdAt: DateTime.parse(json['createdAt']),
|
||||
updatedAt: DateTime.parse(json['updatedAt']),
|
||||
name: json['name'],
|
||||
description: json['description'],
|
||||
region: json['region'] != null ? RegionModel.fromJson(json['region']) : null,
|
||||
spaces: json['spaces'] != null
|
||||
? (json['spaces'] as List).map((space) => SpaceModel.fromJson(space)).toList()
|
||||
: [],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'uuid': uuid,
|
||||
'createdAt': createdAt.toIso8601String(),
|
||||
'updatedAt': updatedAt.toIso8601String(),
|
||||
'name': name,
|
||||
'description': description,
|
||||
'region': region?.toJson(),
|
||||
'spaces': spaces.map((space) => space.toMap()).toList(), // Convert spaces to Map
|
||||
};
|
||||
}
|
||||
}
|
25
lib/pages/spaces_management/model/connection_model.dart
Normal file
@ -0,0 +1,25 @@
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
|
||||
class Connection {
|
||||
final SpaceModel startSpace;
|
||||
final SpaceModel endSpace;
|
||||
final String direction;
|
||||
|
||||
Connection({required this.startSpace, required this.endSpace, required this.direction});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'startUuid': startSpace.uuid ?? 'unsaved-start-space-${startSpace.name}', // Fallback for unsaved spaces
|
||||
'endUuid': endSpace.uuid ?? 'unsaved-end-space-${endSpace.name}', // Fallback for unsaved spaces
|
||||
'direction': direction,
|
||||
};
|
||||
}
|
||||
|
||||
static Connection fromMap(Map<String, dynamic> map, Map<String, SpaceModel> spaces) {
|
||||
return Connection(
|
||||
startSpace: spaces[map['startUuid']]!,
|
||||
endSpace: spaces[map['endUuid']]!,
|
||||
direction: map['direction'],
|
||||
);
|
||||
}
|
||||
}
|
70
lib/pages/spaces_management/model/product_model.dart
Normal file
@ -0,0 +1,70 @@
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class ProductModel {
|
||||
final String uuid;
|
||||
final String catName;
|
||||
String? name;
|
||||
final String prodId;
|
||||
final String prodType;
|
||||
String? icon;
|
||||
|
||||
ProductModel({
|
||||
required this.uuid,
|
||||
required this.catName,
|
||||
required this.prodId,
|
||||
required this.prodType,
|
||||
required this.name,
|
||||
this.icon,
|
||||
});
|
||||
|
||||
// Factory method to create a Product from JSON
|
||||
factory ProductModel.fromMap(Map<String, dynamic> json) {
|
||||
String icon = _mapIconToProduct(json['prodType']);
|
||||
return ProductModel(
|
||||
uuid: json['uuid'],
|
||||
catName: json['catName'],
|
||||
prodId: json['prodId'],
|
||||
prodType: json['prodType'],
|
||||
name: json['name'] ?? '',
|
||||
icon: _mapIconToProduct(json['prodType']));
|
||||
}
|
||||
|
||||
// Method to convert a Product to JSON
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'uuid': uuid,
|
||||
'catName': catName,
|
||||
'prodId': prodId,
|
||||
'prodType': prodType,
|
||||
};
|
||||
}
|
||||
|
||||
static String _mapIconToProduct(String prodType) {
|
||||
const iconMapping = {
|
||||
'1G': Assets.Gang1SwitchIcon,
|
||||
'1GT': Assets.oneTouchSwitch,
|
||||
'2G': Assets.Gang2SwitchIcon,
|
||||
'2GT': Assets.twoTouchSwitch,
|
||||
'3G': Assets.Gang3SwitchIcon,
|
||||
'3GT': Assets.threeTouchSwitch,
|
||||
'CUR': Assets.curtain,
|
||||
'GD': Assets.garageDoor,
|
||||
'GW': Assets.SmartGatewayIcon,
|
||||
'DL': Assets.DoorLockIcon,
|
||||
'WL': Assets.waterLeakSensor,
|
||||
'WH': Assets.waterHeater,
|
||||
'AC': Assets.ac,
|
||||
'CPS': Assets.presenceSensor,
|
||||
'PC': Assets.powerClamp,
|
||||
'WPS': Assets.presenceSensor,
|
||||
'DS': Assets.doorSensor
|
||||
};
|
||||
|
||||
return iconMapping[prodType] ?? Assets.presenceSensor;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProductModel(uuid: $uuid, catName: $catName, prodId: $prodId, prodType: $prodType, name: $name, icon: $icon)';
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
class SelectedProduct {
|
||||
final String productId;
|
||||
int count;
|
||||
|
||||
SelectedProduct({required this.productId, required this.count});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'productId': productId,
|
||||
'count': count,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SelectedProduct(productId: $productId, count: $count)';
|
||||
}
|
||||
}
|
15
lib/pages/spaces_management/model/space_data_model.dart
Normal file
@ -0,0 +1,15 @@
|
||||
import 'dart:ui';
|
||||
|
||||
class SpaceData {
|
||||
final String name;
|
||||
final String icon;
|
||||
Offset position;
|
||||
bool isHovered;
|
||||
|
||||
SpaceData({
|
||||
required this.name,
|
||||
required this.icon,
|
||||
required this.position,
|
||||
this.isHovered = false,
|
||||
});
|
||||
}
|
116
lib/pages/spaces_management/model/space_model.dart
Normal file
@ -0,0 +1,116 @@
|
||||
import 'dart:ui';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/connection_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
enum SpaceStatus { newSpace, modified, unchanged, deleted }
|
||||
|
||||
class SpaceModel {
|
||||
String? uuid;
|
||||
String? icon;
|
||||
final String? spaceTuyaUuid;
|
||||
String name;
|
||||
final bool isPrivate;
|
||||
final String? invitationCode;
|
||||
SpaceModel? parent;
|
||||
final CommunityModel? community;
|
||||
List<SpaceModel> children;
|
||||
Offset position;
|
||||
bool isHovered;
|
||||
SpaceStatus status;
|
||||
List<SelectedProduct> selectedProducts;
|
||||
String internalId;
|
||||
|
||||
List<Connection> outgoingConnections = []; // Connections from this space
|
||||
Connection? incomingConnection; // Connections to this space
|
||||
|
||||
SpaceModel({
|
||||
this.uuid,
|
||||
String? internalId,
|
||||
this.spaceTuyaUuid,
|
||||
required this.icon,
|
||||
required this.name,
|
||||
required this.isPrivate,
|
||||
this.invitationCode,
|
||||
this.parent,
|
||||
this.community,
|
||||
required this.children,
|
||||
required this.position,
|
||||
this.isHovered = false,
|
||||
this.incomingConnection,
|
||||
this.status = SpaceStatus.unchanged,
|
||||
this.selectedProducts = const [],
|
||||
}) : internalId = internalId ?? const Uuid().v4();
|
||||
|
||||
factory SpaceModel.fromJson(Map<String, dynamic> json, {String? parentInternalId}) {
|
||||
final String internalId = json['internalId'] ?? const Uuid().v4();
|
||||
|
||||
final List<SpaceModel> children = json['children'] != null
|
||||
? (json['children'] as List).map((childJson) {
|
||||
return SpaceModel.fromJson(
|
||||
childJson,
|
||||
parentInternalId: internalId,
|
||||
);
|
||||
}).toList()
|
||||
: [];
|
||||
|
||||
return SpaceModel(
|
||||
internalId: internalId,
|
||||
uuid: json['uuid'] ?? '',
|
||||
spaceTuyaUuid: json['spaceTuyaUuid'],
|
||||
name: json['spaceName'],
|
||||
isPrivate: json['isPrivate'] ?? false,
|
||||
invitationCode: json['invitationCode'],
|
||||
parent: parentInternalId != null
|
||||
? SpaceModel(
|
||||
internalId: parentInternalId,
|
||||
uuid: json['parent']?['uuid'],
|
||||
spaceTuyaUuid: json['parent']?['spaceTuyaUuid'],
|
||||
name: json['parent']?['spaceName'] ?? '',
|
||||
isPrivate: json['parent']?['isPrivate'] ?? false,
|
||||
invitationCode: json['parent']?['invitationCode'],
|
||||
children: [],
|
||||
position: Offset(json['parent']?['x'] ?? 0, json['parent']?['y'] ?? 0),
|
||||
icon: json['parent']?['icon'] ?? Assets.location,
|
||||
)
|
||||
: null,
|
||||
community: json['community'] != null ? CommunityModel.fromJson(json['community']) : null,
|
||||
children: children,
|
||||
icon: json['icon'] ?? Assets.location,
|
||||
position: Offset(json['x'] ?? 0, json['y'] ?? 0),
|
||||
isHovered: false,
|
||||
selectedProducts: json['spaceProducts'] != null
|
||||
? (json['spaceProducts'] as List).map((product) {
|
||||
return SelectedProduct(
|
||||
productId: product['product']['uuid'],
|
||||
count: product['productCount'],
|
||||
);
|
||||
}).toList()
|
||||
: [],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'uuid': uuid ?? '',
|
||||
'spaceTuyaUuid': spaceTuyaUuid,
|
||||
'name': name,
|
||||
'isPrivate': isPrivate,
|
||||
'invitationCode': invitationCode,
|
||||
'parent': parent?.uuid,
|
||||
'community': community?.toMap(),
|
||||
'children': children.map((child) => child.toMap()).toList(),
|
||||
'icon': icon,
|
||||
'position': {'dx': position.dx, 'dy': position.dy},
|
||||
'isHovered': isHovered,
|
||||
'outgoingConnections': outgoingConnections.map((c) => c.toMap()).toList(),
|
||||
'incomingConnection': incomingConnection?.toMap(),
|
||||
};
|
||||
}
|
||||
|
||||
void addOutgoingConnection(Connection connection) {
|
||||
outgoingConnections.add(connection);
|
||||
}
|
||||
}
|
39
lib/pages/spaces_management/model/space_response_model.dart
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
import 'space_model.dart';
|
||||
|
||||
class SpacesResponse {
|
||||
final List<SpaceModel> data;
|
||||
final String message;
|
||||
final int page;
|
||||
final int size;
|
||||
final int totalItem;
|
||||
final int totalPage;
|
||||
final bool hasNext;
|
||||
final bool hasPrevious;
|
||||
|
||||
SpacesResponse({
|
||||
required this.data,
|
||||
required this.message,
|
||||
required this.page,
|
||||
required this.size,
|
||||
required this.totalItem,
|
||||
required this.totalPage,
|
||||
required this.hasNext,
|
||||
required this.hasPrevious,
|
||||
});
|
||||
|
||||
factory SpacesResponse.fromJson(Map<String, dynamic> json) {
|
||||
return SpacesResponse(
|
||||
data: (json['data'] as List)
|
||||
.map((jsonItem) => SpaceModel.fromJson(jsonItem))
|
||||
.toList(),
|
||||
message: json['message'],
|
||||
page: json['page'],
|
||||
size: json['size'],
|
||||
totalItem: json['totalItem'],
|
||||
totalPage: json['totalPage'],
|
||||
hasNext: json['hasNext'],
|
||||
hasPrevious: json['hasPrevious'],
|
||||
);
|
||||
}
|
||||
}
|
85
lib/pages/spaces_management/view/spaces_management_page.dart
Normal file
@ -0,0 +1,85 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_state.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/loaded_space_widget.dart';
|
||||
import 'package:syncrow_web/services/product_api.dart';
|
||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||
|
||||
class SpaceManagementPage extends StatefulWidget {
|
||||
const SpaceManagementPage({super.key});
|
||||
|
||||
@override
|
||||
SpaceManagementPageState createState() => SpaceManagementPageState();
|
||||
}
|
||||
|
||||
class SpaceManagementPageState extends State<SpaceManagementPage> {
|
||||
CommunityModel? selectedCommunity;
|
||||
SpaceModel? selectedSpace;
|
||||
final CommunitySpaceManagementApi _api = CommunitySpaceManagementApi();
|
||||
final ProductApi _productApi = ProductApi();
|
||||
Map<String, List<SpaceModel>> communitySpaces = {};
|
||||
List<ProductModel> products = [];
|
||||
bool isProductDataLoaded = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
SpaceManagementBloc(_api, _productApi)..add(LoadCommunityAndSpacesEvent()),
|
||||
child: WebScaffold(
|
||||
appBarTitle: Text('Space Management', style: Theme.of(context).textTheme.headlineLarge),
|
||||
enableMenuSidebar: false,
|
||||
rightBody: const NavigateHomeGridView(),
|
||||
scaffoldBody:
|
||||
BlocBuilder<SpaceManagementBloc, SpaceManagementState>(builder: (context, state) {
|
||||
if (state is SpaceManagementLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is SpaceManagementLoaded) {
|
||||
int selectedIndex = state.communities.indexWhere(
|
||||
(community) => community.uuid == selectedCommunity?.uuid,
|
||||
);
|
||||
if (selectedIndex != -1) {
|
||||
selectedCommunity = state.communities[selectedIndex];
|
||||
} else if (state.selectedCommunity != null) {
|
||||
selectedCommunity = state.selectedCommunity;
|
||||
} else {
|
||||
selectedCommunity = null;
|
||||
selectedSpace = null;
|
||||
}
|
||||
return LoadedSpaceView(
|
||||
communities: state.communities,
|
||||
selectedCommunity: selectedCommunity,
|
||||
selectedSpace: selectedSpace,
|
||||
products: state.products,
|
||||
onCommunitySelected: (community) {
|
||||
setState(() {
|
||||
selectedCommunity = community;
|
||||
});
|
||||
},
|
||||
onSpaceSelected: (space) {
|
||||
setState(() {
|
||||
selectedSpace = space;
|
||||
});
|
||||
},
|
||||
);
|
||||
} else if (state is SpaceManagementError) {
|
||||
return Center(child: Text('Error: ${state.errorMessage}'));
|
||||
}
|
||||
return Container();
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
218
lib/pages/spaces_management/widgets/add_device_type_widget.dart
Normal file
@ -0,0 +1,218 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/counter_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class AddDeviceWidget extends StatefulWidget {
|
||||
final List<ProductModel>? products;
|
||||
final ValueChanged<List<SelectedProduct>>? onProductsSelected;
|
||||
final List<SelectedProduct>? initialSelectedProducts;
|
||||
|
||||
const AddDeviceWidget({
|
||||
super.key,
|
||||
this.products,
|
||||
this.initialSelectedProducts,
|
||||
this.onProductsSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
_AddDeviceWidgetState createState() => _AddDeviceWidgetState();
|
||||
}
|
||||
|
||||
class _AddDeviceWidgetState extends State<AddDeviceWidget> {
|
||||
late final ScrollController _scrollController;
|
||||
late List<SelectedProduct> productCounts;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_scrollController = ScrollController();
|
||||
productCounts =
|
||||
widget.initialSelectedProducts != null ? List.from(widget.initialSelectedProducts!) : [];
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = MediaQuery.of(context).size;
|
||||
|
||||
// Adjust the GridView properties based on screen width
|
||||
final crossAxisCount = size.width > 1200
|
||||
? 8
|
||||
: size.width > 800
|
||||
? 5
|
||||
: 3;
|
||||
|
||||
return AlertDialog(
|
||||
title: const Text('Add Devices'),
|
||||
backgroundColor: ColorsManager.whiteColors,
|
||||
content: SingleChildScrollView(
|
||||
child: Container(
|
||||
width: size.width * 0.9,
|
||||
height: size.height * 0.65,
|
||||
color: ColorsManager.textFieldGreyColor,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||
child: Scrollbar(
|
||||
controller: _scrollController,
|
||||
thumbVisibility: false,
|
||||
child: GridView.builder(
|
||||
shrinkWrap: true,
|
||||
controller: _scrollController,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: crossAxisCount,
|
||||
mainAxisSpacing: 6,
|
||||
crossAxisSpacing: 4,
|
||||
childAspectRatio: .8,
|
||||
),
|
||||
itemCount: widget.products?.length ?? 0,
|
||||
itemBuilder: (context, index) {
|
||||
final product = widget.products![index];
|
||||
return _buildDeviceTypeTile(product, size);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_buildActionButton('Cancel', ColorsManager.boxColor, ColorsManager.blackColor, () {
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
_buildActionButton('Continue', ColorsManager.secondaryColor, Colors.white, () {
|
||||
Navigator.of(context).pop();
|
||||
if (widget.onProductsSelected != null) {
|
||||
widget.onProductsSelected!(productCounts);
|
||||
}
|
||||
}),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDeviceTypeTile(ProductModel product, Size size) {
|
||||
final selectedProduct = productCounts.firstWhere(
|
||||
(p) => p.productId == product.uuid,
|
||||
orElse: () => SelectedProduct(productId: product.uuid, count: 0),
|
||||
);
|
||||
|
||||
return SizedBox(
|
||||
width: size.width * 0.12,
|
||||
height: size.height * 0.15,
|
||||
child: Card(
|
||||
elevation: 2,
|
||||
color: ColorsManager.whiteColors,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
_buildDeviceIcon(product, size),
|
||||
const SizedBox(height: 4),
|
||||
_buildDeviceName(product, size),
|
||||
const SizedBox(height: 4),
|
||||
CounterWidget(
|
||||
initialCount: selectedProduct.count,
|
||||
onCountChanged: (newCount) {
|
||||
setState(() {
|
||||
if (newCount > 0) {
|
||||
if (!productCounts.contains(selectedProduct)) {
|
||||
productCounts
|
||||
.add(SelectedProduct(productId: product.uuid, count: newCount));
|
||||
} else {
|
||||
selectedProduct.count = newCount;
|
||||
}
|
||||
} else {
|
||||
productCounts.removeWhere((p) => p.productId == product.uuid);
|
||||
}
|
||||
|
||||
if (widget.onProductsSelected != null) {
|
||||
widget.onProductsSelected!(productCounts);
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDeviceIcon(ProductModel product, Size size) {
|
||||
return Container(
|
||||
height: size.width > 800 ? 50 : 40,
|
||||
width: size.width > 800 ? 50 : 40,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: ColorsManager.textFieldGreyColor,
|
||||
border: Border.all(
|
||||
color: ColorsManager.neutralGray,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
product.icon ?? Assets.sensors,
|
||||
width: size.width > 800 ? 30 : 20,
|
||||
height: size.width > 800 ? 30 : 20,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDeviceName(ProductModel product, Size size) {
|
||||
return SizedBox(
|
||||
height: size.width > 800 ? 35 : 25,
|
||||
child: Text(
|
||||
product.name ?? '',
|
||||
style: context.textTheme.bodySmall?.copyWith(color: ColorsManager.blackColor),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildActionButton(
|
||||
String label,
|
||||
Color backgroundColor,
|
||||
Color foregroundColor,
|
||||
VoidCallback onPressed,
|
||||
) {
|
||||
return SizedBox(
|
||||
width: 120,
|
||||
child: DefaultButton(
|
||||
onPressed: onPressed,
|
||||
backgroundColor: backgroundColor,
|
||||
foregroundColor: foregroundColor,
|
||||
child: Text(label),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/create_community_dialog.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class BlankCommunityWidget extends StatelessWidget {
|
||||
const BlankCommunityWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
color: ColorsManager.whiteColors, // Parent container with white background
|
||||
child: GridView.builder(
|
||||
padding: const EdgeInsets.only(left: 40.0, top: 20.0),
|
||||
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
maxCrossAxisExtent: 400, // Each item's width will be 400 or less
|
||||
mainAxisSpacing: 10, // Spacing between items
|
||||
crossAxisSpacing: 10, // Spacing between items
|
||||
childAspectRatio: 2.0, // Aspect ratio for width:height (e.g., 300:150 = 2.0)
|
||||
),
|
||||
itemCount: 1, // Only one item
|
||||
itemBuilder: (context, index) {
|
||||
return GestureDetector(
|
||||
onTap: () => _showCreateCommunityDialog(context),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center, // Center align the content
|
||||
children: [
|
||||
Expanded(
|
||||
child: AspectRatio(
|
||||
aspectRatio: 2.0,
|
||||
child: Container(
|
||||
decoration: ShapeDecoration(
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: 4,
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
color: ColorsManager.borderColor,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 9), // Space between item and text
|
||||
Text('Blank', // Text below the item
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
)),
|
||||
],
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showCreateCommunityDialog(BuildContext parentContext) {
|
||||
showDialog(
|
||||
context: parentContext,
|
||||
builder: (context) => CreateCommunityDialog(
|
||||
onCreateCommunity: (String communityName, String description) {
|
||||
parentContext.read<SpaceManagementBloc>().add(
|
||||
CreateCommunityEvent(
|
||||
name: communityName,
|
||||
description: description,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class CommunityStructureHeader extends StatelessWidget {
|
||||
final String? communityName;
|
||||
final bool isEditingName;
|
||||
final bool isSave;
|
||||
final TextEditingController nameController;
|
||||
final VoidCallback onSave;
|
||||
final VoidCallback onDelete;
|
||||
final VoidCallback onEditName;
|
||||
final ValueChanged<String> onNameSubmitted;
|
||||
|
||||
const CommunityStructureHeader({
|
||||
Key? key,
|
||||
required this.communityName,
|
||||
required this.isSave,
|
||||
required this.isEditingName,
|
||||
required this.nameController,
|
||||
required this.onSave,
|
||||
required this.onDelete,
|
||||
required this.onEditName,
|
||||
required this.onNameSubmitted,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: ColorsManager.shadowBlackColor,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildCommunityInfo(theme, screenWidth),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCommunityInfo(ThemeData theme, double screenWidth) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Community Structure',
|
||||
style: theme.textTheme.headlineLarge?.copyWith(color: ColorsManager.blackColor),
|
||||
),
|
||||
if (communityName != null)
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
if (!isEditingName)
|
||||
Flexible(
|
||||
child: Text(
|
||||
communityName!,
|
||||
style:
|
||||
theme.textTheme.bodyLarge?.copyWith(color: ColorsManager.blackColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
if (isEditingName)
|
||||
SizedBox(
|
||||
width: screenWidth * 0.3,
|
||||
child: TextField(
|
||||
controller: nameController,
|
||||
decoration: const InputDecoration(
|
||||
border: InputBorder.none,
|
||||
isDense: true,
|
||||
),
|
||||
style:
|
||||
theme.textTheme.bodyLarge?.copyWith(color: ColorsManager.blackColor),
|
||||
onSubmitted: onNameSubmitted,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
GestureDetector(
|
||||
onTap: onEditName,
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconEdit,
|
||||
width: 16,
|
||||
height: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isSave) ...[
|
||||
const SizedBox(width: 8),
|
||||
_buildActionButtons(theme),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildActionButtons(ThemeData theme) {
|
||||
return Wrap(
|
||||
alignment: WrapAlignment.end,
|
||||
spacing: 10,
|
||||
children: [
|
||||
_buildButton(
|
||||
label: "Save",
|
||||
icon: const Icon(Icons.save, size: 18, color: ColorsManager.spaceColor),
|
||||
onPressed: onSave,
|
||||
theme: theme),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildButton(
|
||||
{required String label,
|
||||
required Widget icon,
|
||||
required VoidCallback onPressed,
|
||||
required ThemeData theme}) {
|
||||
const double buttonHeight = 30;
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 80, minHeight: buttonHeight),
|
||||
child: DefaultButton(
|
||||
onPressed: onPressed,
|
||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||
foregroundColor: ColorsManager.blackColor,
|
||||
borderRadius: 8.0,
|
||||
padding: 2.0,
|
||||
height: buttonHeight,
|
||||
elevation: 0,
|
||||
borderColor: Colors.grey.shade300,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
icon,
|
||||
const SizedBox(width: 5),
|
||||
Flexible(
|
||||
child: Text(
|
||||
label,
|
||||
style: theme.textTheme.bodySmall?.copyWith(color: ColorsManager.blackColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,525 @@
|
||||
// Flutter imports
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
// Syncrow project imports
|
||||
import 'package:syncrow_web/pages/common/buttons/add_space_button.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/connection_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/blank_community_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/community_structure_header_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/create_space_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/curved_line_painter.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/space_card_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/space_container_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CommunityStructureArea extends StatefulWidget {
|
||||
final CommunityModel? selectedCommunity;
|
||||
SpaceModel? selectedSpace;
|
||||
final List<ProductModel>? products;
|
||||
final ValueChanged<SpaceModel?>? onSpaceSelected;
|
||||
|
||||
final List<SpaceModel> spaces;
|
||||
|
||||
CommunityStructureArea({
|
||||
this.selectedCommunity,
|
||||
this.selectedSpace,
|
||||
this.products,
|
||||
required this.spaces,
|
||||
this.onSpaceSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
_CommunityStructureAreaState createState() => _CommunityStructureAreaState();
|
||||
}
|
||||
|
||||
class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
||||
double canvasWidth = 1000;
|
||||
double canvasHeight = 1000;
|
||||
List<SpaceModel> spaces = [];
|
||||
List<Connection> connections = [];
|
||||
late TextEditingController _nameController;
|
||||
bool isEditingName = false;
|
||||
late TransformationController _transformationController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
spaces = widget.spaces.isNotEmpty ? flattenSpaces(widget.spaces) : [];
|
||||
connections = widget.spaces.isNotEmpty ? createConnections(widget.spaces) : [];
|
||||
_adjustCanvasSizeForSpaces();
|
||||
_nameController = TextEditingController(
|
||||
text: widget.selectedCommunity?.name ?? '',
|
||||
);
|
||||
_transformationController = TransformationController();
|
||||
if (widget.selectedSpace != null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_moveToSpace(widget.selectedSpace!);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_nameController.dispose();
|
||||
_transformationController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant CommunityStructureArea oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
|
||||
if (oldWidget.spaces != widget.spaces) {
|
||||
setState(() {
|
||||
spaces = widget.spaces.isNotEmpty ? flattenSpaces(widget.spaces) : [];
|
||||
connections = widget.spaces.isNotEmpty ? createConnections(widget.spaces) : [];
|
||||
_adjustCanvasSizeForSpaces();
|
||||
});
|
||||
}
|
||||
|
||||
if (widget.selectedSpace != oldWidget.selectedSpace && widget.selectedSpace != null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_moveToSpace(widget.selectedSpace!);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.selectedCommunity == null) {
|
||||
return BlankCommunityWidget();
|
||||
}
|
||||
|
||||
Size screenSize = MediaQuery.of(context).size;
|
||||
return Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
_deselectSpace();
|
||||
},
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
left: BorderSide(color: ColorsManager.whiteColors, width: 1.0),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CommunityStructureHeader(
|
||||
communityName: widget.selectedCommunity?.name,
|
||||
isSave: isSave(spaces),
|
||||
isEditingName: isEditingName,
|
||||
nameController: _nameController,
|
||||
onSave: _saveSpaces,
|
||||
onDelete: _onDelete,
|
||||
onEditName: () {
|
||||
setState(() {
|
||||
isEditingName = !isEditingName;
|
||||
if (isEditingName) {
|
||||
_nameController.text = widget.selectedCommunity?.name ?? '';
|
||||
}
|
||||
});
|
||||
},
|
||||
onNameSubmitted: (value) {
|
||||
context.read<SpaceManagementBloc>().add(
|
||||
UpdateCommunityEvent(
|
||||
communityUuid: widget.selectedCommunity!.uuid,
|
||||
name: value,
|
||||
),
|
||||
);
|
||||
setState(() {
|
||||
widget.selectedCommunity?.name = value;
|
||||
isEditingName = false;
|
||||
});
|
||||
},
|
||||
),
|
||||
Flexible(
|
||||
child: Stack(
|
||||
children: [
|
||||
InteractiveViewer(
|
||||
transformationController: _transformationController,
|
||||
boundaryMargin: EdgeInsets.all(500),
|
||||
minScale: 0.5,
|
||||
maxScale: 3.0,
|
||||
constrained: false,
|
||||
child: Container(
|
||||
width: canvasWidth,
|
||||
height: canvasHeight,
|
||||
child: Stack(
|
||||
children: [
|
||||
for (var connection in connections)
|
||||
Opacity(
|
||||
opacity:
|
||||
_isHighlightedConnection(connection) ? 1.0 : 0.3, // Adjust opacity
|
||||
child: CustomPaint(painter: CurvedLinePainter([connection])),
|
||||
),
|
||||
for (var entry in spaces.asMap().entries)
|
||||
if (entry.value.status != SpaceStatus.deleted)
|
||||
Positioned(
|
||||
left: entry.value.position.dx,
|
||||
top: entry.value.position.dy,
|
||||
child: SpaceCardWidget(
|
||||
index: entry.key,
|
||||
onButtonTap: (int index, Offset newPosition, String direction) {
|
||||
_showCreateSpaceDialog(
|
||||
screenSize,
|
||||
position: spaces[index].position + newPosition,
|
||||
parentIndex: index,
|
||||
direction: direction,
|
||||
);
|
||||
},
|
||||
position: entry.value.position,
|
||||
isHovered: entry.value.isHovered,
|
||||
screenSize: screenSize,
|
||||
onHoverChanged: _handleHoverChanged,
|
||||
onPositionChanged: (newPosition) {
|
||||
_updateNodePosition(entry.value, newPosition);
|
||||
},
|
||||
buildSpaceContainer: (int index) {
|
||||
final bool isHighlighted = _isHighlightedSpace(spaces[index]);
|
||||
|
||||
return Opacity(
|
||||
opacity: isHighlighted ? 1.0 : 0.3,
|
||||
child: SpaceContainerWidget(
|
||||
index: index,
|
||||
onDoubleTap: () {
|
||||
_showEditSpaceDialog(spaces[index]);
|
||||
},
|
||||
onTap: () {
|
||||
_selectSpace(spaces[index]);
|
||||
},
|
||||
icon: spaces[index].icon ?? '',
|
||||
name: spaces[index].name,
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (spaces.isEmpty)
|
||||
Center(
|
||||
child: AddSpaceButton(
|
||||
onTap: () {
|
||||
_showCreateSpaceDialog(screenSize,
|
||||
canvasHeight: canvasHeight, canvasWidth: canvasWidth);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
void _updateNodePosition(SpaceModel node, Offset newPosition) {
|
||||
setState(() {
|
||||
node.position = newPosition;
|
||||
if (node.status != SpaceStatus.newSpace) {
|
||||
node.status = SpaceStatus.modified; // Mark as modified
|
||||
}
|
||||
if (node.position.dx >= canvasWidth - 200) {
|
||||
canvasWidth += 200;
|
||||
}
|
||||
if (node.position.dy >= canvasHeight - 200) {
|
||||
canvasHeight += 200;
|
||||
}
|
||||
if (node.position.dx <= 200) {
|
||||
double shiftAmount = 200;
|
||||
canvasWidth += shiftAmount;
|
||||
for (var n in spaces) {
|
||||
n.position = Offset(n.position.dx + shiftAmount, n.position.dy);
|
||||
}
|
||||
}
|
||||
if (node.position.dy < 0) {
|
||||
node.position = Offset(node.position.dx, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _adjustCanvasSizeForSpaces() {
|
||||
for (var space in spaces) {
|
||||
if (space.position.dx >= canvasWidth - 200) {
|
||||
canvasWidth = space.position.dx + 200;
|
||||
}
|
||||
|
||||
if (space.position.dy >= canvasHeight - 200) {
|
||||
canvasHeight = space.position.dy + 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _showCreateSpaceDialog(Size screenSize,
|
||||
{Offset? position,
|
||||
int? parentIndex,
|
||||
String? direction,
|
||||
double? canvasWidth,
|
||||
double? canvasHeight}) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CreateSpaceDialog(
|
||||
products: widget.products,
|
||||
parentSpace: parentIndex != null? spaces[parentIndex] : null,
|
||||
onCreateSpace: (String name, String icon, List<SelectedProduct> selectedProducts) {
|
||||
setState(() {
|
||||
// Set the first space in the center or use passed position
|
||||
|
||||
Offset centerPosition = position ?? _getCenterPosition(screenSize);
|
||||
SpaceModel newSpace = SpaceModel(
|
||||
name: name,
|
||||
icon: icon,
|
||||
position: centerPosition,
|
||||
isPrivate: false,
|
||||
children: [],
|
||||
status: SpaceStatus.newSpace,
|
||||
selectedProducts: selectedProducts);
|
||||
|
||||
if (parentIndex != null && direction != null) {
|
||||
SpaceModel parentSpace = spaces[parentIndex];
|
||||
parentSpace.internalId = spaces[parentIndex].internalId;
|
||||
newSpace.parent = parentSpace;
|
||||
final newConnection = Connection(
|
||||
startSpace: parentSpace,
|
||||
endSpace: newSpace,
|
||||
direction: direction,
|
||||
);
|
||||
connections.add(newConnection);
|
||||
newSpace.incomingConnection = newConnection;
|
||||
parentSpace.addOutgoingConnection(newConnection);
|
||||
parentSpace.children.add(newSpace);
|
||||
}
|
||||
|
||||
spaces.add(newSpace);
|
||||
_updateNodePosition(newSpace, newSpace.position);
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _showEditSpaceDialog(SpaceModel space) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CreateSpaceDialog(
|
||||
products: widget.products,
|
||||
name: space.name,
|
||||
icon: space.icon,
|
||||
isEdit: true,
|
||||
selectedProducts: space.selectedProducts,
|
||||
onCreateSpace: (String name, String icon, List<SelectedProduct> selectedProducts) {
|
||||
setState(() {
|
||||
// Update the space's properties
|
||||
space.name = name;
|
||||
space.icon = icon;
|
||||
space.selectedProducts = selectedProducts;
|
||||
|
||||
if (space.status != SpaceStatus.newSpace) {
|
||||
space.status = SpaceStatus.modified; // Mark as modified
|
||||
}
|
||||
});
|
||||
},
|
||||
// Pre-fill the dialog with current space data
|
||||
key: Key(space.name), // Add a unique key to ensure dialog refresh
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _handleHoverChanged(int index, bool isHovered) {
|
||||
setState(() {
|
||||
spaces[index].isHovered = isHovered;
|
||||
});
|
||||
}
|
||||
|
||||
List<SpaceModel> flattenSpaces(List<SpaceModel> spaces) {
|
||||
List<SpaceModel> result = [];
|
||||
|
||||
void flatten(SpaceModel space) {
|
||||
if (space.status == SpaceStatus.deleted) return;
|
||||
|
||||
result.add(space);
|
||||
|
||||
for (var child in space.children) {
|
||||
flatten(child);
|
||||
}
|
||||
}
|
||||
|
||||
for (var space in spaces) {
|
||||
flatten(space);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
List<Connection> createConnections(List<SpaceModel> spaces) {
|
||||
List<Connection> connections = [];
|
||||
|
||||
void addConnections(SpaceModel parent, String direction) {
|
||||
if (parent.status == SpaceStatus.deleted) return;
|
||||
|
||||
for (var child in parent.children) {
|
||||
if (child.status == SpaceStatus.deleted) continue;
|
||||
|
||||
connections.add(
|
||||
Connection(
|
||||
startSpace: parent,
|
||||
endSpace: child,
|
||||
direction: child.incomingConnection?.direction ?? "down",
|
||||
),
|
||||
);
|
||||
|
||||
// Recursively process the child's children
|
||||
addConnections(child, direction);
|
||||
}
|
||||
}
|
||||
|
||||
for (var space in spaces) {
|
||||
addConnections(space, "down");
|
||||
}
|
||||
|
||||
return connections;
|
||||
}
|
||||
|
||||
void _saveSpaces() {
|
||||
if (widget.selectedCommunity == null) {
|
||||
debugPrint("No community selected for saving spaces.");
|
||||
return;
|
||||
}
|
||||
|
||||
List<SpaceModel> spacesToSave = spaces.where((space) {
|
||||
return space.status == SpaceStatus.newSpace ||
|
||||
space.status == SpaceStatus.modified ||
|
||||
space.status == SpaceStatus.deleted;
|
||||
}).toList();
|
||||
|
||||
if (spacesToSave.isEmpty) {
|
||||
debugPrint("No new or modified spaces to save.");
|
||||
return;
|
||||
}
|
||||
|
||||
String communityUuid = widget.selectedCommunity!.uuid;
|
||||
|
||||
context.read<SpaceManagementBloc>().add(SaveSpacesEvent(
|
||||
spaces: spacesToSave,
|
||||
communityUuid: communityUuid,
|
||||
));
|
||||
}
|
||||
|
||||
void _onDelete() {
|
||||
if (widget.selectedCommunity != null &&
|
||||
widget.selectedCommunity?.uuid != null &&
|
||||
widget.selectedSpace == null) {
|
||||
context.read<SpaceManagementBloc>().add(DeleteCommunityEvent(
|
||||
communityUuid: widget.selectedCommunity!.uuid,
|
||||
));
|
||||
}
|
||||
if (widget.selectedSpace != null) {
|
||||
setState(() {
|
||||
for (var space in spaces) {
|
||||
if (space.uuid == widget.selectedSpace?.uuid) {
|
||||
space.status = SpaceStatus.deleted;
|
||||
_markChildrenAsDeleted(space);
|
||||
}
|
||||
}
|
||||
_removeConnectionsForDeletedSpaces();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _markChildrenAsDeleted(SpaceModel parent) {
|
||||
for (var child in parent.children) {
|
||||
child.status = SpaceStatus.deleted;
|
||||
_markChildrenAsDeleted(child);
|
||||
}
|
||||
}
|
||||
|
||||
void _removeConnectionsForDeletedSpaces() {
|
||||
connections.removeWhere((connection) {
|
||||
return connection.startSpace.status == SpaceStatus.deleted ||
|
||||
connection.endSpace.status == SpaceStatus.deleted;
|
||||
});
|
||||
}
|
||||
|
||||
void _moveToSpace(SpaceModel space) {
|
||||
final double viewportWidth = MediaQuery.of(context).size.width;
|
||||
final double viewportHeight = MediaQuery.of(context).size.height;
|
||||
|
||||
final double dx = -space.position.dx + (viewportWidth / 2) - 400;
|
||||
final double dy = -space.position.dy + (viewportHeight / 2) - 300;
|
||||
|
||||
_transformationController.value = Matrix4.identity()
|
||||
..translate(dx, dy)
|
||||
..scale(1.2);
|
||||
}
|
||||
|
||||
void _selectSpace(SpaceModel space) {
|
||||
setState(() {
|
||||
widget.selectedSpace = space;
|
||||
});
|
||||
|
||||
if (widget.onSpaceSelected != null) {
|
||||
widget.onSpaceSelected!(space);
|
||||
}
|
||||
}
|
||||
|
||||
bool _isHighlightedSpace(SpaceModel space) {
|
||||
if (widget.selectedSpace == null) return true;
|
||||
if (space == widget.selectedSpace) return true;
|
||||
if (widget.selectedSpace?.parent?.internalId == space.internalId) return true;
|
||||
if (widget.selectedSpace?.children != null) {
|
||||
for (var child in widget.selectedSpace!.children) {
|
||||
if (child.internalId == space.internalId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _deselectSpace() {
|
||||
if (widget.selectedSpace != null) {
|
||||
setState(() {
|
||||
widget.selectedSpace = null;
|
||||
});
|
||||
|
||||
if (widget.onSpaceSelected != null) {
|
||||
widget.onSpaceSelected!(null); // Notify parent that no space is selected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _isHighlightedConnection(Connection connection) {
|
||||
if (widget.selectedSpace == null) return true;
|
||||
|
||||
return connection.startSpace == widget.selectedSpace ||
|
||||
connection.endSpace == widget.selectedSpace;
|
||||
}
|
||||
|
||||
Offset _getCenterPosition(Size screenSize) {
|
||||
return Offset(
|
||||
screenSize.width / 2 - 260,
|
||||
screenSize.height / 2 - 200,
|
||||
);
|
||||
}
|
||||
|
||||
bool isSave(List<SpaceModel> spaces) {
|
||||
return spaces.isNotEmpty &&
|
||||
spaces.any((space) =>
|
||||
space.status == SpaceStatus.newSpace ||
|
||||
space.status == SpaceStatus.modified ||
|
||||
space.status == SpaceStatus.deleted);
|
||||
}
|
||||
}
|
35
lib/pages/spaces_management/widgets/community_tile.dart
Normal file
@ -0,0 +1,35 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/common/custom_expansion_tile.dart';
|
||||
|
||||
class CommunityTile extends StatelessWidget {
|
||||
final String title;
|
||||
final List<Widget>? children;
|
||||
final bool isExpanded;
|
||||
final bool isSelected;
|
||||
final Function(String, bool) onExpansionChanged;
|
||||
final Function() onItemSelected;
|
||||
|
||||
const CommunityTile({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.isExpanded,
|
||||
required this.onExpansionChanged,
|
||||
required this.onItemSelected,
|
||||
required this.isSelected,
|
||||
this.children,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomExpansionTile(
|
||||
title: title,
|
||||
initiallyExpanded: isExpanded,
|
||||
isSelected: isSelected,
|
||||
onExpansionChanged: (bool expanded) {
|
||||
onExpansionChanged(title, expanded);
|
||||
},
|
||||
onItemSelected: onItemSelected,
|
||||
children: children ?? [],
|
||||
);
|
||||
}
|
||||
}
|
79
lib/pages/spaces_management/widgets/counter_widget.dart
Normal file
@ -0,0 +1,79 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CounterWidget extends StatefulWidget {
|
||||
final int initialCount;
|
||||
final ValueChanged<int> onCountChanged;
|
||||
|
||||
const CounterWidget({
|
||||
Key? key,
|
||||
this.initialCount = 0,
|
||||
required this.onCountChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CounterWidget> createState() => _CounterWidgetState();
|
||||
}
|
||||
|
||||
class _CounterWidgetState extends State<CounterWidget> {
|
||||
late int _counter;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_counter = widget.initialCount;
|
||||
}
|
||||
|
||||
void _incrementCounter() {
|
||||
setState(() {
|
||||
_counter++;
|
||||
widget.onCountChanged(_counter);
|
||||
});
|
||||
}
|
||||
|
||||
void _decrementCounter() {
|
||||
setState(() {
|
||||
if (_counter > 0) {
|
||||
_counter--;
|
||||
widget.onCountChanged(_counter);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.counterBackgroundColor,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildCounterButton(Icons.remove, _decrementCounter),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'$_counter',
|
||||
style: theme.textTheme.bodyLarge?.copyWith(color: ColorsManager.spaceColor),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildCounterButton(Icons.add, _incrementCounter),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCounterButton(IconData icon, VoidCallback onPressed) {
|
||||
return GestureDetector(
|
||||
onTap: onPressed,
|
||||
child: Icon(
|
||||
icon,
|
||||
color: ColorsManager.spaceColor,
|
||||
size: 18,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
65
lib/pages/spaces_management/widgets/curved_line_painter.dart
Normal file
@ -0,0 +1,65 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/connection_model.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CurvedLinePainter extends CustomPainter {
|
||||
final List<Connection> connections;
|
||||
|
||||
CurvedLinePainter(this.connections);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()
|
||||
..color = ColorsManager.blackColor
|
||||
..strokeWidth = 2
|
||||
..style = PaintingStyle.stroke;
|
||||
|
||||
// Ensure connections exist before painting
|
||||
if (connections.isEmpty) {
|
||||
return; // Nothing to paint if there are no connections
|
||||
}
|
||||
|
||||
for (var connection in connections) {
|
||||
// Ensure positions are valid before drawing lines
|
||||
if (connection.endSpace.position == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Offset start = connection.startSpace.position +
|
||||
const Offset(75, 60); // Center bottom of start space
|
||||
Offset end = connection.endSpace.position +
|
||||
const Offset(75, 0); // Center top of end space
|
||||
|
||||
if (connection.direction == 'down') {
|
||||
// Curved line for down connections
|
||||
final controlPoint = Offset((start.dx + end.dx) / 2, start.dy + 50);
|
||||
final path = Path()
|
||||
..moveTo(start.dx, start.dy)
|
||||
..quadraticBezierTo(controlPoint.dx, controlPoint.dy, end.dx, end.dy);
|
||||
canvas.drawPath(path, paint);
|
||||
} else if (connection.direction == 'right') {
|
||||
start = connection.startSpace.position +
|
||||
const Offset(150, 30); // Right center
|
||||
end = connection.endSpace.position + const Offset(0, 30); // Left center
|
||||
|
||||
canvas.drawLine(start, end, paint);
|
||||
} else if (connection.direction == 'left') {
|
||||
start =
|
||||
connection.startSpace.position + const Offset(0, 30); // Left center
|
||||
end = connection.endSpace.position +
|
||||
const Offset(150, 30); // Right center
|
||||
|
||||
canvas.drawLine(start, end, paint);
|
||||
}
|
||||
|
||||
final dotPaint = Paint()..color = ColorsManager.blackColor;
|
||||
canvas.drawCircle(start, 5, dotPaint); // Start dot
|
||||
canvas.drawCircle(end, 5, dotPaint); // End dot
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CreateCommunityDialog extends StatefulWidget {
|
||||
final Function(String name, String description) onCreateCommunity;
|
||||
|
||||
const CreateCommunityDialog({super.key, required this.onCreateCommunity});
|
||||
|
||||
@override
|
||||
CreateCommunityDialogState createState() => CreateCommunityDialogState();
|
||||
}
|
||||
|
||||
class CreateCommunityDialogState extends State<CreateCommunityDialog> {
|
||||
String enteredName = ''; // Store the entered community name
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
backgroundColor: Colors.transparent, // Transparent for shadow effect
|
||||
child: Stack(
|
||||
children: [
|
||||
// Background container with shadow and rounded corners
|
||||
Container(
|
||||
width: 490,
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.25),
|
||||
blurRadius: 20,
|
||||
spreadRadius: 5,
|
||||
offset: const Offset(0, 5),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Community Name',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
// Input field for the community name
|
||||
TextField(
|
||||
onChanged: (value) {
|
||||
enteredName = value; // Capture entered name
|
||||
},
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Please enter the community name',
|
||||
filled: true,
|
||||
fillColor: ColorsManager.boxColor,
|
||||
hintStyle: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: ColorsManager.grayBorder,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide: const BorderSide(color: ColorsManager.boxColor, width: 1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(color: ColorsManager.boxColor, width: 1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: const BorderSide(color: ColorsManager.boxColor, width: 1),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
// Action buttons
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
backgroundColor: ColorsManager.boxColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
child: const Text(
|
||||
'Cancel',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
if (enteredName.isNotEmpty) {
|
||||
widget.onCreateCommunity(
|
||||
enteredName,
|
||||
"",
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
backgroundColor: ColorsManager.secondaryColor,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,383 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/add_device_type_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/icon_selection_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/hoverable_button.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/constants/space_icon_const.dart';
|
||||
|
||||
class CreateSpaceDialog extends StatefulWidget {
|
||||
final Function(String, String, List<SelectedProduct> selectedProducts) onCreateSpace;
|
||||
final List<ProductModel>? products;
|
||||
final String? name;
|
||||
final String? icon;
|
||||
final bool isEdit;
|
||||
final List<SelectedProduct> selectedProducts;
|
||||
final SpaceModel? parentSpace;
|
||||
|
||||
const CreateSpaceDialog(
|
||||
{super.key,
|
||||
this.parentSpace,
|
||||
required this.onCreateSpace,
|
||||
this.products,
|
||||
this.name,
|
||||
this.icon,
|
||||
this.isEdit = false,
|
||||
this.selectedProducts = const []});
|
||||
|
||||
@override
|
||||
CreateSpaceDialogState createState() => CreateSpaceDialogState();
|
||||
}
|
||||
|
||||
class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
||||
String selectedIcon = Assets.location;
|
||||
String enteredName = '';
|
||||
List<SelectedProduct> selectedProducts = [];
|
||||
late TextEditingController nameController;
|
||||
bool isOkButtonEnabled = false;
|
||||
bool isNameFieldInvalid = false;
|
||||
bool isNameFieldExist = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
selectedIcon = widget.icon ?? Assets.location;
|
||||
nameController = TextEditingController(text: widget.name ?? '');
|
||||
selectedProducts = widget.selectedProducts.isNotEmpty ? widget.selectedProducts : [];
|
||||
isOkButtonEnabled = enteredName.isNotEmpty || nameController.text.isNotEmpty;
|
||||
}
|
||||
|
||||
@override
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
return AlertDialog(
|
||||
title: widget.isEdit ? const Text('Edit Space') : const Text('Create New Space'),
|
||||
backgroundColor: ColorsManager.whiteColors,
|
||||
content: SizedBox(
|
||||
width: screenWidth * 0.5, // Limit dialog width
|
||||
child: SingleChildScrollView(
|
||||
// Scrollable content to prevent overflow
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: screenWidth * 0.1, // Adjusted width
|
||||
height: screenWidth * 0.1, // Adjusted height
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
selectedIcon,
|
||||
width: screenWidth * 0.04,
|
||||
height: screenWidth * 0.04,
|
||||
),
|
||||
Positioned(
|
||||
top: 6,
|
||||
right: 6,
|
||||
child: InkWell(
|
||||
onTap: _showIconSelectionDialog,
|
||||
child: Container(
|
||||
width: screenWidth * 0.020,
|
||||
height: screenWidth * 0.020,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconEdit,
|
||||
width: screenWidth * 0.06,
|
||||
height: screenWidth * 0.06,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
// Ensure the text field expands responsively
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextField(
|
||||
controller: nameController,
|
||||
onChanged: (value) {
|
||||
enteredName = value.trim();
|
||||
setState(() {
|
||||
isNameFieldExist = false;
|
||||
isOkButtonEnabled = false;
|
||||
isNameFieldInvalid = value.isEmpty;
|
||||
|
||||
if (!isNameFieldInvalid) {
|
||||
if (widget.parentSpace?.children
|
||||
.any((child) => child.name == value) ??
|
||||
false) {
|
||||
isNameFieldExist = true;
|
||||
} else {
|
||||
isOkButtonEnabled = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Please enter the name',
|
||||
hintStyle: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: ColorsManager.lightGrayColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: ColorsManager.boxColor,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: isNameFieldInvalid || isNameFieldExist
|
||||
? ColorsManager.red
|
||||
: ColorsManager.boxColor,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: const BorderSide(
|
||||
color: ColorsManager.boxColor,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isNameFieldInvalid)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'*Space name should not be empty.',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
?.copyWith(color: ColorsManager.red),
|
||||
),
|
||||
),
|
||||
if (isNameFieldExist)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'*Name already exist',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
?.copyWith(color: ColorsManager.red),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (selectedProducts.isNotEmpty)
|
||||
_buildSelectedProductsButtons(widget.products ?? [])
|
||||
else
|
||||
DefaultButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AddDeviceWidget(
|
||||
products: widget.products,
|
||||
onProductsSelected: (selectedProductsMap) {
|
||||
setState(() {
|
||||
selectedProducts = selectedProductsMap;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||
foregroundColor: Colors.black,
|
||||
borderColor: ColorsManager.neutralGray,
|
||||
borderRadius: 16.0,
|
||||
padding: 10.0, // Reduced padding for smaller size
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.addIcon,
|
||||
width: screenWidth * 0.015, // Adjust icon size
|
||||
height: screenWidth * 0.015,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Add devices / Assign a space model',
|
||||
overflow: TextOverflow.ellipsis, // Prevent overflow
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: CancelButton(
|
||||
label: 'Cancel',
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
if (nameController.text.isEmpty) {
|
||||
setState(() {
|
||||
isNameFieldInvalid = true;
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
String newName = enteredName.isNotEmpty ? enteredName : (widget.name ?? '');
|
||||
if (newName.isNotEmpty) {
|
||||
widget.onCreateSpace(newName, selectedIcon, selectedProducts);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
}
|
||||
},
|
||||
borderRadius: 10,
|
||||
backgroundColor:
|
||||
isOkButtonEnabled ? ColorsManager.secondaryColor : ColorsManager.grayColor,
|
||||
foregroundColor: ColorsManager.whiteColors,
|
||||
child: const Text('OK'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _showIconSelectionDialog() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return IconSelectionDialog(
|
||||
spaceIconList: spaceIconList,
|
||||
onIconSelected: (String selectedIcon) {
|
||||
setState(() {
|
||||
this.selectedIcon = selectedIcon;
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSelectedProductsButtons(List<ProductModel> products) {
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
return Container(
|
||||
width: screenWidth * 0.6,
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.textFieldGreyColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: ColorsManager.neutralGray,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
for (var i = 0; i < selectedProducts.length; i++) ...[
|
||||
HoverableButton(
|
||||
iconPath: _mapIconToProduct(selectedProducts[i].productId, products),
|
||||
text: 'x${selectedProducts[i].count}',
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selectedProducts.remove(selectedProducts[i]);
|
||||
});
|
||||
// Handle button tap
|
||||
},
|
||||
),
|
||||
if (i < selectedProducts.length - 1)
|
||||
const SizedBox(width: 2), // Add space except after the last button
|
||||
],
|
||||
const SizedBox(width: 2),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AddDeviceWidget(
|
||||
products: widget.products,
|
||||
initialSelectedProducts: selectedProducts,
|
||||
onProductsSelected: (selectedProductsMap) {
|
||||
setState(() {
|
||||
selectedProducts = selectedProductsMap;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.add,
|
||||
color: ColorsManager.spaceColor,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _mapIconToProduct(String uuid, List<ProductModel> products) {
|
||||
// Find the product with the matching UUID
|
||||
final product = products.firstWhere(
|
||||
(product) => product.uuid == uuid,
|
||||
orElse: () => ProductModel(
|
||||
uuid: '',
|
||||
catName: '',
|
||||
prodId: '',
|
||||
prodType: '',
|
||||
name: '',
|
||||
icon: Assets.presenceSensor,
|
||||
),
|
||||
);
|
||||
|
||||
return product.icon ?? Assets.presenceSensor;
|
||||
}
|
||||
}
|
136
lib/pages/spaces_management/widgets/dialogs/delete_dialogue.dart
Normal file
@ -0,0 +1,136 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
void showDeleteConfirmationDialog(BuildContext context, VoidCallback onConfirm, bool isSpace) {
|
||||
final String title = isSpace ? 'Delete Space' : 'Delete Community';
|
||||
final String subtitle = isSpace
|
||||
? 'All the data in the space will be lost'
|
||||
: 'All the data in the community will be lost';
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)),
|
||||
child: SizedBox(
|
||||
width: 500,
|
||||
child: Container(
|
||||
color: ColorsManager.whiteColors,
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildWarningIcon(),
|
||||
const SizedBox(height: 20),
|
||||
_buildDialogTitle(context, title),
|
||||
const SizedBox(height: 10),
|
||||
_buildDialogSubtitle(context, subtitle),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
CancelButton(
|
||||
label: 'Cancel',
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(); // Close the first dialog
|
||||
showProcessingPopup(context, isSpace, onConfirm);
|
||||
},
|
||||
style: _dialogButtonStyle(Colors.blue),
|
||||
child: const Text('Continue', style: TextStyle(color: Colors.white)),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void showProcessingPopup(BuildContext context, bool isSpace, VoidCallback onDelete) {
|
||||
final String title = isSpace ? 'Delete Space' : 'Delete Community';
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)),
|
||||
child: SizedBox(
|
||||
width: 500,
|
||||
child: Container(
|
||||
color: ColorsManager.whiteColors,
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildWarningIcon(),
|
||||
const SizedBox(height: 20),
|
||||
_buildDialogTitle(context, title),
|
||||
const SizedBox(height: 10),
|
||||
_buildDialogSubtitle(context, 'Are you sure you want to delete?'),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: onDelete,
|
||||
style: _dialogButtonStyle(ColorsManager.warningRed),
|
||||
child: const Text('Delete', style: TextStyle(color: Colors.white)),
|
||||
),
|
||||
CancelButton(
|
||||
label: 'Cancel',
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildWarningIcon() {
|
||||
return Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.warningRed,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(Icons.close, color: Colors.white, size: 40),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDialogTitle(BuildContext context, String title) {
|
||||
return Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDialogSubtitle(BuildContext context, String subtitle) {
|
||||
return Text(
|
||||
subtitle,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: ColorsManager.grayColor),
|
||||
);
|
||||
}
|
||||
|
||||
ButtonStyle _dialogButtonStyle(Color color) {
|
||||
return ElevatedButton.styleFrom(
|
||||
backgroundColor: color,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
||||
fixedSize: const Size(140, 40),
|
||||
);
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class IconSelectionDialog extends StatelessWidget {
|
||||
final List<String> spaceIconList;
|
||||
final Function(String selectedIcon) onIconSelected;
|
||||
|
||||
const IconSelectionDialog({
|
||||
Key? key,
|
||||
required this.spaceIconList,
|
||||
required this.onIconSelected,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
final screenHeight = MediaQuery.of(context).size.height;
|
||||
|
||||
return Dialog(
|
||||
elevation: 0,
|
||||
backgroundColor: ColorsManager.transparentColor,
|
||||
child: Container(
|
||||
width: screenWidth * 0.44,
|
||||
height: screenHeight * 0.45,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2), // Shadow color
|
||||
blurRadius: 20, // Spread of the blur
|
||||
offset: const Offset(0, 8), // Offset of the shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: AlertDialog(
|
||||
title: Text('Space Icon',style: Theme.of(context).textTheme.headlineMedium),
|
||||
backgroundColor: ColorsManager.whiteColors,
|
||||
content: Container(
|
||||
width: screenWidth * 0.4,
|
||||
height: screenHeight * 0.45,
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 7,
|
||||
crossAxisSpacing: 8,
|
||||
mainAxisSpacing: 16,
|
||||
),
|
||||
itemCount: spaceIconList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
onIconSelected(spaceIconList[index]);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
spaceIconList[index],
|
||||
width: screenWidth * 0.03,
|
||||
height: screenWidth * 0.03,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class GradientCanvasBorderWidget extends StatelessWidget {
|
||||
final double top;
|
||||
final double bottom;
|
||||
final double left;
|
||||
final double width;
|
||||
|
||||
const GradientCanvasBorderWidget({
|
||||
super.key,
|
||||
this.top = 0,
|
||||
this.bottom = 0,
|
||||
this.left = 300,
|
||||
this.width = 8,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
top: top,
|
||||
bottom: bottom,
|
||||
left: left,
|
||||
width: width,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
ColorsManager.semiTransparentBlackColor.withOpacity(0.1),
|
||||
ColorsManager.transparentColor,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
91
lib/pages/spaces_management/widgets/hoverable_button.dart
Normal file
@ -0,0 +1,91 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class HoverableButton extends StatefulWidget {
|
||||
final String iconPath;
|
||||
final String text;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const HoverableButton({
|
||||
Key? key,
|
||||
required this.iconPath,
|
||||
required this.text,
|
||||
required this.onTap,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<HoverableButton> createState() => _HoverableButtonState();
|
||||
}
|
||||
|
||||
class _HoverableButtonState extends State<HoverableButton> {
|
||||
bool isHovered = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
child: MouseRegion(
|
||||
onEnter: (_) => _updateHoverState(true),
|
||||
onExit: (_) => _updateHoverState(false),
|
||||
child: SizedBox(
|
||||
width: screenWidth * .07,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isHovered ? ColorsManager.warningRed : ColorsManager.whiteColors,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
if (isHovered)
|
||||
BoxShadow(
|
||||
color: ColorsManager.warningRed.withOpacity(0.4),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildIcon(),
|
||||
if (!isHovered) const SizedBox(width: 8),
|
||||
if (!isHovered) _buildText(theme),
|
||||
],
|
||||
),
|
||||
)),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildIcon() {
|
||||
return isHovered
|
||||
? const Icon(
|
||||
Icons.close,
|
||||
color: ColorsManager.whiteColors,
|
||||
size: 24,
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
widget.iconPath,
|
||||
width: 24,
|
||||
height: 24,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildText(ThemeData theme) {
|
||||
return Text(
|
||||
widget.text,
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
color: ColorsManager.spaceColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _updateHoverState(bool hover) {
|
||||
setState(() => isHovered = hover);
|
||||
}
|
||||
}
|
78
lib/pages/spaces_management/widgets/loaded_space_widget.dart
Normal file
@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/community_structure_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/gradient_canvas_border_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/sidebar_widget.dart';
|
||||
|
||||
class LoadedSpaceView extends StatefulWidget {
|
||||
final List<CommunityModel> communities;
|
||||
final CommunityModel? selectedCommunity;
|
||||
final SpaceModel? selectedSpace;
|
||||
final ValueChanged<CommunityModel>? onCommunitySelected;
|
||||
final ValueChanged<SpaceModel?>? onSpaceSelected;
|
||||
final List<ProductModel>? products;
|
||||
|
||||
const LoadedSpaceView({
|
||||
super.key,
|
||||
required this.communities,
|
||||
this.selectedCommunity,
|
||||
this.selectedSpace,
|
||||
required this.onCommunitySelected,
|
||||
required this.onSpaceSelected,
|
||||
this.products,
|
||||
});
|
||||
|
||||
@override
|
||||
_LoadedStateViewState createState() => _LoadedStateViewState();
|
||||
}
|
||||
|
||||
class _LoadedStateViewState extends State<LoadedSpaceView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SidebarWidget(
|
||||
communities: widget.communities,
|
||||
onCommunitySelected: widget.onCommunitySelected,
|
||||
onSpaceSelected: widget.onSpaceSelected,
|
||||
selectedSpaceUuid: widget.selectedSpace?.uuid,
|
||||
onSelectedSpaceChanged: (String? spaceUuid) {
|
||||
setState(() {
|
||||
final selectedSpace = findSpaceByUuid(spaceUuid, widget.communities);
|
||||
if (selectedSpace != null) {
|
||||
widget.onSpaceSelected!(selectedSpace);
|
||||
}
|
||||
});
|
||||
}),
|
||||
CommunityStructureArea(
|
||||
selectedCommunity: widget.selectedCommunity,
|
||||
selectedSpace: widget.selectedSpace,
|
||||
spaces: widget.selectedCommunity?.spaces ?? [],
|
||||
products: widget.products,
|
||||
onSpaceSelected: (SpaceModel? space) {
|
||||
setState(() {
|
||||
widget.onSpaceSelected!(space);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const GradientCanvasBorderWidget(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
SpaceModel? findSpaceByUuid(String? uuid, List<CommunityModel> communities) {
|
||||
for (var community in communities) {
|
||||
for (var space in community.spaces) {
|
||||
if (space.uuid == uuid) return space;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
53
lib/pages/spaces_management/widgets/plus_button_widget.dart
Normal file
@ -0,0 +1,53 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class PlusButtonWidget extends StatelessWidget {
|
||||
final int index;
|
||||
final String direction;
|
||||
final Offset offset;
|
||||
final Function(int index, Offset newPosition, String direction) onButtonTap;
|
||||
|
||||
const PlusButtonWidget({
|
||||
super.key,
|
||||
required this.index,
|
||||
required this.direction,
|
||||
required this.offset,
|
||||
required this.onButtonTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
left: offset.dx,
|
||||
top: offset.dy,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Offset newPosition;
|
||||
switch (direction) {
|
||||
case 'left':
|
||||
newPosition = const Offset(-200, 0);
|
||||
break;
|
||||
case 'right':
|
||||
newPosition = const Offset(200, 0);
|
||||
break;
|
||||
case 'down':
|
||||
newPosition = const Offset(0, 150);
|
||||
break;
|
||||
default:
|
||||
newPosition = Offset.zero;
|
||||
}
|
||||
onButtonTap(index, newPosition, direction);
|
||||
},
|
||||
child: Container(
|
||||
width: 30,
|
||||
height: 30,
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.spaceColor,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(Icons.add, color: Colors.white, size: 20),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
249
lib/pages/spaces_management/widgets/sidebar_widget.dart
Normal file
@ -0,0 +1,249 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_web/common/search_bar.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/community_tile.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/create_community_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/widgets/space_tile_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
class SidebarWidget extends StatefulWidget {
|
||||
final Function(CommunityModel)? onCommunitySelected;
|
||||
final Function(SpaceModel?)? onSpaceSelected;
|
||||
final List<CommunityModel> communities;
|
||||
final Function(String?)? onSelectedSpaceChanged; // New callback
|
||||
|
||||
final String? selectedSpaceUuid;
|
||||
|
||||
const SidebarWidget({
|
||||
super.key,
|
||||
this.onCommunitySelected,
|
||||
this.onSpaceSelected,
|
||||
this.onSelectedSpaceChanged,
|
||||
required this.communities,
|
||||
this.selectedSpaceUuid,
|
||||
});
|
||||
|
||||
@override
|
||||
_SidebarWidgetState createState() => _SidebarWidgetState();
|
||||
}
|
||||
|
||||
class _SidebarWidgetState extends State<SidebarWidget> {
|
||||
String _searchQuery = ''; // Track search query
|
||||
String? _selectedSpaceUuid;
|
||||
String? _selectedId;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedId = widget.selectedSpaceUuid; // Initialize with the passed selected space UUID
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant SidebarWidget oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.selectedSpaceUuid != oldWidget.selectedSpaceUuid) {
|
||||
setState(() {
|
||||
_selectedId = widget.selectedSpaceUuid;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _showCreateCommunityDialog(BuildContext parentContext) {
|
||||
showDialog(
|
||||
context: parentContext,
|
||||
builder: (context) => CreateCommunityDialog(
|
||||
onCreateCommunity: (String communityName, String description) {
|
||||
parentContext.read<SpaceManagementBloc>().add(
|
||||
CreateCommunityEvent(
|
||||
name: communityName,
|
||||
description: description,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Function to filter communities based on the search query
|
||||
List<CommunityModel> _filterCommunities() {
|
||||
if (_searchQuery.isEmpty) {
|
||||
// Reset the selected community and space UUIDs if there's no query
|
||||
_selectedSpaceUuid = null;
|
||||
return widget.communities;
|
||||
}
|
||||
|
||||
// Filter communities and expand only those that match the query
|
||||
return widget.communities.where((community) {
|
||||
final containsQueryInCommunity =
|
||||
community.name.toLowerCase().contains(_searchQuery.toLowerCase());
|
||||
final containsQueryInSpaces =
|
||||
community.spaces.any((space) => _containsQuery(space, _searchQuery.toLowerCase()));
|
||||
|
||||
return containsQueryInCommunity || containsQueryInSpaces;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
// Helper function to determine if any space or its children match the search query
|
||||
bool _containsQuery(SpaceModel space, String query) {
|
||||
final matchesSpace = space.name.toLowerCase().contains(query);
|
||||
final matchesChildren =
|
||||
space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
|
||||
|
||||
// If the space or any of its children match the query, expand this space
|
||||
if (matchesSpace || matchesChildren) {
|
||||
_selectedSpaceUuid = space.uuid;
|
||||
}
|
||||
|
||||
return matchesSpace || matchesChildren;
|
||||
}
|
||||
|
||||
bool _isSpaceOrChildSelected(SpaceModel space) {
|
||||
// Return true if the current space or any of its child spaces is selected
|
||||
if (_selectedSpaceUuid == space.uuid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Recursively check if any child spaces match the query
|
||||
for (var child in space.children) {
|
||||
if (_isSpaceOrChildSelected(child)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final filteredCommunities = _filterCommunities();
|
||||
|
||||
return Container(
|
||||
width: 300,
|
||||
decoration: subSectionContainerDecoration,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min, // Ensures the Column only takes necessary height
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Communities title with the add button
|
||||
Container(
|
||||
decoration: subSectionContainerDecoration,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Communities',
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
color: Colors.black,
|
||||
)),
|
||||
GestureDetector(
|
||||
onTap: () => _showCreateCommunityDialog(context),
|
||||
child: Container(
|
||||
width: 30,
|
||||
height: 30,
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
Assets.roundedAddIcon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Search bar
|
||||
CustomSearchBar(
|
||||
onSearchChanged: (query) {
|
||||
setState(() {
|
||||
_searchQuery = query;
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
// Community list
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: filteredCommunities.map((community) {
|
||||
return _buildCommunityTile(community);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCommunityTile(CommunityModel community) {
|
||||
bool hasChildren = community.spaces.isNotEmpty;
|
||||
|
||||
return CommunityTile(
|
||||
title: community.name,
|
||||
key: ValueKey(community.uuid),
|
||||
isSelected: _selectedId == community.uuid,
|
||||
isExpanded: false,
|
||||
onItemSelected: () {
|
||||
setState(() {
|
||||
_selectedId = community.uuid;
|
||||
_selectedSpaceUuid = null; // Update the selected community
|
||||
});
|
||||
|
||||
if (widget.onCommunitySelected != null) {
|
||||
widget.onCommunitySelected!(community);
|
||||
widget.onSpaceSelected!(null); // Pass the entire community
|
||||
}
|
||||
},
|
||||
onExpansionChanged: (String title, bool expanded) {
|
||||
_handleExpansionChange(community.uuid, expanded);
|
||||
},
|
||||
children: hasChildren
|
||||
? community.spaces.map((space) => _buildSpaceTile(space, community)).toList()
|
||||
: null, // Render spaces within the community
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSpaceTile(SpaceModel space, CommunityModel community) {
|
||||
bool isExpandedSpace = _isSpaceOrChildSelected(space);
|
||||
// Check if space should be expanded
|
||||
return SpaceTile(
|
||||
title: space.name,
|
||||
key: ValueKey(space.uuid),
|
||||
isSelected: _selectedId == space.uuid,
|
||||
initiallyExpanded: isExpandedSpace,
|
||||
onExpansionChanged: (bool expanded) {
|
||||
_handleExpansionChange(space.uuid ?? '', expanded);
|
||||
},
|
||||
onItemSelected: () {
|
||||
setState(() {
|
||||
_selectedId = space.uuid;
|
||||
_selectedSpaceUuid = space.uuid;
|
||||
});
|
||||
|
||||
if (widget.onSpaceSelected != null) {
|
||||
widget.onCommunitySelected!(community);
|
||||
widget.onSpaceSelected!(space);
|
||||
}
|
||||
|
||||
if (widget.onSelectedSpaceChanged != null) {
|
||||
widget.onSelectedSpaceChanged!(space.uuid);
|
||||
}
|
||||
},
|
||||
children: space.children.isNotEmpty
|
||||
? space.children.map((childSpace) => _buildSpaceTile(childSpace, community)).toList()
|
||||
: [], // Recursively render child spaces if available
|
||||
);
|
||||
}
|
||||
|
||||
void _handleExpansionChange(String uuid, bool expanded) {}
|
||||
}
|
74
lib/pages/spaces_management/widgets/space_card_widget.dart
Normal file
@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'plus_button_widget.dart'; // Make sure to import your PlusButtonWidget
|
||||
|
||||
class SpaceCardWidget extends StatelessWidget {
|
||||
final int index;
|
||||
final Size screenSize;
|
||||
final Offset position;
|
||||
final bool isHovered;
|
||||
final Function(int index, bool isHovered) onHoverChanged;
|
||||
final Function(int index, Offset newPosition, String direction) onButtonTap;
|
||||
final Widget Function(int index) buildSpaceContainer;
|
||||
final ValueChanged<Offset> onPositionChanged;
|
||||
|
||||
const SpaceCardWidget({
|
||||
super.key,
|
||||
required this.index,
|
||||
required this.onPositionChanged,
|
||||
required this.screenSize,
|
||||
required this.position,
|
||||
required this.isHovered,
|
||||
required this.onHoverChanged,
|
||||
required this.onButtonTap,
|
||||
required this.buildSpaceContainer,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onPanUpdate: (details) {
|
||||
// Call the provided callback to update the position
|
||||
final newPosition = position + details.delta;
|
||||
onPositionChanged(newPosition);
|
||||
},
|
||||
child: MouseRegion(
|
||||
onEnter: (_) {
|
||||
// Call the provided callback to handle hover state
|
||||
onHoverChanged(index, true);
|
||||
},
|
||||
onExit: (_) {
|
||||
// Call the provided callback to handle hover state
|
||||
onHoverChanged(index, false);
|
||||
},
|
||||
child: Stack(
|
||||
clipBehavior: Clip
|
||||
.none, // Allow hovering elements to be displayed outside the boundary
|
||||
children: [
|
||||
buildSpaceContainer(index), // Build the space container
|
||||
if (isHovered) ...[
|
||||
PlusButtonWidget(
|
||||
index: index,
|
||||
direction: 'left',
|
||||
offset: const Offset(-21, 20),
|
||||
onButtonTap: onButtonTap,
|
||||
),
|
||||
PlusButtonWidget(
|
||||
index: index,
|
||||
direction: 'right',
|
||||
offset: const Offset(140, 20),
|
||||
onButtonTap: onButtonTap,
|
||||
),
|
||||
PlusButtonWidget(
|
||||
index: index,
|
||||
direction: 'down',
|
||||
offset: const Offset(63, 50),
|
||||
onButtonTap: onButtonTap,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class SpaceContainerWidget extends StatelessWidget {
|
||||
final int index;
|
||||
final String icon;
|
||||
final String name;
|
||||
final VoidCallback? onDoubleTap;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
const SpaceContainerWidget({
|
||||
super.key,
|
||||
required this.index,
|
||||
required this.icon,
|
||||
required this.name,
|
||||
this.onTap,
|
||||
this.onDoubleTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return GestureDetector(
|
||||
onDoubleTap: onDoubleTap,
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
width: 150,
|
||||
height: 60,
|
||||
decoration: _containerDecoration(),
|
||||
child: Row(
|
||||
children: [
|
||||
_buildIconContainer(),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
name,
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ColorsManager.blackColor,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis, // Handle long names gracefully
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Builds the icon container with the SVG asset.
|
||||
Widget _buildIconContainer() {
|
||||
return Container(
|
||||
width: 40,
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.spaceColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(15),
|
||||
bottomLeft: Radius.circular(15),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
icon,
|
||||
color: ColorsManager.whiteColors,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
BoxDecoration _containerDecoration() {
|
||||
return BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: const Offset(0, 3), // Shadow position
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
52
lib/pages/spaces_management/widgets/space_tile_widget.dart
Normal file
@ -0,0 +1,52 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/common/custom_expansion_tile.dart';
|
||||
|
||||
class SpaceTile extends StatefulWidget {
|
||||
final String title;
|
||||
final bool isSelected;
|
||||
|
||||
final bool initiallyExpanded;
|
||||
final ValueChanged<bool> onExpansionChanged;
|
||||
final List<Widget>? children;
|
||||
final Function() onItemSelected;
|
||||
|
||||
const SpaceTile({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.initiallyExpanded,
|
||||
required this.onExpansionChanged,
|
||||
required this.onItemSelected,
|
||||
required this.isSelected,
|
||||
this.children,
|
||||
});
|
||||
|
||||
@override
|
||||
_SpaceTileState createState() => _SpaceTileState();
|
||||
}
|
||||
|
||||
class _SpaceTileState extends State<SpaceTile> {
|
||||
late bool _isExpanded;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_isExpanded = widget.initiallyExpanded;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomExpansionTile(
|
||||
isSelected: widget.isSelected,
|
||||
title: widget.title,
|
||||
initiallyExpanded: _isExpanded,
|
||||
onItemSelected: widget.onItemSelected,
|
||||
onExpansionChanged: (bool expanded) {
|
||||
setState(() {
|
||||
_isExpanded = expanded;
|
||||
});
|
||||
widget.onExpansionChanged(expanded);
|
||||
},
|
||||
children: widget.children ?? [],
|
||||
);
|
||||
}
|
||||
}
|
49
lib/pages/spaces_management/widgets/space_widget.dart
Normal file
@ -0,0 +1,49 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SpaceWidget extends StatelessWidget {
|
||||
final String name;
|
||||
final Offset position;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const SpaceWidget({
|
||||
super.key,
|
||||
required this.name,
|
||||
required this.position,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
left: position.dx,
|
||||
top: position.dy,
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child:
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.location_on, color: Colors.blue),
|
||||
const SizedBox(width: 8),
|
||||
Text(name, style: const TextStyle(fontSize: 16)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
26
lib/services/product_api.dart
Normal file
@ -0,0 +1,26 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart';
|
||||
import 'package:syncrow_web/services/api/http_service.dart';
|
||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||
|
||||
class ProductApi {
|
||||
Future<List<ProductModel>> fetchProducts() async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.listProducts,
|
||||
expectedResponseModel: (json) {
|
||||
List<dynamic> jsonData = json['data'];
|
||||
|
||||
List<ProductModel> productList = jsonData.map((jsonItem) {
|
||||
return ProductModel.fromMap(jsonItem);
|
||||
}).toList();
|
||||
return productList;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching products: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
253
lib/services/space_mana_api.dart
Normal file
@ -0,0 +1,253 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_response_model.dart';
|
||||
import 'package:syncrow_web/services/api/http_service.dart';
|
||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||
|
||||
class CommunitySpaceManagementApi {
|
||||
// Community Management APIs
|
||||
Future<List<CommunityModel>> fetchCommunities() async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.getCommunityList,
|
||||
expectedResponseModel: (json) {
|
||||
// Access the 'data' key from the response
|
||||
List<dynamic> jsonData = json['data'];
|
||||
|
||||
// Check if jsonData is actually a List
|
||||
List<CommunityModel> communityList = jsonData.map((jsonItem) {
|
||||
return CommunityModel.fromJson(jsonItem);
|
||||
}).toList();
|
||||
return communityList;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching communities: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<CommunityModel?> getCommunityById(String communityId) async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.getCommunityById.replaceAll('{communityId}', communityId),
|
||||
expectedResponseModel: (json) {
|
||||
return CommunityModel.fromJson(json['data']);
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching community by ID: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<CommunityModel?> createCommunity(String name, String description) async {
|
||||
try {
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.createCommunity,
|
||||
body: {
|
||||
'name': name,
|
||||
'description': description,
|
||||
},
|
||||
expectedResponseModel: (json) {
|
||||
return CommunityModel.fromJson(json['data']);
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error creating community: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> updateCommunity(String communityId, String name) async {
|
||||
try {
|
||||
final response = await HTTPService().put(
|
||||
path: ApiEndpoints.updateCommunity.replaceAll('{communityId}', communityId),
|
||||
body: {
|
||||
'name': name,
|
||||
},
|
||||
expectedResponseModel: (json) {
|
||||
return json['success'] ?? false;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error updating community: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteCommunity(String communityId) async {
|
||||
try {
|
||||
final response = await HTTPService().delete(
|
||||
path: ApiEndpoints.deleteCommunity.replaceAll('{communityId}', communityId),
|
||||
expectedResponseModel: (json) {
|
||||
return json['success'] ?? false;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error deleting community: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<SpacesResponse> fetchSpaces(String communityId) async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.listSpaces.replaceAll('{communityId}', communityId),
|
||||
expectedResponseModel: (json) {
|
||||
return SpacesResponse.fromJson(json);
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching spaces: $e');
|
||||
return SpacesResponse(
|
||||
data: [],
|
||||
message: 'Error fetching spaces',
|
||||
page: 1,
|
||||
size: 10,
|
||||
totalItem: 0,
|
||||
totalPage: 0,
|
||||
hasNext: false,
|
||||
hasPrevious: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<SpaceModel?> getSpace(String communityId, String spaceId) async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.getSpace
|
||||
.replaceAll('{communityId}', communityId)
|
||||
.replaceAll('{spaceId}', spaceId),
|
||||
expectedResponseModel: (json) {
|
||||
return SpaceModel.fromJson(json);
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching space: $e');
|
||||
return null; // Assuming an empty SpaceModel constructor
|
||||
}
|
||||
}
|
||||
|
||||
Future<SpaceModel?> createSpace({
|
||||
required String communityId,
|
||||
required String name,
|
||||
String? parentId,
|
||||
String? direction,
|
||||
bool isPrivate = false,
|
||||
required Offset position,
|
||||
String? icon,
|
||||
required List<SelectedProduct> products,
|
||||
}) async {
|
||||
try {
|
||||
final body = {
|
||||
'spaceName': name,
|
||||
'isPrivate': isPrivate,
|
||||
'x': position.dx,
|
||||
'y': position.dy,
|
||||
'direction': direction,
|
||||
'icon': icon,
|
||||
'products': products.map((product) => product.toJson()).toList(),
|
||||
};
|
||||
if (parentId != null) {
|
||||
body['parentUuid'] = parentId;
|
||||
}
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.createSpace.replaceAll('{communityId}', communityId),
|
||||
body: body,
|
||||
expectedResponseModel: (json) {
|
||||
return SpaceModel.fromJson(json['data']);
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error creating space: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<SpaceModel?> updateSpace({
|
||||
required String communityId,
|
||||
required spaceId,
|
||||
required String name,
|
||||
String? parentId,
|
||||
String? icon,
|
||||
String? direction,
|
||||
bool isPrivate = false,
|
||||
required Offset position,
|
||||
required List<SelectedProduct> products,
|
||||
}) async {
|
||||
try {
|
||||
final body = {
|
||||
'spaceName': name,
|
||||
'isPrivate': isPrivate,
|
||||
'x': position.dx,
|
||||
'y': position.dy,
|
||||
'direction': direction,
|
||||
'icon': icon,
|
||||
'products': products.map((product) => product.toJson()).toList(),
|
||||
};
|
||||
if (parentId != null) {
|
||||
body['parentUuid'] = parentId;
|
||||
}
|
||||
|
||||
final response = await HTTPService().put(
|
||||
path: ApiEndpoints.updateSpace
|
||||
.replaceAll('{communityId}', communityId)
|
||||
.replaceAll('{spaceId}', spaceId),
|
||||
body: body,
|
||||
expectedResponseModel: (json) {
|
||||
return SpaceModel.fromJson(json['data']);
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error creating space: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteSpace(String communityId, String spaceId) async {
|
||||
try {
|
||||
final response = await HTTPService().delete(
|
||||
path: ApiEndpoints.deleteSpace
|
||||
.replaceAll('{communityId}', communityId)
|
||||
.replaceAll('{spaceId}', spaceId),
|
||||
expectedResponseModel: (json) {
|
||||
return json['success'] ?? false;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error deleting space: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SpaceModel>> getSpaceHierarchy(String communityId) async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.getSpaceHierarchy.replaceAll('{communityId}', communityId),
|
||||
expectedResponseModel: (json) {
|
||||
final spaceModels =
|
||||
(json['data'] as List).map((spaceJson) => SpaceModel.fromJson(spaceJson)).toList();
|
||||
|
||||
return spaceModels;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching space hierarchy: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import 'package:syncrow_web/pages/access_management/view/access_management.dart'
|
||||
import 'package:syncrow_web/pages/auth/view/login_page.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/view/device_managment_page.dart';
|
||||
import 'package:syncrow_web/pages/home/view/home_page.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/view/spaces_management_page.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/view/visitor_password_dialog.dart';
|
||||
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
||||
|
||||
@ -29,6 +30,9 @@ class AppRoutes {
|
||||
path: RoutesConst.deviceManagementPage,
|
||||
builder: (context, state) => const DeviceManagementPage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: RoutesConst.spacesManagementPage,
|
||||
builder: (context, state) => SpaceManagementPage()),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -9,14 +9,16 @@ abstract class ColorsManager {
|
||||
static const Color whiteColors = Colors.white;
|
||||
static const Color secondaryColor = Color(0xFF023DFE);
|
||||
static const Color onSecondaryColor = Color(0xFF023DFE);
|
||||
static Color shadowBlackColor = Colors.black.withOpacity(0.2);
|
||||
|
||||
static Color dialogBlueTitle = Color(0xFF023DFE).withOpacity(0.6);
|
||||
static Color dialogBlueTitle = const Color(0xFF023DFE).withOpacity(0.6);
|
||||
|
||||
static const Color primaryTextColor = Colors.black;
|
||||
|
||||
static const Color greyColor = Color(0xFFd5d5d5);
|
||||
static const Color lightGreyColor = Color(0xFF999999);
|
||||
static const Color backgroundColor = Color(0xFFececec);
|
||||
static const Color textFieldGreyColor = Color(0xFFF4F4F4);
|
||||
static const Color dozeColor = Color(0xFFFEC258);
|
||||
static const Color relaxColor = Color(0xFFFBD288);
|
||||
static const Color readingColor = Color(0xFFF7D69C);
|
||||
@ -30,6 +32,8 @@ abstract class ColorsManager {
|
||||
static const Color grayColor = Color(0xFF999999);
|
||||
static const Color red = Color(0xFFFF0000);
|
||||
static const Color graysColor = Color(0xffEBEBEB);
|
||||
static const Color lightGrayColor = Color(0xB2999999);
|
||||
static const Color grayBorder = Color(0xFFCFCFCF);
|
||||
static const Color textGray = Color(0xffD5D5D5);
|
||||
static const Color btnColor = Color(0xFF00008B);
|
||||
static const Color blueColor = Color(0xFF0036E6);
|
||||
@ -41,6 +45,14 @@ abstract class ColorsManager {
|
||||
static const Color blue4 = Color(0xFF001E7E);
|
||||
static const Color textGreen = Color(0xFF008905);
|
||||
static const Color yaGreen = Color(0xFFFFBF44);
|
||||
static const Color checkBoxFillColor = Color(0xFFF3F3F3);
|
||||
static const Color semiTransparentBlackColor = Color(0x3F000000);
|
||||
static const Color transparentColor = Color(0x00000000);
|
||||
static const Color spaceColor = Color(0xB2023DFE);
|
||||
static const Color counterBackgroundColor = Color(0xCCF4F4F4);
|
||||
static const Color neutralGray = Color(0xFFE5E5E5);
|
||||
static const Color warningRed = Color(0xFFFF6465);
|
||||
static const Color borderColor = Color(0xFFE5E5E5);
|
||||
static const Color CircleImageBackground = Color(0xFFF4F4F4);
|
||||
}
|
||||
//background: #background: #5D5D5D;
|
||||
|
@ -11,14 +11,12 @@ abstract class ApiEndpoints {
|
||||
static const String visitorPassword = '/visitor-password';
|
||||
static const String getDevices = '/visitor-password/devices';
|
||||
|
||||
static const String sendOnlineOneTime =
|
||||
'/visitor-password/temporary-password/online/one-time';
|
||||
static const String sendOnlineOneTime = '/visitor-password/temporary-password/online/one-time';
|
||||
static const String sendOnlineMultipleTime =
|
||||
'/visitor-password/temporary-password/online/multiple-time';
|
||||
|
||||
//offline Password
|
||||
static const String sendOffLineOneTime =
|
||||
'/visitor-password/temporary-password/offline/one-time';
|
||||
static const String sendOffLineOneTime = '/visitor-password/temporary-password/offline/one-time';
|
||||
static const String sendOffLineMultipleTime =
|
||||
'/visitor-password/temporary-password/offline/multiple-time';
|
||||
|
||||
@ -36,30 +34,44 @@ abstract class ApiEndpoints {
|
||||
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
||||
|
||||
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
||||
|
||||
// Space Module
|
||||
static const String createSpace = '/communities/{communityId}/spaces';
|
||||
static const String listSpaces = '/communities/{communityId}/spaces';
|
||||
static const String deleteSpace = '/communities/{communityId}/spaces/{spaceId}';
|
||||
static const String updateSpace = '/communities/{communityId}/spaces/{spaceId}';
|
||||
static const String getSpace = '/communities/{communityId}/spaces/{spaceId}';
|
||||
static const String getSpaceHierarchy = '/communities/{communityId}/spaces';
|
||||
|
||||
// Community Module
|
||||
static const String createCommunity = '/communities';
|
||||
static const String getCommunityList = '/communities';
|
||||
static const String getCommunityById = '/communities/{communityId}';
|
||||
static const String updateCommunity = '/communities/{communityId}';
|
||||
static const String deleteCommunity = '/communities/{communityId}';
|
||||
static const String getUserCommunities = '/communities/user/{userUuid}';
|
||||
static const String createUserCommunity = '/communities/user';
|
||||
static const String getDeviceLogsByDate =
|
||||
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
||||
|
||||
static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
|
||||
static const String getScheduleByDeviceId =
|
||||
'/schedule/{deviceUuid}?category={category}';
|
||||
static const String deleteScheduleByDeviceId =
|
||||
'/schedule/{deviceUuid}/{scheduleUuid}';
|
||||
static const String updateScheduleByDeviceId =
|
||||
'/schedule/enable/{deviceUuid}';
|
||||
static const String getScheduleByDeviceId = '/schedule/{deviceUuid}?category={category}';
|
||||
static const String deleteScheduleByDeviceId = '/schedule/{deviceUuid}/{scheduleUuid}';
|
||||
static const String updateScheduleByDeviceId = '/schedule/enable/{deviceUuid}';
|
||||
static const String factoryReset = '/device/factory/reset/{deviceUuid}';
|
||||
static const String powerClamp =
|
||||
'/device/{powerClampUuid}/power-clamp/status';
|
||||
static const String powerClamp = '/device/{powerClampUuid}/power-clamp/status';
|
||||
|
||||
//product
|
||||
static const String listProducts = '/products';
|
||||
static const String getSpaceScenes = '/scene/tap-to-run/{unitUuid}';
|
||||
static const String getSpaceAutomation = '/automation/{unitUuid}';
|
||||
static const String getIconScene = '/scene/icon';
|
||||
static const String createScene = '/scene/tap-to-run';
|
||||
static const String createAutomation = '/automation';
|
||||
static const String getUnitScenes =
|
||||
'/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
|
||||
static const String getAutomationDetails =
|
||||
'/automation/details/{automationId}';
|
||||
static const String getUnitScenes = '/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
|
||||
static const String getAutomationDetails = '/automation/details/{automationId}';
|
||||
static const String getScene = '/scene/tap-to-run/{sceneId}';
|
||||
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
|
||||
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
|
||||
|
||||
static const String deleteAutomation = '/automation/{automationId}';
|
||||
}
|
||||
|
@ -13,12 +13,10 @@ class Assets {
|
||||
static const String rightLine = "assets/images/right_line.png";
|
||||
static const String google = "assets/images/google.svg";
|
||||
static const String facebook = "assets/images/facebook.svg";
|
||||
static const String invisiblePassword =
|
||||
"assets/images/Password_invisible.svg";
|
||||
static const String invisiblePassword = "assets/images/Password_invisible.svg";
|
||||
static const String visiblePassword = "assets/images/password_visible.svg";
|
||||
static const String accessIcon = "assets/images/access_icon.svg";
|
||||
static const String spaseManagementIcon =
|
||||
"assets/images/spase_management_icon.svg";
|
||||
static const String spaseManagementIcon = "assets/images/spase_management_icon.svg";
|
||||
static const String devicesIcon = "assets/images/devices_icon.svg";
|
||||
static const String moveinIcon = "assets/images/movein_icon.svg";
|
||||
static const String constructionIcon = "assets/images/construction_icon.svg";
|
||||
@ -31,15 +29,13 @@ class Assets {
|
||||
static const String emptyTable = "assets/images/empty_table.svg";
|
||||
|
||||
// General assets
|
||||
static const String motionlessDetection =
|
||||
"assets/icons/motionless_detection.svg";
|
||||
static const String motionlessDetection = "assets/icons/motionless_detection.svg";
|
||||
static const String acHeating = "assets/icons/ac_heating.svg";
|
||||
static const String acPowerOff = "assets/icons/ac_power_off.svg";
|
||||
static const String acFanMiddle = "assets/icons/ac_fan_middle.svg";
|
||||
static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg";
|
||||
static const String resetOff = "assets/icons/reset_off.svg";
|
||||
static const String sensitivityOperationIcon =
|
||||
"assets/icons/sesitivity_operation_icon.svg";
|
||||
static const String sensitivityOperationIcon = "assets/icons/sesitivity_operation_icon.svg";
|
||||
static const String motionDetection = "assets/icons/motion_detection.svg";
|
||||
static const String freezing = "assets/icons/freezing.svg";
|
||||
static const String indicator = "assets/icons/indicator.svg";
|
||||
@ -60,8 +56,7 @@ class Assets {
|
||||
static const String celsiusDegrees = "assets/icons/celsius_degrees.svg";
|
||||
static const String masterState = "assets/icons/master_state.svg";
|
||||
static const String acPower = "assets/icons/ac_power.svg";
|
||||
static const String farDetectionFunction =
|
||||
"assets/icons/far_detection_function.svg";
|
||||
static const String farDetectionFunction = "assets/icons/far_detection_function.svg";
|
||||
static const String nobodyTime = "assets/icons/nobody_time.svg";
|
||||
|
||||
// Automation functions
|
||||
@ -69,47 +64,33 @@ class Assets {
|
||||
"assets/icons/automation_functions/temp_password_unlock.svg";
|
||||
static const String doorlockNormalOpen =
|
||||
"assets/icons/automation_functions/doorlock_normal_open.svg";
|
||||
static const String doorbell =
|
||||
"assets/icons/automation_functions/doorbell.svg";
|
||||
static const String doorbell = "assets/icons/automation_functions/doorbell.svg";
|
||||
static const String remoteUnlockViaApp =
|
||||
"assets/icons/automation_functions/remote_unlock_via_app.svg";
|
||||
static const String doubleLock =
|
||||
"assets/icons/automation_functions/double_lock.svg";
|
||||
static const String selfTestResult =
|
||||
"assets/icons/automation_functions/self_test_result.svg";
|
||||
static const String lockAlarm =
|
||||
"assets/icons/automation_functions/lock_alarm.svg";
|
||||
static const String presenceState =
|
||||
"assets/icons/automation_functions/presence_state.svg";
|
||||
static const String currentTemp =
|
||||
"assets/icons/automation_functions/current_temp.svg";
|
||||
static const String presence =
|
||||
"assets/icons/automation_functions/presence.svg";
|
||||
static const String doubleLock = "assets/icons/automation_functions/double_lock.svg";
|
||||
static const String selfTestResult = "assets/icons/automation_functions/self_test_result.svg";
|
||||
static const String lockAlarm = "assets/icons/automation_functions/lock_alarm.svg";
|
||||
static const String presenceState = "assets/icons/automation_functions/presence_state.svg";
|
||||
static const String currentTemp = "assets/icons/automation_functions/current_temp.svg";
|
||||
static const String presence = "assets/icons/automation_functions/presence.svg";
|
||||
static const String residualElectricity =
|
||||
"assets/icons/automation_functions/residual_electricity.svg";
|
||||
static const String hijackAlarm =
|
||||
"assets/icons/automation_functions/hijack_alarm.svg";
|
||||
static const String passwordUnlock =
|
||||
"assets/icons/automation_functions/password_unlock.svg";
|
||||
static const String hijackAlarm = "assets/icons/automation_functions/hijack_alarm.svg";
|
||||
static const String passwordUnlock = "assets/icons/automation_functions/password_unlock.svg";
|
||||
static const String remoteUnlockRequest =
|
||||
"assets/icons/automation_functions/remote_unlock_req.svg";
|
||||
static const String cardUnlock =
|
||||
"assets/icons/automation_functions/card_unlock.svg";
|
||||
static const String cardUnlock = "assets/icons/automation_functions/card_unlock.svg";
|
||||
static const String motion = "assets/icons/automation_functions/motion.svg";
|
||||
static const String fingerprintUnlock =
|
||||
"assets/icons/automation_functions/fingerprint_unlock.svg";
|
||||
|
||||
// Presence Sensor Assets
|
||||
static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg";
|
||||
static const String sensorPresenceIcon =
|
||||
"assets/icons/sensor_presence_ic.svg";
|
||||
static const String sensorPresenceIcon = "assets/icons/sensor_presence_ic.svg";
|
||||
static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg";
|
||||
static const String illuminanceRecordIcon =
|
||||
"assets/icons/illuminance_record_ic.svg";
|
||||
static const String presenceRecordIcon =
|
||||
"assets/icons/presence_record_ic.svg";
|
||||
static const String helpDescriptionIcon =
|
||||
"assets/icons/help_description_ic.svg";
|
||||
static const String illuminanceRecordIcon = "assets/icons/illuminance_record_ic.svg";
|
||||
static const String presenceRecordIcon = "assets/icons/presence_record_ic.svg";
|
||||
static const String helpDescriptionIcon = "assets/icons/help_description_ic.svg";
|
||||
|
||||
static const String lightPulp = "assets/icons/light_pulb.svg";
|
||||
static const String acDevice = "assets/icons/ac_device.svg";
|
||||
@ -142,7 +123,34 @@ class Assets {
|
||||
static const String dyi = 'assets/icons/dyi.svg';
|
||||
static const String office = 'assets/icons/office.svg';
|
||||
static const String parlour = 'assets/icons/parlour.svg';
|
||||
static const String grid = "assets/images/grid.svg";
|
||||
static const String grid = 'assets/images/grid.svg';
|
||||
|
||||
static const String bbq = 'assets/icons/bbq_icon.svg';
|
||||
static const String building = 'assets/icons/building_icon.svg';
|
||||
static const String desk = 'assets/icons/desk_icon.svg';
|
||||
static const String door = 'assets/icons/door_icon.svg';
|
||||
static const String gym = 'assets/icons/gym_icon.svg';
|
||||
static const String location = 'assets/icons/location_icon.svg';
|
||||
static const String parking = 'assets/icons/parking_icon.svg';
|
||||
static const String pool = 'assets/icons/pool_icon.svg';
|
||||
static const String sauna = 'assets/icons/sauna_icon.svg';
|
||||
static const String stair = 'assets/icons/stair_icon.svg';
|
||||
static const String steamRoom = 'assets/icons/steam_room_icon.svg';
|
||||
static const String street = 'assets/icons/street_icon.svg';
|
||||
static const String unit = 'assets/icons/unit_icon.svg';
|
||||
static const String villa = 'assets/icons/villa_icon.svg';
|
||||
static const String iconEdit = 'assets/icons/icon_edit_icon.svg';
|
||||
static const String textFieldSearch = 'assets/icons/textfield_search_icon.svg';
|
||||
static const String roundedAddIcon = 'assets/icons/rounded_add_icon.svg';
|
||||
static const String addIcon = 'assets/icons/add_icon.svg';
|
||||
static const String smartThermostatIcon = 'assets/icons/smart_thermostat_icon.svg';
|
||||
static const String smartLightIcon = 'assets/icons/smart_light_icon.svg';
|
||||
static const String presenceSensor = 'assets/icons/presence_sensor.svg';
|
||||
static const String Gang3SwitchIcon = 'assets/icons/3_Gang_switch_icon.svg';
|
||||
static const String Gang2SwitchIcon = 'assets/icons/2_Gang_Switch_icon.svg';
|
||||
static const String Gang1SwitchIcon = 'assets/icons/1_Gang_switch_icon.svg';
|
||||
static const String DoorLockIcon = 'assets/icons/door_lock.svg';
|
||||
static const String SmartGatewayIcon = 'assets/icons/smart_gateway_icon.svg';
|
||||
static const String curtainIcon = "assets/images/curtain.svg";
|
||||
static const String unlock = 'assets/icons/unlock_ic.svg';
|
||||
static const String firmware = 'assets/icons/firmware.svg';
|
||||
@ -183,8 +191,7 @@ class Assets {
|
||||
//assets/icons/water_leak_normal.svg
|
||||
static const String waterLeakNormal = 'assets/icons/water_leak_normal.svg';
|
||||
//assets/icons/water_leak_detected.svg
|
||||
static const String waterLeakDetected =
|
||||
'assets/icons/water_leak_detected.svg';
|
||||
static const String waterLeakDetected = 'assets/icons/water_leak_detected.svg';
|
||||
|
||||
//assets/icons/automation_records.svg
|
||||
static const String automationRecords = 'assets/icons/automation_records.svg';
|
||||
@ -219,6 +226,17 @@ class Assets {
|
||||
//assets/icons/sos_normal.svg
|
||||
static const String sosNormal = 'assets/icons/sos_normal.svg';
|
||||
|
||||
static const String waterLeakSensor = 'assets/icons/water_leak_sensor.svg';
|
||||
static const String powerClamp = 'assets/icons/power_clamp.svg';
|
||||
static const String threeTouchSwitch = 'assets/icons/3G_touch_switch.svg';
|
||||
static const String twoTouchSwitch = 'assets/icons/2G_touch_switch.svg';
|
||||
static const String oneTouchSwitch = 'assets/icons/1G_touch_switch.svg';
|
||||
|
||||
static const String garageDoor = 'assets/icons/garage_opener.svg';
|
||||
static const String doorSensor = 'assets/icons/door_sensor.svg';
|
||||
|
||||
static const String delete = 'assets/icons/delete.svg';
|
||||
static const String edit = 'assets/icons/edit.svg';
|
||||
//assets/icons/routine/tab_to_run.svg
|
||||
static const String tabToRun = 'assets/icons/routine/tab_to_run.svg';
|
||||
|
||||
@ -238,64 +256,40 @@ class Assets {
|
||||
static const String delay = 'assets/icons/routine/delay.svg';
|
||||
|
||||
// Assets for functions_icons
|
||||
static const String assetsSensitivityFunction =
|
||||
"assets/icons/functions_icons/sensitivity.svg";
|
||||
static const String assetsSensitivityFunction = "assets/icons/functions_icons/sensitivity.svg";
|
||||
static const String assetsSensitivityOperationIcon =
|
||||
"assets/icons/functions_icons/sesitivity_operation_icon.svg";
|
||||
static const String assetsAcPower =
|
||||
"assets/icons/functions_icons/ac_power.svg";
|
||||
static const String assetsAcPowerOFF =
|
||||
"assets/icons/functions_icons/ac_power_off.svg";
|
||||
static const String assetsChildLock =
|
||||
"assets/icons/functions_icons/child_lock.svg";
|
||||
static const String assetsFreezing =
|
||||
"assets/icons/functions_icons/freezing.svg";
|
||||
static const String assetsFanSpeed =
|
||||
"assets/icons/functions_icons/fan_speed.svg";
|
||||
static const String assetsAcCooling =
|
||||
"assets/icons/functions_icons/ac_cooling.svg";
|
||||
static const String assetsAcHeating =
|
||||
"assets/icons/functions_icons/ac_heating.svg";
|
||||
static const String assetsCelsiusDegrees =
|
||||
"assets/icons/functions_icons/celsius_degrees.svg";
|
||||
static const String assetsTempreture =
|
||||
"assets/icons/functions_icons/tempreture.svg";
|
||||
static const String assetsAcFanLow =
|
||||
"assets/icons/functions_icons/ac_fan_low.svg";
|
||||
static const String assetsAcFanMiddle =
|
||||
"assets/icons/functions_icons/ac_fan_middle.svg";
|
||||
static const String assetsAcFanHigh =
|
||||
"assets/icons/functions_icons/ac_fan_high.svg";
|
||||
static const String assetsAcFanAuto =
|
||||
"assets/icons/functions_icons/ac_fan_auto.svg";
|
||||
static const String assetsSceneChildLock =
|
||||
"assets/icons/functions_icons/scene_child_lock.svg";
|
||||
static const String assetsAcPower = "assets/icons/functions_icons/ac_power.svg";
|
||||
static const String assetsAcPowerOFF = "assets/icons/functions_icons/ac_power_off.svg";
|
||||
static const String assetsChildLock = "assets/icons/functions_icons/child_lock.svg";
|
||||
static const String assetsFreezing = "assets/icons/functions_icons/freezing.svg";
|
||||
static const String assetsFanSpeed = "assets/icons/functions_icons/fan_speed.svg";
|
||||
static const String assetsAcCooling = "assets/icons/functions_icons/ac_cooling.svg";
|
||||
static const String assetsAcHeating = "assets/icons/functions_icons/ac_heating.svg";
|
||||
static const String assetsCelsiusDegrees = "assets/icons/functions_icons/celsius_degrees.svg";
|
||||
static const String assetsTempreture = "assets/icons/functions_icons/tempreture.svg";
|
||||
static const String assetsAcFanLow = "assets/icons/functions_icons/ac_fan_low.svg";
|
||||
static const String assetsAcFanMiddle = "assets/icons/functions_icons/ac_fan_middle.svg";
|
||||
static const String assetsAcFanHigh = "assets/icons/functions_icons/ac_fan_high.svg";
|
||||
static const String assetsAcFanAuto = "assets/icons/functions_icons/ac_fan_auto.svg";
|
||||
static const String assetsSceneChildLock = "assets/icons/functions_icons/scene_child_lock.svg";
|
||||
static const String assetsSceneChildUnlock =
|
||||
"assets/icons/functions_icons/scene_child_unlock.svg";
|
||||
static const String assetsSceneRefresh =
|
||||
"assets/icons/functions_icons/scene_refresh.svg";
|
||||
static const String assetsLightCountdown =
|
||||
"assets/icons/functions_icons/light_countdown.svg";
|
||||
static const String assetsFarDetection =
|
||||
"assets/icons/functions_icons/far_detection.svg";
|
||||
static const String assetsSceneRefresh = "assets/icons/functions_icons/scene_refresh.svg";
|
||||
static const String assetsLightCountdown = "assets/icons/functions_icons/light_countdown.svg";
|
||||
static const String assetsFarDetection = "assets/icons/functions_icons/far_detection.svg";
|
||||
static const String assetsFarDetectionFunction =
|
||||
"assets/icons/functions_icons/far_detection_function.svg";
|
||||
static const String assetsIndicator =
|
||||
"assets/icons/functions_icons/indicator.svg";
|
||||
static const String assetsMotionDetection =
|
||||
"assets/icons/functions_icons/motion_detection.svg";
|
||||
static const String assetsIndicator = "assets/icons/functions_icons/indicator.svg";
|
||||
static const String assetsMotionDetection = "assets/icons/functions_icons/motion_detection.svg";
|
||||
static const String assetsMotionlessDetection =
|
||||
"assets/icons/functions_icons/motionless_detection.svg";
|
||||
static const String assetsNobodyTime =
|
||||
"assets/icons/functions_icons/nobody_time.svg";
|
||||
static const String assetsFactoryReset =
|
||||
"assets/icons/functions_icons/factory_reset.svg";
|
||||
static const String assetsMasterState =
|
||||
"assets/icons/functions_icons/master_state.svg";
|
||||
static const String assetsNobodyTime = "assets/icons/functions_icons/nobody_time.svg";
|
||||
static const String assetsFactoryReset = "assets/icons/functions_icons/factory_reset.svg";
|
||||
static const String assetsMasterState = "assets/icons/functions_icons/master_state.svg";
|
||||
static const String assetsSwitchAlarmSound =
|
||||
"assets/icons/functions_icons/switch_alarm_sound.svg";
|
||||
static const String assetsResetOff =
|
||||
"assets/icons/functions_icons/reset_off.svg";
|
||||
static const String assetsResetOff = "assets/icons/functions_icons/reset_off.svg";
|
||||
|
||||
// Assets for automation_functions
|
||||
static const String assetsCardUnlock =
|
||||
@ -326,8 +320,7 @@ class Assets {
|
||||
"assets/icons/functions_icons/automation_functions/self_test_result.svg";
|
||||
static const String assetsPresence =
|
||||
"assets/icons/functions_icons/automation_functions/presence.svg";
|
||||
static const String assetsMotion =
|
||||
"assets/icons/functions_icons/automation_functions/motion.svg";
|
||||
static const String assetsMotion = "assets/icons/functions_icons/automation_functions/motion.svg";
|
||||
static const String assetsCurrentTemp =
|
||||
"assets/icons/functions_icons/automation_functions/current_temp.svg";
|
||||
static const String assetsPresenceState =
|
||||
|
@ -4,4 +4,5 @@ class RoutesConst {
|
||||
static const String visitorPassword = '/visitor-password';
|
||||
static const String accessManagementPage = '/access-management-page';
|
||||
static const String deviceManagementPage = '/device-management-page';
|
||||
static const String spacesManagementPage = '/spaces_management-page';
|
||||
}
|
||||
|
18
lib/utils/constants/space_icon_const.dart
Normal file
@ -0,0 +1,18 @@
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
const List<String> spaceIconList = [
|
||||
Assets.location,
|
||||
Assets.villa,
|
||||
Assets.gym,
|
||||
Assets.sauna,
|
||||
Assets.bbq,
|
||||
Assets.building,
|
||||
Assets.desk,
|
||||
Assets.door,
|
||||
Assets.parking,
|
||||
Assets.pool,
|
||||
Assets.stair,
|
||||
Assets.steamRoom,
|
||||
Assets.street,
|
||||
Assets.unit,
|
||||
];
|
@ -21,11 +21,11 @@ InputDecoration? textBoxDecoration({bool suffixIcon = false}) => InputDecoration
|
||||
borderSide: BorderSide.none, // Remove the underline
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.red, width: 2),
|
||||
borderSide: const BorderSide(color: Colors.red, width: 2),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.red, width: 2),
|
||||
borderSide: const BorderSide(color: Colors.red, width: 2),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
);
|
||||
@ -47,3 +47,15 @@ BoxDecoration containerWhiteDecoration = BoxDecoration(boxShadow: [
|
||||
offset: const Offset(0, 5), // changes position of shadow
|
||||
),
|
||||
], color: ColorsManager.whiteColors, borderRadius: const BorderRadius.all(Radius.circular(15)));
|
||||
|
||||
BoxDecoration subSectionContainerDecoration = BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
blurRadius: 10,
|
||||
spreadRadius: 1,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -657,10 +657,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.5"
|
||||
version: "14.2.4"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -50,8 +50,8 @@ dependencies:
|
||||
dropdown_search: ^5.0.6
|
||||
flutter_dotenv: ^5.1.0
|
||||
fl_chart: ^0.69.0
|
||||
uuid: ^4.4.2
|
||||
time_picker_spinner: ^1.0.0
|
||||
uuid: ^4.4.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|