Compare commits

..

101 Commits

Author SHA1 Message Date
b3ec0fbf73 Merged with dev 2024-11-06 10:44:10 +03:00
27b0816ffd Merge pull request #48 from SyncrowIOT/new_devices
SOS Device
2024-11-04 23:51:52 +03:00
dc55232a42 remove commented code 2024-11-04 12:09:44 +03:00
7b179c90c3 push SOS device 2024-11-04 12:06:44 +03:00
0fc709a5b1 push sos basic device implementation 2024-10-31 11:32:34 +03:00
3e9b93c2fc Merge branch 'dev' of https://github.com/SyncrowIOT/web into feat/refactoring 2024-10-31 09:26:23 +04:00
13622c1dcf Merge pull request #45 from SyncrowIOT/web_issue
forget_password&power_clamp_issue
2024-10-30 14:24:22 +03:00
8b1099c683 dateTime issue 2024-10-30 13:17:46 +03:00
b802a6130d Merged with dev 2024-10-30 10:55:45 +03:00
73ab6f3d05 forget_password&power_clamp_issue 2024-10-30 09:47:18 +03:00
bc53605114 Merge pull request #44 from SyncrowIOT/30_oct_fixes
enhancement and bug fixes
2024-10-30 09:31:01 +03:00
29a2e9285b enhancement and bug fixes 2024-10-30 00:46:48 +03:00
5d10b2a35b Merge pull request #41 from SyncrowIOT/power_clamp
Power clamp
2024-10-29 11:06:16 +03:00
4eb214e010 remove_file 2024-10-29 10:50:44 +03:00
81913dca9f power_clamp_issue 2024-10-29 09:43:09 +03:00
62e8c372f7 Merge branch 'power_clamp' of https://github.com/SyncrowIOT/web into power_clamp 2024-10-28 13:18:42 +03:00
0425b19478 power_clamp_issue 2024-10-28 13:17:48 +03:00
8775258160 Updated the pubspec.lock 2024-10-27 23:41:26 +03:00
9dda21075e Updated the pubspec.lock 2024-10-27 23:39:00 +03:00
361891546c Merged with dev 2024-10-27 23:31:04 +03:00
79f96f3255 Merge pull request #43 from SyncrowIOT/enhancement
shadow and text color
2024-10-27 23:15:26 +03:00
c4421a9ef3 Edited pubspec.lock file 2024-10-27 23:12:38 +03:00
5fff4445ac Added pubspec.lock file 2024-10-27 23:09:33 +03:00
19e0c6e7bd Delete pubspec.lock 2024-10-27 15:23:32 +03:00
b7dddcb8dd shadow and text color 2024-10-27 12:36:32 +03:00
23e54c7e78 batch_control 2024-10-25 20:17:34 +03:00
a594d5b93c power_clamp_batch_control 2024-10-25 20:06:07 +03:00
b8ad20b3ff power_clamp_functionality 2024-10-24 17:40:32 +03:00
9b4e687e9a power_clamp_functionality 2024-10-24 15:03:19 +03:00
2941565b3d Merge pull request #42 from SyncrowIOT/web_scroll_logout_fixes
table scroll, logout, and  fixes
2024-10-23 13:12:07 +03:00
76fbfd2d95 Removed vs_scrollbar package 2024-10-23 13:08:34 +03:00
0b15391868 push logout dialog design 2024-10-23 11:56:48 +03:00
1c9943cfdb finilizing the alert dialog for logut 2024-10-23 02:40:44 +03:00
bd7651fa8c push scroll bar and design enhancment 2024-10-23 01:15:17 +03:00
e01ed33b17 Merge branch 'power_clamp' of https://github.com/SyncrowIOT/web into power_clamp 2024-10-22 13:28:28 +03:00
f0c2560af2 power_clamp 2024-10-22 13:26:36 +03:00
64b84fed82 filter by space 2024-10-22 11:31:49 +04:00
bb5571a02d power_clamp 2024-10-22 10:18:49 +03:00
0b0fee2e26 added community filtering 2024-10-22 10:47:14 +04:00
76f48aad6f added community 2024-10-22 10:22:39 +04:00
c297e02a84 added community to all device 2024-10-22 10:12:08 +04:00
03b5c49df0 added device spaces model 2024-10-21 21:54:22 +04:00
b9ecae7068 power_clamp 2024-10-21 16:50:05 +03:00
97c3b90b76 power_clamp 2024-10-21 16:47:31 +03:00
3684ac4d27 power_clamp 2024-10-21 16:39:10 +03:00
9b0e6ff898 power_clamp 2024-10-20 16:36:45 +03:00
a3a92e5d3f Merge pull request #38 from SyncrowIOT/access_bug_fixes
access_bug_fixes
2024-10-09 21:30:58 +03:00
3102c3823a Bug fixes 2024-10-09 21:29:20 +03:00
d5395f4fe7 Merge pull request #39 from SyncrowIOT/bug_fixes_sprint_10
Bug fixes sprint 10
2024-10-09 20:35:05 +03:00
13e90abf76 access_bug_fixes 2024-10-09 17:43:17 +03:00
308c8a44c5 pull changes 2024-10-09 13:29:12 +03:00
7ca6e60d02 fix notification toggle 2024-10-09 13:28:19 +03:00
853cccbcce Merge pull request #36 from SyncrowIOT/bug_fixes_sprint_10
Bug fixes
2024-10-08 23:18:06 +03:00
03dfeabde4 Bug fixes 2024-10-08 23:14:41 +03:00
62e03bac27 Merge pull request #35 from SyncrowIOT/bug_fixes_sprint_10
fix oct/8 issues
2024-10-08 20:41:01 +03:00
79ec890244 fix oct/8 issues 2024-10-08 20:15:52 +03:00
4653c519c4 Merge pull request #34 from SyncrowIOT/bug_fixes_sprint_10
Bug fixes sprint 10
2024-10-08 12:40:26 +03:00
66f6b1cba9 fix bugs 2024-10-08 11:48:35 +03:00
c06f3d5a58 Changed the color of the device control container 2024-10-08 02:19:59 +03:00
813f2f2693 Fixed design issues 2024-10-08 01:56:09 +03:00
d05328e998 Bug fixes 2024-10-07 22:53:18 +03:00
ab22e15736 Merge pull request #33 from SyncrowIOT/garage_water_leack_devices
push water leak device
2024-10-07 11:58:25 +03:00
9ea8e3be2b push water leak device 2024-10-07 11:26:30 +03:00
889d3dbd02 Merge pull request #32 from SyncrowIOT/garage_water_leack_devices
Garage water leack devices
2024-10-07 10:16:18 +03:00
2b5249e985 push firmware update 2024-10-07 10:06:28 +03:00
e508849fa5 push factory reset 2024-10-07 09:52:16 +03:00
3748fc1419 push garage door preferences 2024-10-07 09:31:33 +03:00
ebde81b64d working on preferences 2024-10-07 07:43:07 +03:00
00277742d0 push garage door records 2024-10-07 01:12:35 +03:00
9733295dca push garage door delay 2024-10-07 00:45:34 +03:00
4f833e86fb push garage door schedule 2024-10-06 23:31:36 +03:00
1e2e2bf4e6 push garage partial garage door 2024-10-06 15:09:36 +03:00
b9bc2ec186 Merge pull request #31 from SyncrowIOT/new_devices_oct
New devices oct
2024-10-05 23:13:20 +03:00
47f1a9a6cd push 3G glass switches 2024-10-04 17:40:52 +03:00
7661f54427 push 1G , 2G glass switches 2024-10-04 17:07:00 +03:00
4fabbf7a77 Merge pull request #30 from SyncrowIOT/sep_bug_fixes2
Sep bug fixes2
2024-10-02 10:40:25 +03:00
30dd3a1ee2 push ac schedule ac fake design 2024-10-02 02:54:18 +03:00
9dbf4b0540 push batch door sensor, design bugs 2024-10-02 01:41:15 +03:00
05d027f8ff Merge pull request #29 from SyncrowIOT/sep_bug_fixes2
schedule bug fixes,  icons and design fixes
2024-10-01 10:28:57 +03:00
0d49ad5106 change themostat widget 2024-10-01 00:32:17 +03:00
9e5d5c0d84 push bug fixes 2024-10-01 00:27:03 +03:00
92d32e4d84 push bug fixes 2024-09-30 19:55:25 +03:00
0731507d3b Merge pull request #28 from SyncrowIOT/sep_bug_fixes
Sep bug fixes
2024-09-25 00:25:28 +03:00
58938d4598 Added syncrow icons, changed the description, increased the width of the control button 2024-09-25 00:23:47 +03:00
e690ddc23a push selectAll bug, design and icons fixes 2024-09-24 22:10:36 +03:00
215fe60bc0 Merge pull request #27 from SyncrowIOT/schedual_view
Schedual view
2024-09-24 12:31:39 +03:00
6568b26cb1 push centered 2 gang switch 2024-09-24 11:01:45 +03:00
d47b0f4c71 push schedules active enable api 2024-09-24 10:45:17 +03:00
f3f6369237 push schedule apis 2024-09-24 00:51:13 +03:00
18265e7b06 Merge pull request #26 from SyncrowIOT/schedual_view
Schedual view
2024-09-23 11:51:05 +03:00
6e3ad984e1 change timer picker theme color 2024-09-23 09:22:32 +03:00
0c530e9ea6 push water heater batch control view 2024-09-23 08:32:49 +03:00
b5eeeedcd2 push ac temp step amount and main door icons 2024-09-23 07:29:04 +03:00
2955533209 push factory reset logic and call for all devices 2024-09-22 21:56:17 +03:00
3a28f0ef9a refactor schedule view and cleaning 2024-09-22 20:47:34 +03:00
b3d891b2c8 add the delete api 2024-09-22 14:51:15 +03:00
f99744338c connecting apis and changes the table design to match figma 2024-09-22 14:17:52 +03:00
66f45721e5 working on schedual table 2024-09-22 00:16:44 +03:00
921ccf0132 push schedule basic design and bloc manegment 2024-09-20 02:27:07 +03:00
26816b99cd push countdown logic 2024-09-20 00:41:59 +03:00
facdef4741 Merge pull request #25 from SyncrowIOT/batch_control
Batch control
2024-09-19 10:24:57 +03:00
208 changed files with 13453 additions and 2016 deletions

View File

@ -1,7 +1,5 @@
# syncrow_web
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.

5
assets/icons/1gang.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M38.0142 39.2553L35.3682 40H20.9308H19.9999H19.0691H1.24111C0.555643 40 0 39.4444 0 38.7589V1.24111C0 0.555643 0.555643 0 1.24111 0H19.0682H20.1226H20.9543H35.4255L38.2625 1.24111C38.9479 1.24111 39.5036 1.79675 39.5036 2.48221L39.2553 38.0142C39.2553 38.6997 38.6997 39.2553 38.0142 39.2553Z" fill="#E9E9E9"/>
<path d="M38.7589 0H35.0356C35.721 0 36.2767 0.555643 36.2767 1.24111V38.7589C36.2767 39.4444 35.721 40 35.0356 40H38.7589C39.4444 40 40 39.4444 40 38.7589V1.24111C40 0.555643 39.4444 0 38.7589 0Z" fill="#D1D1D1"/>
<path opacity="0.6" d="M21.375 31.8319V33.3213C21.375 34.0067 20.9553 34.5624 20.4375 34.5624H16.3125C15.7947 34.5624 15.375 34.0067 15.375 33.3213V31.8319C15.375 31.1465 15.7947 30.5908 16.3125 30.5908H20.4375C20.9553 30.5908 21.375 31.1465 21.375 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 933 B

7
assets/icons/2gang.svg Normal file
View File

@ -0,0 +1,7 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M38.0142 39.2553L35.3682 40H20.9308H19.9999H19.0691H1.24111C0.555643 40 0 39.4444 0 38.7589V1.24111C0 0.555643 0.555643 0 1.24111 0H19.0682H20.1226H20.9543H35.4255L38.2625 1.24111C38.9479 1.24111 39.5036 1.79675 39.5036 2.48221L39.2553 38.0142C39.2553 38.6997 38.6997 39.2553 38.0142 39.2553Z" fill="#E9E9E9"/>
<path d="M38.7589 0H35.0356C35.721 0 36.2767 0.555643 36.2767 1.24111V38.7589C36.2767 39.4444 35.721 40 35.0356 40H38.7589C39.4444 40 40 39.4444 40 38.7589V1.24111C40 0.555643 39.4444 0 38.7589 0Z" fill="#D1D1D1"/>
<path opacity="0.6" d="M12.0284 31.8319V33.3213C12.0284 34.0067 11.6087 34.5624 11.0909 34.5624H6.96594C6.44816 34.5624 6.02844 34.0067 6.02844 33.3213V31.8319C6.02844 31.1465 6.44816 30.5908 6.96594 30.5908H11.0909C11.6087 30.5908 12.0284 31.1465 12.0284 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
<path opacity="0.6" d="M26.0285 31.8319V33.3213C26.0285 34.0067 26.4482 34.5624 26.966 34.5624H31.091C31.6088 34.5624 32.0285 34.0067 32.0285 33.3213V31.8319C32.0285 31.1465 31.6088 30.5908 31.091 30.5908H26.966C26.4482 30.5908 26.0285 31.1465 26.0285 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
<path d="M19.0691 0H20.9308V40H19.0691V0Z" fill="#D1D1D1"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

5
assets/icons/ac_lock.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="25" height="35" viewBox="0 0 25 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.3952 0C7.16271 0.00642578 2.92244 4.24662 2.91602 9.47919V15.3125C2.91602 15.7152 3.2425 16.0417 3.64521 16.0417H6.5619C6.9646 16.0417 7.29109 15.7152 7.29109 15.3125V9.47919C7.29102 6.66019 9.57627 4.375 12.3952 4.375C15.2141 4.375 17.4994 6.66019 17.4994 9.47919V15.3125C17.4994 15.7152 17.8259 16.0417 18.2286 16.0417H21.1452C21.5479 16.0417 21.8744 15.7152 21.8744 15.3125V9.47919C21.868 4.24662 17.6277 0.00642578 12.3952 0Z" fill="#455A64"/>
<path d="M3.64581 14.5833H21.1458C23.1593 14.5833 24.7916 16.2155 24.7916 18.2291V31.3541C24.7916 33.3677 23.1593 34.9999 21.1458 34.9999H3.64581C1.63229 34.9999 0 33.3677 0 31.3541V18.2291C0 16.2155 1.63229 14.5833 3.64581 14.5833Z" fill="#2F66D3"/>
<path d="M16.0417 22.6041C16.0501 20.5906 14.4248 18.9514 12.4112 18.9429C10.3977 18.9344 8.75851 20.5598 8.75003 22.5733C8.74415 23.9651 9.53118 25.2388 10.7785 25.8562L10.2156 29.7937C10.1592 30.1924 10.4367 30.5613 10.8355 30.6177C10.8692 30.6225 10.9034 30.6249 10.9375 30.6249H13.8542C14.2569 30.629 14.5866 30.3059 14.5907 29.9032C14.591 29.8661 14.5886 29.8289 14.5833 29.7922L14.0203 25.8547C15.2524 25.2381 16.0337 23.9817 16.0417 22.6041Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,28 @@
<svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.6724 33.345C25.8803 33.345 33.3447 25.8805 33.3447 16.6726C33.3447 7.46472 25.8803 0.000244141 16.6724 0.000244141C7.46448 0.000244141 0 7.46472 0 16.6726C0 25.8805 7.46448 33.345 16.6724 33.345Z" fill="#F07281"/>
<path d="M17.3767 33.3303C17.1436 33.3401 16.9084 33.345 16.6725 33.345C7.46478 33.345 0 25.8802 0 16.6725C0 7.46478 7.46478 0 16.6725 0C16.9084 0 17.1436 0.00492188 17.3767 0.0147656C8.4957 0.38377 1.40841 7.70068 1.40841 16.6725C1.40841 25.6443 8.4957 32.9613 17.3767 33.3303Z" fill="#EB5569"/>
<path d="M16.6726 31.1577C24.6725 31.1577 31.1577 24.6725 31.1577 16.6726C31.1577 8.67269 24.6725 2.1875 16.6726 2.1875C8.67269 2.1875 2.1875 8.67269 2.1875 16.6726C2.1875 24.6725 8.67269 31.1577 16.6726 31.1577Z" fill="#EAF6FF"/>
<path d="M17.7291 31.1197C17.3805 31.145 17.0276 31.1577 16.6727 31.1577C8.67269 31.1577 2.1875 24.6725 2.1875 16.6725C2.1875 8.67244 8.67275 2.18726 16.6728 2.18726C17.0277 2.18726 17.3805 2.1999 17.7291 2.22526C10.2221 2.76619 4.30022 9.02743 4.30022 16.6725C4.30022 24.3175 10.2221 30.5788 17.7291 31.1197Z" fill="#D8ECFE"/>
<path d="M15.7672 8.23932L16.4138 7.82301C16.5715 7.72143 16.7741 7.72143 16.9319 7.82301L17.5785 8.23932C17.6957 8.31479 17.7666 8.44474 17.7666 8.58419V16.8661H15.5791V8.58419C15.579 8.44474 15.6499 8.31486 15.7672 8.23932Z" fill="#5680A6"/>
<path d="M17.377 8.10996L16.9876 8.36063V16.8662H15.5791V8.62163C15.5791 8.45893 15.6617 8.30738 15.7985 8.21933L16.4136 7.82326C16.5714 7.72167 16.774 7.72167 16.9318 7.82326L17.377 8.10996Z" fill="#497090"/>
<path d="M23.5067 16.9316L23.1106 17.5467C23.0225 17.6835 22.871 17.7662 22.7083 17.7662H16.6729V15.5789H22.7083C22.871 15.5789 23.0225 15.6615 23.1106 15.7983L23.5067 16.4135C23.6083 16.5712 23.6083 16.7738 23.5067 16.9316Z" fill="#5680A6"/>
<path d="M19.6131 16.6725C19.6131 17.0591 19.5384 17.4281 19.4018 17.7662H16.6729V15.5789H19.4018C19.5384 15.9169 19.6131 16.2859 19.6131 16.6725Z" fill="#497090"/>
<path d="M16.6723 18.2039C17.5182 18.2039 18.2039 17.5182 18.2039 16.6723C18.2039 15.8264 17.5182 15.1406 16.6723 15.1406C15.8264 15.1406 15.1406 15.8264 15.1406 16.6723C15.1406 17.5182 15.8264 18.2039 16.6723 18.2039Z" fill="#F07281"/>
<path d="M17.3765 18.0323C17.166 18.1422 16.9265 18.2042 16.6723 18.2042C15.8265 18.2042 15.1406 17.5183 15.1406 16.6725C15.1406 15.8268 15.8265 15.1409 16.6723 15.1409C16.9265 15.1409 17.166 15.2029 17.3765 15.3127C16.885 15.567 16.549 16.081 16.549 16.6726C16.549 17.2642 16.885 17.7781 17.3765 18.0323Z" fill="#EB5569"/>
<path d="M34.5329 28.7151V27.6225C34.5329 27.4043 34.3853 27.2137 34.174 27.1592L32.9876 26.853C32.8555 26.3207 32.6457 25.8193 32.37 25.3617L32.9923 24.3064C33.1032 24.1184 33.0728 23.8793 32.9185 23.7249L32.1459 22.9523C31.9916 22.798 31.7524 22.7676 31.5644 22.8785L30.5091 23.5008C30.0516 23.2251 29.5501 23.0153 29.0178 22.8832L28.7116 21.6968C28.6571 21.4855 28.4665 21.3379 28.2483 21.3379H27.1557C26.9375 21.3379 26.7469 21.4855 26.6924 21.6968L26.3862 22.8832C25.8539 23.0153 25.3525 23.2252 24.8949 23.5008L23.8396 22.8785C23.6516 22.7676 23.4125 22.798 23.2581 22.9523L22.4855 23.7249C22.3313 23.8792 22.3009 24.1184 22.4117 24.3064L23.0341 25.3617C22.7583 25.8193 22.5485 26.3207 22.4164 26.853L21.23 27.1592C21.0188 27.2137 20.8711 27.4043 20.8711 27.6225V28.7151C20.8711 28.9333 21.0188 29.1239 21.23 29.1784L22.4164 29.4846C22.5485 30.0169 22.7584 30.5183 23.0341 30.9759L22.4117 32.0312C22.3008 32.2192 22.3313 32.4583 22.4855 32.6127L23.2581 33.3853C23.4124 33.5396 23.6516 33.5699 23.8396 33.4591L24.8949 32.8368C25.3525 33.1125 25.8539 33.3223 26.3862 33.4544L26.6924 34.6408C26.7469 34.8521 26.9375 34.9997 27.1557 34.9997H28.2483C28.4665 34.9997 28.6571 34.8521 28.7116 34.6408L29.0178 33.4544C29.5501 33.3223 30.0516 33.1124 30.5091 32.8368L31.5644 33.4591C31.7524 33.57 31.9915 33.5396 32.1459 33.3853L32.9185 32.6127C33.0728 32.4584 33.1031 32.2192 32.9923 32.0312L32.37 30.9759C32.6457 30.5183 32.8555 30.0169 32.9876 29.4846L34.174 29.1784C34.3853 29.1239 34.5329 28.9333 34.5329 28.7151Z" fill="#88B4F5"/>
<path d="M22.2796 27.252V29.0858L23.8246 29.4844C23.9563 30.0168 24.1662 30.5182 24.4423 30.976L23.6317 32.3506L24.4057 33.1246L23.8391 33.4588C23.6511 33.5696 23.4119 33.5393 23.2576 33.3849L22.4853 32.6127C22.331 32.4584 22.3007 32.2192 22.4115 32.0313L23.0338 30.976C22.7577 30.5182 22.5479 30.0168 22.4162 29.4844L21.23 29.1784C21.0187 29.124 20.8711 28.9333 20.8711 28.7151V27.6226C20.8711 27.4044 21.0187 27.2139 21.2299 27.1593L22.4162 26.8527C22.5479 26.321 22.7577 25.8189 23.0338 25.3619L22.4115 24.3064C22.3007 24.1185 22.331 23.8794 22.4853 23.7251L23.2577 22.9523C23.4119 22.7978 23.6512 22.7675 23.8392 22.8784L24.4057 23.2125L23.6317 23.9872L24.4423 25.3619C24.1662 25.8189 23.9564 26.321 23.8246 26.8527L22.2796 27.252Z" fill="#6EA2F2"/>
<path d="M27.7946 33.4542L28.1932 35H27.1555C26.9372 35 26.7466 34.8523 26.6921 34.6409L26.3861 33.4542C26.1361 33.393 25.8924 33.3134 25.6572 33.2176L26.303 32.8367C26.7608 33.1126 27.2622 33.3225 27.7946 33.4542Z" fill="#6EA2F2"/>
<path d="M27.1555 21.3379H28.1932L27.7946 22.883C27.2622 23.0154 26.7608 23.2252 26.303 23.5006L25.6572 23.1196C25.8925 23.0245 26.1361 22.945 26.3861 22.883L26.6921 21.6969C26.7466 21.4855 26.9373 21.3379 27.1555 21.3379Z" fill="#6EA2F2"/>
<path d="M27.7023 31.4612C29.5205 31.4612 30.9944 29.9873 30.9944 28.1691C30.9944 26.3509 29.5205 24.877 27.7023 24.877C25.8841 24.877 24.4102 26.3509 24.4102 28.1691C24.4102 29.9873 25.8841 31.4612 27.7023 31.4612Z" fill="#5680A6"/>
<path d="M28.7581 31.2882C28.4264 31.4009 28.0707 31.4615 27.7017 31.4615C25.8841 31.4615 24.4102 29.9875 24.4102 28.1692C24.4102 26.3509 25.8841 24.877 27.7017 24.877C28.0707 24.877 28.4263 24.9375 28.7581 25.0502C27.4588 25.4903 26.5229 26.7206 26.5229 28.1692C26.5229 29.6178 27.4588 30.8481 28.7581 31.2882Z" fill="#497090"/>
<path d="M16.6727 6.19289C16.381 6.19289 16.1445 5.95644 16.1445 5.66475V4.30036C16.1445 4.00867 16.381 3.77222 16.6727 3.77222C16.9644 3.77222 17.2008 4.00867 17.2008 4.30036V5.66468C17.2008 5.95637 16.9644 6.19289 16.6727 6.19289Z" fill="#88B4F5"/>
<path d="M16.6727 29.5729C16.381 29.5729 16.1445 29.3365 16.1445 29.0448V27.6805C16.1445 27.3888 16.381 27.1523 16.6727 27.1523C16.9644 27.1523 17.2008 27.3888 17.2008 27.6805V29.0448C17.2008 29.3364 16.9644 29.5729 16.6727 29.5729Z" fill="#88B4F5"/>
<path d="M5.66492 17.2006H4.30061C4.00892 17.2006 3.77246 16.9641 3.77246 16.6724C3.77246 16.3807 4.00892 16.1443 4.30061 16.1443H5.66492C5.95661 16.1443 6.19307 16.3807 6.19307 16.6724C6.19307 16.9641 5.95661 17.2006 5.66492 17.2006Z" fill="#88B4F5"/>
<path d="M29.0448 17.2006H27.6805C27.3887 17.2006 27.1523 16.9641 27.1523 16.6724C27.1523 16.3807 27.3888 16.1443 27.6805 16.1443H29.0448C29.3366 16.1443 29.5729 16.3807 29.5729 16.6724C29.5729 16.9641 29.3365 17.2006 29.0448 17.2006Z" fill="#88B4F5"/>
<path d="M5.95843 23.3868C5.77591 23.3868 5.59838 23.2921 5.50056 23.1226C5.35468 22.87 5.44122 22.547 5.69388 22.4012L6.8754 21.719C7.12785 21.5733 7.45099 21.6597 7.59687 21.9123C7.74275 22.1649 7.6562 22.488 7.40355 22.6338L6.22202 23.3159C6.1389 23.364 6.04805 23.3868 5.95843 23.3868Z" fill="#88B4F5"/>
<path d="M26.2065 11.6969C26.0239 11.6969 25.8464 11.6022 25.7486 11.4327C25.6027 11.1801 25.6893 10.8571 25.9419 10.7113L27.1234 10.0291C27.376 9.88328 27.699 9.96976 27.8449 10.2224C27.9908 10.475 27.9042 10.7981 27.6516 10.9439L26.4701 11.626C26.3869 11.6741 26.296 11.6969 26.2065 11.6969Z" fill="#88B4F5"/>
<path d="M7.139 11.6967C7.04938 11.6967 6.9586 11.6739 6.8754 11.6259L5.69388 10.9437C5.44122 10.7978 5.35468 10.4748 5.50056 10.2222C5.64637 9.96957 5.96937 9.88296 6.22202 10.0289L7.40355 10.7111C7.6562 10.8569 7.74275 11.1799 7.59687 11.4325C7.49904 11.602 7.32152 11.6967 7.139 11.6967Z" fill="#88B4F5"/>
<path d="M10.4858 27.9156C10.3962 27.9156 10.3054 27.8928 10.2222 27.8447C9.96954 27.6988 9.883 27.3758 10.0289 27.1232L10.711 25.9417C10.8568 25.6891 11.1799 25.6024 11.4325 25.7484C11.6852 25.8943 11.7717 26.2173 11.6258 26.4699L10.9437 27.6514C10.8458 27.8208 10.6683 27.9156 10.4858 27.9156Z" fill="#88B4F5"/>
<path d="M22.1762 7.66776C22.0866 7.66776 21.9958 7.64492 21.9126 7.59687C21.66 7.45106 21.5734 7.12799 21.7193 6.8754L22.4015 5.69388C22.5473 5.44122 22.8702 5.35468 23.1229 5.50056C23.3755 5.64637 23.4621 5.96944 23.3162 6.22202L22.6341 7.40355C22.5363 7.57301 22.3587 7.66776 22.1762 7.66776Z" fill="#88B4F5"/>
<path d="M11.1689 7.66776C10.9864 7.66776 10.8089 7.57301 10.711 7.40355L10.0289 6.22202C9.883 5.96944 9.96954 5.64637 10.2222 5.50056C10.4747 5.35468 10.7979 5.44122 10.9437 5.69388L11.6258 6.8754C11.7717 7.12799 11.6852 7.45106 11.4325 7.59687C11.3494 7.64486 11.2585 7.66776 11.1689 7.66776Z" fill="#88B4F5"/>
</svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -0,0 +1,6 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.892857 12.1429H2.44054C2.60714 12.733 2.84125 13.2989 3.13875 13.8311L2.04518 14.9246C1.87643 15.0932 1.78357 15.3175 1.78357 15.5561C1.78357 15.7946 1.87661 16.0188 2.04518 16.1873L3.43196 17.5741C3.57125 17.7136 3.7975 17.7136 3.93696 17.5741C4.07643 17.4346 4.07643 17.2086 3.93696 17.0691L2.55018 15.6821C2.50464 15.6368 2.49786 15.5836 2.49786 15.5559C2.49786 15.5282 2.50464 15.4752 2.55018 15.4295L3.83821 14.1414C3.95464 14.025 3.97643 13.8441 3.89089 13.7034C3.51482 13.0843 3.23607 12.4105 3.0625 11.7009C3.02357 11.5411 2.88018 11.4286 2.71571 11.4286H0.892857C0.794464 11.4286 0.714286 11.3484 0.714286 11.25V8.75C0.714286 8.65161 0.794464 8.57143 0.892857 8.57143H2.71571C2.88036 8.57143 3.02357 8.45893 3.06268 8.29911C3.23607 7.58964 3.51482 6.91571 3.89107 6.29661C3.97661 6.15589 3.95464 5.975 3.83839 5.85857L2.55036 4.57054C2.50482 4.525 2.49804 4.47179 2.49804 4.44411C2.49804 4.41661 2.50482 4.36339 2.55036 4.31786L4.31804 2.55C4.38786 2.48018 4.50089 2.48036 4.57071 2.55L5.85875 3.83821C5.97518 3.95464 6.15607 3.97643 6.29679 3.89089C6.91607 3.51464 7.58982 3.23589 8.29929 3.0625C8.45893 3.02357 8.57143 2.88018 8.57143 2.71571V0.892857C8.57143 0.794464 8.65161 0.714286 8.75 0.714286H11.25C11.3484 0.714286 11.4286 0.794464 11.4286 0.892857V2.71571C11.4286 2.88036 11.5411 3.02357 11.7009 3.06268C12.4104 3.23607 13.0843 3.51482 13.7034 3.89107C13.8441 3.97661 14.0252 3.95482 14.1414 3.83839L15.4295 2.55036C15.4991 2.48071 15.6125 2.48054 15.6821 2.55036L17.4498 4.31821C17.4954 4.36357 17.5021 4.41679 17.5021 4.44446C17.5021 4.47214 17.4954 4.52518 17.4498 4.57089L16.1618 5.85893C16.0454 5.97536 16.0236 6.15625 16.1091 6.29696C16.4854 6.91625 16.7641 7.59 16.9375 8.29946C16.9766 8.45929 17.1198 8.57179 17.2845 8.57179H19.1071C19.2055 8.57179 19.2857 8.65196 19.2857 8.75036V11.2504C19.2857 11.3488 19.2055 11.4289 19.1071 11.4289H17.2843C17.1196 11.4289 16.9764 11.5414 16.9373 11.7013C16.7639 12.4111 16.4852 13.0848 16.1089 13.7037C16.0234 13.8445 16.0452 14.0254 16.1616 14.1418L17.4496 15.4298C17.4952 15.4754 17.502 15.5286 17.502 15.5562C17.502 15.5837 17.4952 15.637 17.4496 15.6825L16.0629 17.0693C15.9234 17.2087 15.9234 17.4348 16.0629 17.5743C16.1327 17.6441 16.2239 17.6789 16.3154 17.6789C16.4068 17.6789 16.4982 17.6441 16.5679 17.5743L17.9546 16.1875C18.1232 16.0189 18.2163 15.7946 18.2163 15.5561C18.2163 15.3175 18.1234 15.0934 17.9546 14.9246L16.8611 13.8311C17.1586 13.2989 17.3927 12.7332 17.5593 12.1429H19.1071C19.5995 12.1429 20 11.7423 20 11.25V8.75C20 8.25768 19.5995 7.85714 19.1071 7.85714H17.5595C17.3929 7.26714 17.1588 6.70125 16.8612 6.16911L17.9548 5.07554C18.1236 4.90696 18.2164 4.68268 18.2164 4.44411C18.2164 4.20554 18.1234 3.98143 17.9548 3.81286L16.1871 2.045C15.8391 1.69696 15.2727 1.69679 14.9245 2.045L13.8309 3.13857C13.2988 2.84107 12.7329 2.60696 12.1429 2.44036V0.892857C12.1429 0.400536 11.7423 0 11.25 0H8.75C8.25768 0 7.85714 0.400536 7.85714 0.892857V2.44054C7.26714 2.60714 6.70125 2.84125 6.16911 3.13875L5.07554 2.045C4.72732 1.69696 4.16089 1.69696 3.81286 2.045L2.04518 3.81268C1.87661 3.98125 1.78357 4.20554 1.78357 4.44411C1.78357 4.68268 1.87643 4.90679 2.04518 5.07554L3.13875 6.16911C2.84125 6.70125 2.60714 7.26714 2.44054 7.85714H0.892857C0.400536 7.85714 0 8.25768 0 8.75V11.25C0 11.7423 0.400536 12.1429 0.892857 12.1429Z" fill="black"/>
<path d="M13.3929 9.28568C13.3929 7.41479 11.8709 5.89282 10 5.89282C8.12914 5.89282 6.60718 7.41479 6.60718 9.28568C6.60718 11.1566 8.12914 12.6785 10 12.6785C11.8709 12.6785 13.3929 11.1566 13.3929 9.28568ZM7.32146 9.28568C7.32146 7.80871 8.52307 6.60711 10 6.60711C11.477 6.60711 12.6786 7.80871 12.6786 9.28568C12.6786 10.7626 11.477 11.9643 10 11.9643C8.52307 11.9643 7.32146 10.7626 7.32146 9.28568Z" fill="black"/>
<path d="M4.64282 17.3214V18.75C4.64282 19.4393 5.20354 20 5.89282 20H14.1071C14.7964 20 15.3571 19.4393 15.3571 18.75V17.3214C15.3571 15.1551 13.5948 13.3928 11.4285 13.3928H8.57139C6.40514 13.3928 4.64282 15.1551 4.64282 17.3214ZM8.57139 14.1071H11.4285C13.2009 14.1071 14.6428 15.5491 14.6428 17.3214V18.75C14.6428 19.0453 14.4025 19.2857 14.1071 19.2857H5.89282C5.59747 19.2857 5.35711 19.0453 5.35711 18.75V17.3214C5.35711 15.5491 6.79907 14.1071 8.57139 14.1071Z" fill="black"/>
<path d="M10.3571 15.7143H11.3048C12.1607 15.7143 12.8571 16.4107 12.8571 17.2666C12.8571 17.4638 13.0171 17.6238 13.2143 17.6238C13.4114 17.6238 13.5714 17.4638 13.5714 17.2666C13.5714 16.0168 12.5546 15 11.3048 15H10.3571C10.16 15 10 15.16 10 15.3571C10 15.5543 10.16 15.7143 10.3571 15.7143Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1,17 @@
<svg width="35" height="36" viewBox="0 0 35 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.7648 0H11.3236C9.61799 0 8.23535 1.38264 8.23535 3.08824V32.049C8.23535 33.7546 9.61799 35.1373 11.3236 35.1373H31.9118C33.6174 35.1373 35.0001 33.7546 35.0001 32.049V8.23529L26.7648 0Z" fill="#E4F2F9"/>
<path d="M26.7642 0H21.6172V35.1373H31.9113C33.6169 35.1373 34.9995 33.7546 34.9995 32.049V8.23529L26.7642 0Z" fill="#BDE0F1"/>
<path d="M26.7646 0V7.20588C26.7646 7.77439 27.2256 8.23529 27.7941 8.23529H34.9999L26.7646 0Z" fill="#77BEE2"/>
<path d="M29.1675 20.7258H14.0695C13.5009 20.7258 13.04 20.2649 13.04 19.6964C13.04 19.1279 13.5009 18.667 14.0695 18.667H29.1675C29.736 18.667 30.1969 19.1279 30.1969 19.6964C30.1969 20.2649 29.736 20.7258 29.1675 20.7258Z" fill="#5F5F82"/>
<path d="M29.1675 14.5491H14.0695C13.5009 14.5491 13.04 14.0882 13.04 13.5196C13.04 12.9511 13.5009 12.4902 14.0695 12.4902H29.1675C29.736 12.4902 30.1969 12.9511 30.1969 13.5196C30.1969 14.0882 29.736 14.5491 29.1675 14.5491Z" fill="#5F5F82"/>
<path d="M29.1675 26.9026H14.0695C13.5009 26.9026 13.04 26.4417 13.04 25.8732C13.04 25.3047 13.5009 24.8438 14.0695 24.8438H29.1675C29.736 24.8438 30.1969 25.3047 30.1969 25.8732C30.1969 26.4417 29.736 26.9026 29.1675 26.9026Z" fill="#5F5F82"/>
<path d="M30.1956 19.6954C30.1956 19.1269 29.7347 18.666 29.1662 18.666H21.6172V20.7248H29.1662C29.7347 20.7248 30.1956 20.2639 30.1956 19.6954Z" fill="#3C3C55"/>
<path d="M30.1956 13.5196C30.1956 12.9511 29.7347 12.4902 29.1662 12.4902H21.6172V14.5491H29.1662C29.7347 14.5491 30.1956 14.0882 30.1956 13.5196Z" fill="#3C3C55"/>
<path d="M29.1662 26.9016C29.7347 26.9016 30.1956 26.4407 30.1956 25.8722C30.1956 25.3037 29.7347 24.8428 29.1662 24.8428H21.6172V26.9016H29.1662Z" fill="#3C3C55"/>
<path d="M9.26471 35.1368C4.15615 35.1368 0 30.9807 0 25.8721C0 20.7636 4.15615 16.6074 9.26471 16.6074C14.3733 16.6074 18.5294 20.7636 18.5294 25.8721C18.5294 30.9807 14.3733 35.1368 9.26471 35.1368Z" fill="#FF7350"/>
<path d="M9.26465 16.6074V35.1368C14.3732 35.1368 18.5294 30.9807 18.5294 25.8721C18.5294 20.7636 14.3732 16.6074 9.26465 16.6074Z" fill="#FF4B20"/>
<path d="M9.26448 18.666C5.29115 18.666 2.05859 21.8986 2.05859 25.8719C2.05859 29.8452 5.29115 33.0778 9.26448 33.0778C13.2378 33.0778 16.4704 29.8452 16.4704 25.8719C16.4704 21.8986 13.2378 18.666 9.26448 18.666Z" fill="#E4F2F9"/>
<path d="M9.26465 18.666V33.0778C13.238 33.0778 16.4705 29.8452 16.4705 25.8719C16.4705 21.8986 13.238 18.666 9.26465 18.666Z" fill="#BDE0F1"/>
<path d="M12.0099 24.8432H10.2942V21.755C10.2942 21.1865 9.83327 20.7256 9.26476 20.7256C8.69625 20.7256 8.23535 21.1865 8.23535 21.755V25.8726C8.23535 26.4412 8.69625 26.9021 9.26476 26.9021H12.0099C12.5784 26.9021 13.0393 26.4412 13.0393 25.8726C13.0393 25.3041 12.5784 24.8432 12.0099 24.8432Z" fill="#5F5F82"/>
<path d="M12.0097 24.8432H10.2941V21.755C10.2941 21.1865 9.83316 20.7256 9.26465 20.7256V26.9021H12.0097C12.5783 26.9021 13.0392 26.4412 13.0392 25.8726C13.0392 25.3041 12.5783 24.8432 12.0097 24.8432Z" fill="#3C3C55"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,135 @@
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.39648 12.4951H35.6037V37.8285H2.39648V12.4951Z" fill="url(#paint0_linear_3415_983)"/>
<path d="M2.40332 20.3789H14.3054V38.0005H2.40332V20.3789Z" fill="url(#paint1_linear_3415_983)"/>
<g clip-path="url(#clip0_3415_983)">
<path d="M2.40332 19.1719H35.5958V29.3425H2.40332V19.1719Z" fill="url(#paint2_linear_3415_983)"/>
<path d="M2.45801 11.9824H35.6149V15.9314H2.45801V11.9824Z" fill="url(#paint3_linear_3415_983)"/>
<path d="M2.45801 15.1123H35.6149V19.0613H2.45801V15.1123Z" fill="url(#paint4_linear_3415_983)"/>
<path d="M2.45801 18.3154H35.6149V22.2644H2.45801V18.3154Z" fill="url(#paint5_linear_3415_983)"/>
<path d="M2.45801 21.3965H35.6149V25.3455H2.45801V21.3965Z" fill="url(#paint6_linear_3415_983)"/>
<path d="M2.45801 24.5264H35.6149V28.4754H2.45801V24.5264Z" fill="url(#paint7_linear_3415_983)"/>
<path d="M2.45801 27.7305H35.6149V31.6795H2.45801V27.7305Z" fill="url(#paint8_linear_3415_983)"/>
<path d="M2.45801 30.8594H35.6149V34.8084H2.45801V30.8594Z" fill="url(#paint9_linear_3415_983)"/>
<path d="M2.45801 33.9893H35.6149V37.9383H2.45801V33.9893Z" fill="url(#paint10_linear_3415_983)"/>
</g>
<path d="M36.3054 9.43704L22.7255 0.961176C21.6987 0.320392 20.3494 0 19 0C17.6506 0 16.3013 0.320392 15.2745 0.961176L1.69458 9.43704C0.640486 10.095 0 11.2497 0 12.4923V35.6368C0 36.942 1.05804 38 2.36323 38C3.03367 38 3.57722 37.4565 3.57722 36.786V15.833C3.57722 14.4546 4.69464 13.3373 6.07292 13.3373H31.9271C33.3054 13.3373 34.4228 14.4546 34.4228 15.833V36.786C34.4228 37.4565 34.9663 38 35.6368 38C36.942 38 38 36.942 38 35.6368V12.4923C38 11.2497 37.3595 10.095 36.3054 9.43704Z" fill="url(#paint11_linear_3415_983)"/>
<path d="M36.3054 9.43704L22.7255 0.961177C21.6987 0.320392 20.3494 0 19 0C17.6506 0 16.3013 0.320392 15.2745 0.961177L1.69458 9.43704C0.640486 10.095 0 11.2497 0 12.4923V16.0686C0 14.8261 0.640486 13.6713 1.69458 13.0134L15.2745 4.53743C16.3013 3.89664 17.6506 3.57625 19 3.57625C20.3494 3.57625 21.6987 3.89664 22.7255 4.53743L36.3054 13.0133C37.3595 13.6712 38 14.826 38 16.0686V12.4923C38 11.2497 37.3595 10.095 36.3054 9.43704Z" fill="url(#paint12_linear_3415_983)"/>
<path d="M14.7543 8.44803H23.2456C23.7264 8.44803 24.1161 8.05827 24.1161 7.57753C24.1161 7.09672 23.7264 6.70703 23.2456 6.70703H14.7543C14.2735 6.70703 13.8838 7.09679 13.8838 7.57753C13.8838 8.05827 14.2735 8.44803 14.7543 8.44803Z" fill="url(#paint13_linear_3415_983)"/>
<path d="M14.7543 11.6512H23.2456C23.7264 11.6512 24.1161 11.2614 24.1161 10.7807C24.1161 10.2998 23.7264 9.91016 23.2456 9.91016H14.7543C14.2735 9.91016 13.8838 10.2999 13.8838 10.7807C13.8838 11.2614 14.2735 11.6512 14.7543 11.6512Z" fill="url(#paint14_linear_3415_983)"/>
<path d="M38 16.0685V35.6363C38 36.289 37.7355 36.8798 37.3078 37.3075C36.8801 37.7352 36.2893 37.9997 35.6366 37.9997C34.966 37.9997 34.4228 37.4565 34.4228 36.7859V15.8323C34.4228 14.4546 33.3051 13.337 31.9267 13.337H6.07329C4.69486 13.337 3.57722 14.4546 3.57722 15.8323V36.7859C3.57722 37.1212 3.44161 37.4245 3.2218 37.6443C3.002 37.8641 2.69875 37.9997 2.36345 37.9997C1.05804 37.9997 0 36.9417 0 35.6363V16.0685C0 14.8257 0.640784 13.6708 1.69435 13.0128L15.2745 4.53735C16.3013 3.89656 17.6506 3.57617 19 3.57617C20.3494 3.57617 21.6987 3.89656 22.7255 4.53735L36.3056 13.0128C37.3592 13.6708 38 14.8257 38 16.0685Z" fill="url(#paint15_linear_3415_983)"/>
<path d="M19.0745 1.49121C16.8994 1.49121 14.7908 2.11724 12.9767 3.30173C12.4945 3.61653 12.3588 4.2626 12.6736 4.74476L14.39 6.46646C14.3263 6.69416 14.3564 6.94682 14.4952 7.16066L16.0917 8.77879C16.0317 8.96194 16.0515 9.16945 16.1637 9.34417L17.8679 11.0139C17.7547 11.4323 17.8613 11.8978 18.1898 12.2264L19.3006 13.3372H31.927C33.3054 13.3372 34.4227 14.4546 34.4227 15.8329V28.4594L38 32.0366V16.1358L25.1723 3.30173C23.3583 2.11732 21.2496 1.49121 19.0745 1.49121Z" fill="url(#paint16_linear_3415_983)"/>
<path d="M21.7117 8.35279C20.9031 7.83324 19.9655 7.55859 19.0005 7.55859C18.0355 7.55859 17.0981 7.83324 16.2893 8.35272C15.981 8.55084 15.8917 8.96132 16.0897 9.26956C16.2878 9.57781 16.6982 9.66715 17.0066 9.46917C17.6009 9.08739 18.2904 8.88554 19.0005 8.88554C19.7107 8.88554 20.4002 9.08739 20.9945 9.46917C21.1055 9.54048 21.2296 9.57453 21.3525 9.57453C21.5708 9.57453 21.7846 9.46686 21.9113 9.26956C22.1094 8.96139 22.02 8.55084 21.7117 8.35279Z" fill="url(#paint17_linear_3415_983)"/>
<path d="M23.3287 5.90666C22.0398 5.06947 20.543 4.62695 19.0002 4.62695C17.4574 4.62695 15.9607 5.06947 14.6717 5.90658C14.2766 6.1632 14.1643 6.69155 14.421 7.08667C14.6776 7.4818 15.206 7.59401 15.6011 7.3374C16.6127 6.68037 17.7881 6.33308 19.0002 6.33308C20.2123 6.33308 21.3878 6.68037 22.3994 7.3374C22.5429 7.43061 22.704 7.47517 22.8632 7.47517C23.1424 7.47517 23.416 7.33822 23.5794 7.08667C23.8361 6.69155 23.7238 6.16327 23.3287 5.90666Z" fill="url(#paint18_linear_3415_983)"/>
<path d="M25.0982 3.22758C23.2841 2.0431 21.1755 1.41699 19.0003 1.41699C16.8252 1.41699 14.7166 2.04302 12.9024 3.22751C12.4203 3.54231 12.2846 4.18838 12.5994 4.67054C12.9142 5.15269 13.5603 5.28837 14.0424 4.97357C15.5167 4.01105 17.2311 3.5023 19.0003 3.5023C20.7696 3.5023 22.484 4.01105 23.9582 4.97364C24.134 5.08846 24.3317 5.14338 24.5272 5.14338C24.8676 5.14338 25.2013 4.97692 25.4012 4.67061C25.716 4.18846 25.5804 3.54238 25.0982 3.22758Z" fill="url(#paint19_linear_3415_983)"/>
<path d="M19.0002 12.5189C19.6912 12.5189 20.2514 11.9588 20.2514 11.2678C20.2514 10.5768 19.6912 10.0166 19.0002 10.0166C18.3092 10.0166 17.749 10.5768 17.749 11.2678C17.749 11.9588 18.3092 12.5189 19.0002 12.5189Z" fill="url(#paint20_linear_3415_983)"/>
<defs>
<linearGradient id="paint0_linear_3415_983" x1="19.0001" y1="22.0548" x2="19.0001" y2="35.447" 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_3415_983" x1="6.55642" y1="29.1897" x2="2.75642" y2="29.1897" 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_3415_983" x1="18.9996" y1="25.2444" x2="18.9996" y2="20.1772" 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_3415_983" x1="19.0364" y1="13.4726" x2="19.0364" y2="15.5602" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint4_linear_3415_983" x1="19.0364" y1="16.6025" x2="19.0364" y2="18.6901" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint5_linear_3415_983" x1="19.0364" y1="19.8056" x2="19.0364" y2="21.8932" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint6_linear_3415_983" x1="19.0364" y1="22.8867" x2="19.0364" y2="24.9743" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint7_linear_3415_983" x1="19.0364" y1="26.0166" x2="19.0364" y2="28.1042" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint8_linear_3415_983" x1="19.0364" y1="29.2207" x2="19.0364" y2="31.3083" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint9_linear_3415_983" x1="19.0364" y1="32.3496" x2="19.0364" y2="34.4372" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint10_linear_3415_983" x1="19.0364" y1="35.4795" x2="19.0364" y2="37.5671" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint11_linear_3415_983" x1="8.5956" y1="5.36746" x2="26.3289" y2="36.9596" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint12_linear_3415_983" x1="19" y1="-5.51269" x2="19" y2="16.7501" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint13_linear_3415_983" x1="18.9999" y1="8.21578" x2="18.9999" y2="6.61255" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint14_linear_3415_983" x1="18.9999" y1="11.4189" x2="18.9999" y2="9.81568" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint15_linear_3415_983" x1="13.1332" y1="14.0993" x2="9.70572" y2="7.31888" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint16_linear_3415_983" x1="28.616" y1="14.9578" x2="17.9611" y2="0.279385" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint17_linear_3415_983" x1="18.4669" y1="7.38439" x2="19.3768" y2="9.98784" 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_3415_983" x1="18.2352" y1="3.84222" x2="19.2715" y2="7.60831" 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_3415_983" x1="18.1995" y1="1.17089" x2="19.3116" y2="5.24031" 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_3415_983" x1="17.7869" y1="10.0545" x2="19.7964" y2="12.064" 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_3415_983">
<rect width="33.2119" height="25.9556" fill="white" transform="translate(2.40332 11.9824)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,29 @@
<svg width="35" height="34" viewBox="0 0 35 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.5355 9.24578H10.4576C10.1702 9.24578 9.93727 9.01288 9.93727 8.72543C9.93727 8.43798 10.1702 8.20508 10.4576 8.20508H17.5355C17.8229 8.20508 18.0559 8.43798 18.0559 8.72543C18.0559 9.01288 17.8229 9.24578 17.5355 9.24578ZM6.9905 9.24578H0.520352C0.232969 9.24578 0 9.01288 0 8.72543C0 8.43798 0.2329 8.20508 0.520352 8.20508H6.9905C7.27788 8.20508 7.51085 8.43798 7.51085 8.72543C7.51085 9.01288 7.27788 9.24578 6.9905 9.24578Z" fill="#D9EEFF"/>
<path d="M7.49238 12.8874H2.60141C2.31402 12.8874 2.08105 12.6545 2.08105 12.367C2.08105 12.0796 2.31396 11.8467 2.60141 11.8467H7.49238C7.77977 11.8467 8.01273 12.0796 8.01273 12.367C8.01267 12.6545 7.77977 12.8874 7.49238 12.8874Z" fill="#D9EEFF"/>
<path d="M4.18018 20.1706H0.520352C0.232969 20.1706 0 19.9377 0 19.6502C0 19.3628 0.2329 19.1299 0.520352 19.1299H4.18018C4.46756 19.1299 4.70053 19.3628 4.70053 19.6502C4.70053 19.9377 4.46756 20.1706 4.18018 20.1706Z" fill="#D9EEFF"/>
<path d="M8.2021 23.8132H2.20199C1.91461 23.8132 1.68164 23.5803 1.68164 23.2928C1.68164 23.0054 1.91454 22.7725 2.20199 22.7725H8.2021C8.48948 22.7725 8.72245 23.0054 8.72245 23.2928C8.72245 23.5802 8.48955 23.8132 8.2021 23.8132Z" fill="#D9EEFF"/>
<path d="M6.26145 27.4548H3.71273C3.42535 27.4548 3.19238 27.2219 3.19238 26.9344C3.19238 26.647 3.42528 26.4141 3.71273 26.4141H6.26145C6.54883 26.4141 6.7818 26.647 6.7818 26.9344C6.78173 27.2219 6.54883 27.4548 6.26145 27.4548Z" fill="#D9EEFF"/>
<path d="M14.4701 31.0964H6.78207C6.49469 31.0964 6.26172 30.8635 6.26172 30.576C6.26172 30.2886 6.49462 30.0557 6.78207 30.0557H14.4701C14.7575 30.0557 14.9905 30.2886 14.9905 30.576C14.9905 30.8634 14.7576 31.0964 14.4701 31.0964Z" fill="#D9EEFF"/>
<path d="M8.83613 16.529H4.79281C4.50543 16.529 4.27246 16.2961 4.27246 16.0086C4.27246 15.7212 4.50536 15.4883 4.79281 15.4883H8.83613C9.12352 15.4883 9.35648 15.7212 9.35648 16.0086C9.35648 16.2961 9.12352 16.529 8.83613 16.529Z" fill="#D9EEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.5953 3.04199L22.9434 7.74231C23.7969 7.84854 24.6523 8.03927 25.4999 8.31852C26.3475 8.59776 27.1499 8.95378 27.8992 9.3746L29.5512 4.67428L24.5953 3.04199Z" fill="#EFF6FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.2115 0.527932L22.5999 2.38444C22.4682 2.78564 22.6864 3.22225 23.0876 3.35398L24.2637 3.73945L29.2176 5.37181L30.3916 5.75927C30.7928 5.89107 31.2294 5.67074 31.3612 5.26954L31.9728 3.41304C32.1045 3.01184 31.8843 2.57523 31.4831 2.4435L24.1811 0.0382052C23.7799 -0.0935917 23.3432 0.126731 23.2115 0.527932Z" fill="#375E7D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.3903 5.75932C30.7915 5.89111 31.2281 5.67079 31.3599 5.26959L31.9715 3.41309C32.1032 3.01188 31.8829 2.57527 31.4818 2.44354L29.6725 1.84766C30.0738 1.97945 30.294 2.416 30.1622 2.8172L29.5506 4.6737C29.4189 5.0749 28.9823 5.29516 28.5811 5.16343H28.585L29.2163 5.37192L30.3903 5.75932Z" fill="#2B4D66"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.3254 33.1402C24.3875 35.4648 31.9963 31.6259 34.3208 24.5655C36.368 18.3528 33.6404 11.7153 28.1456 8.62577C27.3964 8.20488 26.594 7.84893 25.7464 7.56968C24.8987 7.29043 24.0433 7.09964 23.1898 6.99348C20.2104 6.62181 17.2585 7.27075 14.7609 8.72414C12.0175 10.3211 9.82274 12.8915 8.75291 16.1443C6.42644 23.2046 10.2652 30.8156 17.3254 33.1402Z" fill="#375E7D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.8179 10.3919C19.3153 8.57866 13.386 11.5719 11.5728 17.0746C9.76154 22.5774 12.7527 28.5069 18.2553 30.3182C23.7579 32.1314 29.6872 29.1401 31.5004 23.6374L31.5063 23.6177C33.3057 18.1209 30.3145 12.2012 24.8179 10.3919Z" fill="#EFF6FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.8169 10.3926L22.0833 18.6919C21.7666 19.6517 22.3763 20.5563 23.1865 20.8788L31.5053 23.6184C33.3047 18.1216 30.3135 12.2019 24.8169 10.3926Z" fill="#EB5468"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M31.5064 23.6184C33.0836 18.8001 30.9793 13.6573 26.7354 11.2422C27.4807 13.4665 27.8917 15.913 27.8917 18.4814C27.8917 19.7991 27.7836 21.0853 27.5771 22.3243L31.5064 23.6184Z" fill="#E5384F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.3205 24.5668C36.3677 18.3541 33.64 11.7166 28.1453 8.62706C27.5947 8.3163 27.0145 8.04293 26.4088 7.80894C26.1905 7.72437 25.9703 7.64569 25.746 7.57098C25.4825 7.48443 25.219 7.40575 24.9535 7.33691C25.6654 8.53266 26.2671 9.8444 26.7352 11.2427C30.9792 13.6578 33.0834 18.8006 31.5062 23.6189C31.5042 23.6248 31.5022 23.6307 31.5003 23.6386C30.3735 27.0566 27.6596 29.5051 24.4461 30.4353C23.5828 31.7294 22.5837 32.8701 21.4746 33.8199C27.1522 33.8475 32.4483 30.2524 34.3205 24.5668Z" fill="#2B4D66"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.4453 30.4347C27.6588 29.5045 30.3727 27.056 31.4995 23.6379L31.5054 23.6183L27.5761 22.3242C27.2103 24.5249 26.5377 26.5801 25.6173 28.415C25.2615 29.123 24.8701 29.7975 24.4453 30.4347Z" fill="#D9EEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.1457 8.62614L29.2175 5.37135L28.5823 5.16285L27.4083 4.77539L26.4092 7.80802C27.0149 8.04208 27.5951 8.31545 28.1457 8.62614Z" fill="#D9EEFF"/>
<path d="M18.2667 30.8037C18.2127 30.8037 18.1578 30.7952 18.1038 30.7774C17.8308 30.6875 17.6824 30.3934 17.7724 30.1204L18.3329 28.4192C18.4227 28.1462 18.7166 27.9978 18.9899 28.0879C19.2629 28.1778 19.4113 28.4719 19.3212 28.7449L18.7608 30.4461C18.6886 30.665 18.4852 30.8037 18.2667 30.8037Z" fill="#375E7D"/>
<path d="M13.2968 18.1426C13.2428 18.1426 13.1879 18.1341 13.1337 18.1162L11.4346 17.5557C11.1617 17.4657 11.0134 17.1715 11.1035 16.8985C11.1935 16.6257 11.4874 16.4771 11.7607 16.5675L13.4598 17.128C13.7327 17.218 13.881 17.5122 13.7909 17.7852C13.7187 18.0039 13.5153 18.1426 13.2968 18.1426Z" fill="#375E7D"/>
<path d="M17.6349 13.1075C17.4448 13.1075 17.2617 13.003 17.1701 12.8218L16.3617 11.2229C16.2321 10.9665 16.3349 10.6534 16.5914 10.5238C16.8478 10.3943 17.1609 10.497 17.2905 10.7534L18.0988 12.3523C18.2285 12.6087 18.1256 12.9217 17.8692 13.0514C17.7939 13.0894 17.7138 13.1075 17.6349 13.1075Z" fill="#375E7D"/>
<path d="M26.2598 30.2062C26.0695 30.2062 25.8862 30.1015 25.7948 29.9201L24.9885 28.3211C24.8591 28.0646 24.9622 27.7516 25.2188 27.6223C25.4753 27.4928 25.7882 27.5959 25.9176 27.8526L26.7239 29.4515C26.8533 29.7081 26.7502 30.021 26.4936 30.1504C26.4185 30.1882 26.3385 30.2062 26.2598 30.2062Z" fill="#375E7D"/>
<path d="M12.1947 25.5749C12.0044 25.5749 11.8211 25.4701 11.7297 25.2887C11.6003 25.0321 11.7034 24.7193 11.96 24.5899L13.5589 23.7835C13.8154 23.6539 14.1284 23.7571 14.2577 24.0138C14.3872 24.2704 14.2841 24.5832 14.0274 24.7126L12.4285 25.519C12.3534 25.5569 12.2735 25.5749 12.1947 25.5749Z" fill="#375E7D"/>
<path d="M20.1233 19.7372C19.9981 19.7372 19.8727 19.6924 19.7729 19.6015L15.995 16.1578C15.7826 15.9641 15.7674 15.6351 15.9609 15.4227C16.1545 15.2103 16.4835 15.1952 16.696 15.3887L20.4739 18.8324C20.6862 19.026 20.7014 19.355 20.5079 19.5674C20.4053 19.68 20.2646 19.7372 20.1233 19.7372Z" fill="#375E7D"/>
<path d="M21.9851 24.5472C21.7247 24.5472 21.5 24.3522 21.469 24.0872L21.2409 22.1344C21.2075 21.849 21.4118 21.5906 21.6973 21.5572C21.9817 21.5243 22.2411 21.7281 22.2745 22.0136L22.5026 23.9665C22.5359 24.2519 22.3316 24.5103 22.0461 24.5437C22.0257 24.546 22.0053 24.5472 21.9851 24.5472Z" fill="#375E7D"/>
<path d="M21.5489 31.3714C20.3897 31.3714 19.2254 31.1861 18.0923 30.8128C12.3267 28.9149 9.18023 22.6793 11.0784 16.9125C11.999 14.1188 13.9519 11.8507 16.5773 10.5258C19.2032 9.2007 22.1875 8.97792 24.9806 9.89831C30.7348 11.7925 33.8839 18.0161 32.0028 23.7739L31.9987 23.7875C31.9974 23.7919 31.996 23.7964 31.9946 23.8008C31.0741 26.5942 29.1212 28.862 26.4957 30.1864C24.9349 30.9734 23.2474 31.3714 21.5489 31.3714ZM21.5263 10.3809C19.9878 10.3809 18.4597 10.7414 17.0461 11.4547C14.6687 12.6544 12.9004 14.7083 12.0668 17.2379C10.3481 22.4595 13.1971 28.1058 18.4178 29.8243C20.9472 30.6578 23.6495 30.4564 26.0269 29.2571C28.4023 28.0589 30.1696 26.008 31.004 23.4815L31.0079 23.4687C31.0091 23.4646 31.0104 23.4604 31.0117 23.4564C32.7189 18.2411 29.8674 12.6024 24.6551 10.8866C24.655 10.8866 24.6549 10.8865 24.6549 10.8865C23.6295 10.5486 22.5755 10.3809 21.5263 10.3809Z" fill="#FFC250"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.0847 18.6918C21.1762 18.3928 20.1968 18.8865 19.8978 19.7951C19.5989 20.7037 20.0925 21.6831 21.0011 21.982C21.9096 22.281 22.889 21.7874 23.188 20.8787C23.4869 19.9702 22.9933 18.9907 22.0847 18.6918Z" fill="#FFE07D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.1879 20.8785C23.4868 19.97 22.9932 18.9905 22.0846 18.6916C21.6107 18.5362 21.117 18.5952 20.71 18.8174C21.5497 19.1557 21.9942 20.0938 21.7071 20.967C21.5635 21.3996 21.2665 21.7398 20.8949 21.9444C20.9303 21.9581 20.9657 21.9699 21.001 21.9818C21.9096 22.2808 22.889 21.7872 23.1879 20.8785Z" fill="#FFE07D"/>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -0,0 +1,15 @@
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.92516 12.1457C6.6709 11.6094 6.03272 11.3809 5.49988 11.6364L0.830003 13.8763C0.355091 13.9861 0 14.4121 0 14.9238V20.3082C0 20.9031 0.478601 21.385 1.06937 21.385C1.66001 21.385 2.13847 20.9031 2.13847 20.3082V16.5989L5.49988 18.2112C5.64826 18.2825 5.80469 18.3161 5.95867 18.3161C6.35844 18.3161 6.74154 18.0893 6.92516 17.7017C7.1786 17.1648 6.95249 16.5222 6.41937 16.2664L3.61977 14.9237L6.41937 13.581C6.95262 13.3253 7.1786 12.6828 6.92516 12.1457Z" fill="#D5D5D5"/>
<path d="M12.3651 10.6137C12.5194 10.6137 12.6755 10.5802 12.8243 10.5089L19.2289 7.43717C19.762 7.1812 19.9886 6.53854 19.7347 6.00156C19.481 5.46528 18.8432 5.23697 18.3094 5.49225L11.9046 8.56423C11.3714 8.82006 11.1453 9.46245 11.3989 9.99956C11.5824 10.3868 11.9655 10.6137 12.3651 10.6137Z" fill="#D5D5D5"/>
<path d="M25.6338 4.36467L28.9106 2.79269V6.54683C28.9106 7.14161 29.3893 7.62367 29.9797 7.62367C30.5704 7.62367 31.0488 7.14161 31.0488 6.54683V2.77315L34.3669 4.36467C34.5157 4.43582 34.6719 4.46953 34.8261 4.46953C35.2256 4.46953 35.6089 4.24274 35.7922 3.85522C36.0459 3.31825 35.8198 2.67572 35.2866 2.41989L30.46 0.104656C30.169 -0.0348854 29.8315 -0.0348854 29.5405 0.104656L24.7142 2.41989C24.1811 2.67572 23.9548 3.31811 24.2085 3.85522C24.4628 4.39261 25.1019 4.62119 25.6338 4.36467Z" fill="#D5D5D5"/>
<path d="M40.7719 7.43681L47.1768 10.5089C47.3249 10.5802 47.4816 10.6138 47.6358 10.6138C48.0353 10.6138 48.4186 10.387 48.6019 9.99948C48.8555 9.4625 48.6295 8.81998 48.0963 8.56415L41.6912 5.49189C41.1588 5.23648 40.5206 5.46451 40.2662 6.0012C40.0124 6.53818 40.2386 7.1807 40.7719 7.43681Z" fill="#D5D5D5"/>
<path d="M48.9237 20.886C49.4568 20.6303 49.683 19.9878 49.4292 19.4506C49.1755 18.9139 48.537 18.6855 48.0042 18.9417L43.9005 20.9106L31.0489 14.7463V9.94598C31.0489 9.35079 30.5704 8.86914 29.9798 8.86914C29.3893 8.86914 28.9107 9.35093 28.9107 9.94598V14.7658L16.101 20.9101L12.4202 19.1445C11.8858 18.8886 11.2492 19.1168 10.9949 19.6539C10.7412 20.1909 10.9674 20.8335 11.5006 21.0894L15.4821 22.9992V37.0011L11.4358 38.9419C10.9027 39.1977 10.6766 39.8401 10.9301 40.3774C11.1135 40.7648 11.4966 40.9915 11.8962 40.9915C12.0505 40.9915 12.2071 40.958 12.3553 40.8867L16.1012 39.09L28.9107 45.2342V48.9046C28.9107 49.4996 29.3893 49.9814 29.9798 49.9814C30.5704 49.9814 31.0489 49.4995 31.0489 48.9046V45.254L43.8996 39.0901L47.7917 40.957C47.9404 41.0282 48.0967 41.0619 48.2508 41.0619C48.6503 41.0619 49.0335 40.8351 49.2169 40.4476C49.4707 39.9106 49.2443 39.2681 48.7112 39.0121L44.5188 37.0013V22.9992L48.9237 20.886ZM42.3806 37.4328L31.049 42.8681V29.4597L42.3806 24.0241V37.4328ZM17.6875 37.1364C17.6685 37.0962 17.6434 37.0615 17.6203 37.0249V24.0243L28.9107 29.4399V42.8485L17.7848 37.5119C17.7746 37.3852 17.7449 37.2579 17.6875 37.1364ZM30.0004 16.6291L41.4126 22.103L30.0004 27.5767L18.5882 22.103L30.0004 16.6291Z" fill="#D5D5D5"/>
<path d="M47.1767 49.4916L40.772 52.5637C40.2389 52.8196 40.0123 53.4622 40.2662 53.9987C40.4497 54.3864 40.8329 54.6129 41.2324 54.6129C41.3865 54.6129 41.5432 54.5793 41.6915 54.5086L48.0964 51.4363C48.6295 51.1805 48.8556 50.5377 48.602 50.0007C48.3479 49.464 47.7094 49.237 47.1767 49.4916Z" fill="#D5D5D5"/>
<path d="M34.367 55.636L31.0489 57.2276V52.9362C31.0489 52.3414 30.5704 51.8594 29.9798 51.8594C29.3893 51.8594 28.9107 52.3414 28.9107 52.9362V57.2081L25.6338 55.636C25.1002 55.3814 24.4628 55.6084 24.2086 56.1455C23.9548 56.6825 24.181 57.3248 24.7142 57.5806L29.5408 59.8956C29.6862 59.965 29.8433 60 30.0005 60C30.1578 60 30.3149 59.965 30.4603 59.8956L35.2869 57.5806C35.82 57.3248 36.0462 56.6825 35.7925 56.1455C35.5383 55.6084 34.8997 55.3819 34.367 55.636Z" fill="#D5D5D5"/>
<path d="M19.2289 52.5636L12.824 49.4914C12.2922 49.2362 11.6534 49.4635 11.3989 50.0005C11.1453 50.5375 11.3714 51.1803 11.9046 51.4361L18.3096 54.5083C18.4577 54.5791 18.6144 54.6127 18.7685 54.6127C19.168 54.6127 19.5512 54.3861 19.7346 53.9985C19.9883 53.4621 19.762 52.8195 19.2289 52.5636Z" fill="#D5D5D5"/>
<path d="M6.92516 42.2985C6.6709 41.7618 6.03272 41.5345 5.49988 41.7894L2.13847 43.4014V39.3708C2.13847 38.776 1.66001 38.2939 1.06937 38.2939C0.478601 38.2939 0 38.776 0 39.3708V44.7553C0 44.8898 0.0274617 45.0171 0.0724116 45.1359C0.0941352 45.5271 0.319158 45.8792 0.673293 46.0493L5.49988 48.3645C5.64826 48.4354 5.80469 48.4692 5.95867 48.4692C6.35844 48.4692 6.74154 48.2424 6.92516 47.855C7.1786 47.3181 6.95249 46.6755 6.41937 46.4194L3.61977 45.077L6.41937 43.7343C6.95262 43.4783 7.1786 42.8355 6.92516 42.2985Z" fill="#D5D5D5"/>
<path d="M1.06937 34.0934C1.66001 34.0934 2.13847 33.6114 2.13847 33.0163V26.6623C2.13847 26.0675 1.66001 25.5854 1.06937 25.5854C0.478601 25.5854 0 26.0675 0 26.6623V33.0163C0.000136626 33.6114 0.478738 34.0934 1.06937 34.0934Z" fill="#D5D5D5"/>
<path d="M59.1707 13.8762L54.5008 11.6362C53.9669 11.3801 53.3298 11.6088 53.0757 12.1455C52.8221 12.6828 53.0482 13.3252 53.5813 13.5811L56.3809 14.9239L53.5813 16.2666C53.0482 16.5224 52.8221 17.1648 53.0757 17.7019C53.259 18.0894 53.6422 18.3162 54.0417 18.3162C54.196 18.3162 54.3527 18.2826 54.5008 18.2113L57.8622 16.599V20.3083C57.8622 20.9032 58.3407 21.3852 58.9313 21.3852C59.5219 21.3852 60.0003 20.9032 60.0003 20.3083V14.924C60.0003 14.4119 59.6456 13.986 59.1707 13.8762Z" fill="#D5D5D5"/>
<path d="M58.9314 25.5854C58.3406 25.5854 57.8623 26.0675 57.8623 26.6623V33.0163C57.8623 33.6114 58.3408 34.0931 58.9314 34.0931C59.522 34.0931 60.0004 33.6113 60.0004 33.0163V26.6623C60.0004 26.0675 59.5222 25.5854 58.9314 25.5854Z" fill="#D5D5D5"/>
<path d="M58.9313 38.2935C58.3405 38.2935 57.8622 38.7755 57.8622 39.3703V43.4009L54.5008 41.7889C53.9669 41.5336 53.3298 41.7611 53.0757 42.2981C52.8221 42.835 53.0482 43.4778 53.5813 43.7337L56.3809 45.0764L53.5813 46.4188C53.0482 46.6749 52.8221 47.3174 53.0757 47.8544C53.259 48.2418 53.6422 48.4686 54.0417 48.4686C54.196 48.4686 54.3527 48.4347 54.5008 48.3639L59.3274 46.0486C59.6815 45.8785 59.9065 45.5265 59.9283 45.1353C59.9731 45.0165 60.0003 44.8892 60.0003 44.7546V39.3702C60.0003 38.7755 59.5221 38.2935 58.9313 38.2935Z" fill="#D5D5D5"/>
</svg>

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -0,0 +1,25 @@
<svg width="23" height="18" viewBox="0 0 23 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.3032 0.832703H1.4526C1.10932 0.832703 0.830078 1.11285 0.830078 1.45725V16.6318C0.830078 16.9762 1.10932 17.2563 1.4526 17.2563H22.3032C22.6463 17.2563 22.9257 16.9762 22.9257 16.6318V1.45725C22.9257 1.11265 22.6465 0.832703 22.3032 0.832703Z" fill="#E6E7E8"/>
<path d="M21.8881 0.624556V15.7989C21.8881 16.029 21.7023 16.2153 21.4731 16.2153H0.622537C0.393143 16.2153 0.20752 16.029 0.20752 15.7989V0.624556C0.20752 0.394417 0.393143 0.208191 0.622537 0.208191H21.4731C21.7023 0.208191 21.8881 0.394417 21.8881 0.624556Z" fill="white"/>
<path d="M0.20752 15.7989C0.20752 16.0288 0.393143 16.2152 0.622537 16.2152H21.4731C21.7023 16.2152 21.8881 16.0288 21.8881 15.7989V0.832703H0.20752V15.7989Z" fill="#D4FBFF"/>
<path d="M4.44421 8.45071C4.36336 8.45071 4.29 8.3952 4.27055 8.31266C3.4626 4.87562 2.7657 4.37773 2.4283 4.37427C1.65825 4.38423 0.871172 6.79256 0.555856 8.30819C0.535592 8.40517 0.440754 8.46758 0.3447 8.44705C0.248038 8.42672 0.186231 8.33177 0.206293 8.235C0.29566 7.80501 1.11779 4.03293 2.42364 4.01605H2.43336C3.2484 4.01605 3.94267 5.35582 4.61829 8.23053C4.64098 8.32669 4.58161 8.42326 4.48555 8.44603C4.47157 8.44928 4.45799 8.45071 4.44421 8.45071Z" fill="#FFD7E5"/>
<path d="M12.6696 8.59971C12.5887 8.59971 12.5156 8.54421 12.4959 8.46167C11.6916 5.03987 11.001 4.52328 10.6583 4.52328C10.6569 4.52328 10.6553 4.52348 10.6539 4.52348C9.88383 4.53344 9.09696 6.94157 8.78164 8.45719C8.76118 8.55417 8.66634 8.61679 8.57029 8.59605C8.47362 8.57572 8.41182 8.48078 8.43188 8.38401C8.52145 7.95402 9.34358 4.18193 10.6494 4.16526C11.4762 4.15693 12.1656 5.49364 12.8437 8.37953C12.8664 8.4757 12.807 8.57226 12.7109 8.59524C12.6972 8.59829 12.6834 8.59971 12.6696 8.59971Z" fill="#FFD7E5"/>
<path d="M20.7961 8.29596C20.7152 8.29596 20.6418 8.24046 20.6224 8.15792C19.8181 4.73612 19.1275 4.21953 18.7848 4.21953C18.7832 4.21953 18.7818 4.21973 18.7803 4.21973C18.0103 4.2297 17.2234 6.63782 16.9081 8.15345C16.8878 8.25042 16.7928 8.31284 16.6968 8.2923C16.6001 8.27197 16.5383 8.17703 16.5583 8.08026C16.6477 7.65027 17.47 3.87818 18.7759 3.86151C19.5903 3.84647 20.2921 5.1899 20.9701 8.07579C20.9928 8.17195 20.9335 8.26852 20.8374 8.29149C20.8234 8.29454 20.8098 8.29596 20.7961 8.29596Z" fill="#FFD7E5"/>
<path d="M6.52174 12.5619C6.5185 12.5619 6.51546 12.5617 6.51181 12.5617C5.17537 12.5448 4.33378 8.7729 4.24219 8.34291C4.22152 8.24594 4.28495 8.15099 4.38384 8.13087C4.48252 8.11074 4.57959 8.17275 4.60006 8.26972C4.92287 9.78535 5.729 12.1935 6.51668 12.2034C6.5181 12.2034 6.51972 12.2036 6.52114 12.2036C6.87212 12.2036 7.57915 11.6875 8.40229 8.26525C8.42519 8.16909 8.52388 8.10993 8.62216 8.13188C8.72065 8.15465 8.78144 8.25122 8.75814 8.34759C8.06671 11.2215 7.35583 12.5619 6.52174 12.5619Z" fill="#FFD7E5"/>
<path d="M14.7221 12.5619C14.7187 12.5619 14.7157 12.5617 14.7124 12.5617C13.4066 12.5448 12.5842 8.7729 12.4949 8.34291C12.4748 8.24594 12.5366 8.15099 12.6333 8.13087C12.7299 8.11074 12.8244 8.17275 12.8446 8.26972C13.1599 9.78535 13.9472 12.1935 14.7169 12.2034C14.7183 12.2034 14.7197 12.2036 14.7213 12.2036C15.064 12.2036 15.7546 11.6875 16.5589 8.26525C16.5816 8.16909 16.6777 8.10972 16.7737 8.13188C16.8698 8.15465 16.9292 8.25122 16.9065 8.34759C16.2314 11.2215 15.5368 12.5619 14.7221 12.5619Z" fill="#FFD7E5"/>
<path d="M21.7088 11.1408C21.6411 11.1408 21.5763 11.102 21.5463 11.0361C20.9983 9.83621 20.6678 8.26468 20.6542 8.1982C20.634 8.10142 20.696 8.00648 20.7926 7.98615C20.8887 7.96602 20.9837 8.02803 21.0038 8.12501C21.0072 8.14087 21.34 9.72419 21.8711 10.8871C21.912 10.9769 21.8727 11.0831 21.783 11.1245C21.7591 11.1357 21.7339 11.1408 21.7088 11.1408Z" fill="#FFD7E5"/>
<path d="M3.03701 8.32623C2.97175 8.32623 2.91238 8.2811 2.89677 8.21462C2.36037 5.93295 1.90949 5.68532 1.73582 5.69386C1.28088 5.69976 0.771229 7.16923 0.554601 8.21096C0.538389 8.28923 0.46179 8.33945 0.383771 8.32298C0.305753 8.30671 0.255902 8.23007 0.271911 8.152C0.366952 7.69498 0.884102 5.41534 1.73177 5.40436H1.73845C2.28033 5.40436 2.7379 6.27653 3.17764 8.14814C3.19588 8.2258 3.14785 8.30387 3.07024 8.32237C3.0593 8.32461 3.04815 8.32623 3.03701 8.32623Z" fill="#FA759E"/>
<path d="M8.34895 8.42239C8.2835 8.42239 8.22412 8.37746 8.20852 8.31078C7.67475 6.03927 7.22204 5.79002 7.04979 5.79002C7.04898 5.79002 7.04838 5.79002 7.04757 5.79002C6.59283 5.79592 6.08318 7.26539 5.86655 8.30712C5.85014 8.38539 5.77333 8.43561 5.69572 8.41914C5.6177 8.40288 5.56765 8.32623 5.58386 8.24816C5.6789 7.79114 6.19605 5.5115 7.04372 5.50052H7.0502C7.59207 5.50052 8.04965 6.37269 8.48939 8.2443C8.50762 8.32196 8.4596 8.40003 8.38198 8.41853C8.37084 8.42117 8.3599 8.42239 8.34895 8.42239Z" fill="#FA759E"/>
<path d="M13.5964 8.22601C13.5309 8.22601 13.4716 8.18108 13.456 8.1144C12.9198 5.83293 12.4648 5.59039 12.295 5.59385C11.8401 5.59974 11.3304 7.06922 11.1138 8.11094C11.0976 8.18921 11.021 8.23984 10.9432 8.22296C10.8651 8.2067 10.8151 8.12985 10.8313 8.05178C10.9263 7.59476 11.4435 5.31532 12.2912 5.30414H12.2976C12.8395 5.30414 13.2971 6.17651 13.7368 8.04812C13.7551 8.12578 13.707 8.20385 13.6294 8.22235C13.6185 8.22479 13.6073 8.22601 13.5964 8.22601Z" fill="#FA759E"/>
<path d="M18.895 8.42239C18.8298 8.42239 18.7704 8.37746 18.7548 8.31078C18.2186 6.02931 17.7635 5.78677 17.5938 5.79002C17.1389 5.79612 16.6292 7.26539 16.4126 8.30712C16.3962 8.38539 16.3198 8.43601 16.242 8.41914C16.1638 8.40288 16.1139 8.32623 16.1301 8.24816C16.2252 7.79114 16.7421 5.5115 17.5898 5.50052H17.5965C18.1383 5.50052 18.5959 6.37269 19.0357 8.2443C19.0539 8.32196 19.0059 8.40003 18.9283 8.41853C18.9171 8.42117 18.9062 8.42239 18.895 8.42239Z" fill="#FA759E"/>
<path d="M4.4265 11.1188C4.42427 11.1188 4.42204 11.1188 4.41981 11.1188C3.57195 11.1076 3.055 8.8282 2.95996 8.37118C2.94375 8.2929 2.9938 8.21626 3.07162 8.19999C3.14984 8.18332 3.22623 8.23374 3.24245 8.31201C3.45928 9.35354 3.96913 10.8234 4.42367 10.8291H4.42589C4.59814 10.8291 5.05065 10.5799 5.58462 8.30856C5.60286 8.2309 5.68067 8.18312 5.75808 8.20081C5.8357 8.2191 5.88352 8.29717 5.86528 8.37504C5.42575 10.2464 4.96838 11.1188 4.4265 11.1188Z" fill="#FA759E"/>
<path d="M9.67406 10.9584C9.67183 10.9584 9.6696 10.9584 9.66737 10.9584C8.81951 10.9474 8.30256 8.66778 8.20752 8.21076C8.19131 8.13248 8.24136 8.05584 8.31917 8.03978C8.3976 8.02311 8.47359 8.07353 8.49 8.1518C8.70683 9.19332 9.21669 10.663 9.67122 10.6689H9.67345C9.8457 10.6689 10.2982 10.4196 10.8322 8.14814C10.8504 8.07027 10.928 8.0229 11.0056 8.04059C11.0833 8.05889 11.1311 8.13696 11.1128 8.21482C10.6733 10.086 10.2159 10.9584 9.67406 10.9584Z" fill="#FA759E"/>
<path d="M14.9774 10.9842C14.9752 10.9842 14.9732 10.9842 14.971 10.9842C14.1229 10.9732 13.6061 8.69361 13.5111 8.23658C13.4949 8.15831 13.5449 8.08166 13.6228 8.0656C13.701 8.04893 13.7772 8.09915 13.7934 8.17762C14.0102 9.21915 14.5201 10.6888 14.9746 10.6947H14.9768C15.1491 10.6947 15.6016 10.4455 16.1356 8.17396C16.1538 8.0963 16.2316 8.04873 16.309 8.06642C16.3866 8.08471 16.4347 8.16278 16.4164 8.24065C15.9767 10.1121 15.5193 10.9842 14.9774 10.9842Z" fill="#FA759E"/>
<path d="M20.234 11.1188C20.2318 11.1188 20.2298 11.1188 20.2274 11.1188C19.3795 11.1076 18.8627 8.8282 18.7677 8.37118C18.7515 8.2929 18.8015 8.21626 18.8794 8.19999C18.9576 8.18332 19.0338 8.23374 19.05 8.31201C19.2668 9.35354 19.7767 10.8234 20.2312 10.8291H20.2334C20.4057 10.8291 20.8582 10.5799 21.3922 8.30856C21.4104 8.2309 21.4882 8.18312 21.5656 8.20081C21.6432 8.2191 21.6913 8.29717 21.673 8.37504C21.2335 10.2464 20.7759 11.1188 20.234 11.1188Z" fill="#FA759E"/>
<path d="M5.67451 8.26302C5.58717 8.26302 5.50794 8.20284 5.48707 8.11399C4.43696 3.6462 3.52019 2.97225 3.06363 2.97225C3.06161 2.97225 3.05958 2.97225 3.05776 2.97225C2.03541 2.98567 1.00151 6.12996 0.589942 8.10912C0.568258 8.21382 0.46572 8.28091 0.361763 8.25895C0.257401 8.2372 0.190528 8.13473 0.212211 8.02983C0.327719 7.47501 1.38816 2.60651 3.05269 2.58496H3.06404C4.08719 2.58496 5.00254 4.36447 5.86257 8.02495C5.88709 8.12884 5.82265 8.23333 5.7191 8.25793C5.7043 8.26139 5.68931 8.26302 5.67451 8.26302Z" fill="#0089EF"/>
<path d="M16.3507 8.26302C16.2633 8.26302 16.1841 8.20284 16.163 8.11399C15.1131 3.6462 14.1964 2.97225 13.7398 2.97225C13.7378 2.97225 13.7357 2.97225 13.7337 2.97225C12.7116 2.98567 11.6779 6.12996 11.2661 8.10912C11.2442 8.21382 11.1419 8.28091 11.0379 8.25895C10.9336 8.2372 10.8667 8.13473 10.8882 8.02983C11.0039 7.47501 12.0641 2.60651 13.7286 2.58496H13.74C14.7627 2.58496 15.6781 4.36447 16.5385 8.02495C16.563 8.12884 16.4986 8.23333 16.3951 8.25793C16.3805 8.26139 16.3655 8.26302 16.3507 8.26302Z" fill="#0089EF"/>
<path d="M8.46634 13.838C8.46269 13.838 8.45884 13.838 8.45499 13.838C6.79046 13.8164 5.73002 8.94794 5.61431 8.39292C5.59263 8.28843 5.6595 8.18576 5.76406 8.164C5.86802 8.14205 5.97056 8.20934 5.99224 8.31384C6.40422 10.2928 7.43832 13.4375 8.45985 13.4505H8.46593C8.9227 13.4505 9.83926 12.777 10.8892 8.30896C10.9137 8.20507 11.0178 8.14123 11.1212 8.16482C11.2249 8.18942 11.2892 8.29371 11.2647 8.3978C10.4046 12.0583 9.48909 13.838 8.46634 13.838Z" fill="#0089EF"/>
<path d="M19.014 13.6947C19.0103 13.6947 19.0065 13.6947 19.0026 13.6947C17.3381 13.6729 16.2776 8.80464 16.1619 8.24963C16.1402 8.14513 16.2069 8.04246 16.3117 8.0205C16.416 7.99875 16.518 8.06604 16.5399 8.17054C16.9518 10.1495 17.9859 13.294 19.0075 13.3072H19.0135C19.4703 13.3072 20.3869 12.6335 21.4368 8.16546C21.4613 8.06157 21.5655 7.99794 21.6688 8.02152C21.7726 8.04592 21.837 8.15021 21.8123 8.2543C20.9523 11.9148 20.0367 13.6947 19.014 13.6947Z" fill="#0089EF"/>
<path d="M21.4731 0H0.622526C0.279245 0 0 0.280152 0 0.624547V15.7991C0 16.1435 0.279245 16.4236 0.622526 16.4236H21.4731C21.8162 16.4236 22.0956 16.1435 22.0956 15.7991V6.08324C22.0956 5.96817 22.0026 5.87506 21.8881 5.87506C21.7734 5.87506 21.6806 5.96817 21.6806 6.08324V8.00323H18.0263C17.7882 6.70921 16.7602 1.48066 15.5275 0.416365H21.4731C21.5874 0.416365 21.6806 0.509681 21.6806 0.624547V2.90866C21.6806 3.02373 21.7734 3.11684 21.8881 3.11684C22.0026 3.11684 22.0956 3.02373 22.0956 2.90866V0.624547C22.0956 0.279949 21.8164 0 21.4731 0ZM17.6453 8.4196C17.94 9.69594 19.2156 14.9412 20.4964 16.0071H9.63335C10.8664 14.9428 11.8945 9.71342 12.1324 8.4196H17.6453ZM9.20192 15.7828C8.47685 15.7828 7.18702 12.0658 6.33874 8.4196H11.7101C11.0348 12.0642 9.92273 15.7828 9.20192 15.7828ZM5.80943 8.00323H0.438119C1.11576 4.35902 2.23011 0.640405 2.95072 0.640405C3.67558 0.640405 4.96319 4.3574 5.80943 8.00323ZM0.622526 0.416365H2.51908C1.64751 1.16899 0.876441 4.00121 0.415017 6.0564V0.624547C0.415017 0.509681 0.508032 0.416365 0.622526 0.416365ZM0.415017 15.7989V8.4196H5.91258C6.20723 9.69594 7.48288 14.9412 8.7636 16.0071H0.622526C0.508032 16.0071 0.415017 15.9138 0.415017 15.7989ZM21.4731 16.0071H21.3939C21.4934 15.9217 21.5902 15.8062 21.6806 15.6543V15.7989C21.6806 15.9138 21.5874 16.0071 21.4731 16.0071ZM21.6806 14.2969C21.5136 15.3866 21.1434 15.7828 20.9347 15.7828C20.2096 15.7828 18.9198 12.0658 18.0715 8.4196H21.6802V14.2969H21.6806ZM17.604 8.00323H12.2329C13.081 4.3574 14.3708 0.640405 15.0959 0.640405C15.8167 0.640405 16.9288 4.35902 17.604 8.00323ZM11.8065 8.00323H6.2356C5.94156 6.72629 4.66915 1.48249 3.38944 0.416365H14.6569C13.3768 1.48269 12.1014 6.72669 11.8065 8.00323Z" fill="#3A2C60"/>
<path d="M21.8882 3.50696C21.7735 3.50696 21.6807 3.60007 21.6807 3.71514V5.22446C21.6807 5.33953 21.7735 5.43265 21.8882 5.43265C22.0027 5.43265 22.0957 5.33953 22.0957 5.22446V3.71514C22.0957 3.60027 22.0027 3.50696 21.8882 3.50696Z" fill="#3A2C60"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,4 @@
<svg width="39" height="39" viewBox="0 0 39 39" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="19.5" cy="19.5" r="18.5" fill="#D9D9D9" stroke="white" stroke-width="2"/>
<path opacity="0.994" fill-rule="evenodd" clip-rule="evenodd" d="M13.7258 10.75C14.6614 10.75 15.597 10.75 16.5326 10.75C16.5718 11.8783 17.0678 12.7378 18.0205 13.3285C19.1166 13.9015 20.1818 13.8508 21.2162 13.1763C22.0192 12.5708 22.4363 11.762 22.4674 10.75C23.403 10.75 24.3386 10.75 25.2742 10.75C25.2418 12.4975 24.5795 13.9516 23.2874 15.1123C23.2762 15.1236 23.2762 15.1349 23.2874 15.1461C23.4903 15.3265 23.682 15.5181 23.8623 15.721C25.0293 14.4194 26.4919 13.7543 28.25 13.7258C28.25 14.6614 28.25 15.597 28.25 16.5326C27.215 16.5583 26.3949 16.9866 25.7899 17.8176C25.2517 18.6453 25.1333 19.5301 25.4348 20.4722C25.948 21.7316 26.8864 22.3967 28.25 22.4674C28.25 23.403 28.25 24.3386 28.25 25.2742C26.4961 25.2406 25.0363 24.5755 23.8708 23.279C23.6793 23.4845 23.4793 23.6818 23.2705 23.8708C23.2593 23.882 23.2593 23.8933 23.2705 23.9046C24.5686 25.0695 25.2364 26.5293 25.2742 28.2838C24.3386 28.2838 23.403 28.2838 22.4674 28.2838C22.408 27.0503 21.8331 26.1514 20.7428 25.587C19.6978 25.1484 18.7059 25.2442 17.7669 25.8744C16.9735 26.4776 16.5621 27.2807 16.5326 28.2838C15.597 28.2838 14.6614 28.2838 13.7258 28.2838C13.7577 26.5268 14.4255 25.067 15.7295 23.9046C15.7407 23.8933 15.7407 23.882 15.7295 23.8708C15.5207 23.6818 15.3207 23.4845 15.1292 23.279C13.9613 24.57 12.5016 25.2351 10.75 25.2742C10.75 24.3386 10.75 23.403 10.75 22.4674C11.9627 22.4124 12.856 21.8544 13.43 20.7935C13.9025 19.7273 13.8123 18.7128 13.1594 17.75C12.5542 16.9612 11.751 16.5555 10.75 16.5326C10.75 15.597 10.75 14.6614 10.75 13.7258C12.5067 13.7576 13.9693 14.4227 15.1377 15.721C15.2222 15.6252 15.3068 15.5294 15.3913 15.4336C15.5042 15.3348 15.6141 15.2333 15.721 15.1292C14.4204 13.9649 13.7554 12.5051 13.7258 10.75ZM19.2717 16.5326C20.3739 16.4946 21.2559 16.9117 21.9179 17.7838C22.6033 18.8416 22.6427 19.9238 22.0362 21.0302C21.4416 21.9421 20.5962 22.4211 19.5 22.4674C18.4038 22.4211 17.5584 21.9421 16.9638 21.0302C16.3957 20.0193 16.3901 19.0048 16.9469 17.9867C17.4892 17.1319 18.2641 16.6472 19.2717 16.5326Z" fill="#FEFFFE"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,24 @@
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="30" cy="30" r="30" fill="white"/>
<g filter="url(#filter0_i_2351_2399)">
<path d="M16 16.1817C16 13.6934 17.8282 11.5608 20.3041 11.3129C24.581 10.8846 27.9929 10.9034 32.2213 11.3239C34.7091 11.5713 36.5548 13.7089 36.5548 16.209V43.7835C36.5548 46.246 34.7637 48.3665 32.3165 48.6408C28.0557 49.1183 24.5855 49.1222 20.2426 48.6376C17.7933 48.3643 16 46.2435 16 43.7791V16.1817Z" fill="#EAF6FF"/>
</g>
<path d="M33.5761 34.3577C33.7051 34.3577 33.8341 34.3086 33.9325 34.2102C34.1293 34.0133 34.1293 33.6943 33.9325 33.4975C32.2479 31.813 32.2479 29.0721 33.9325 27.3875C34.1293 27.1907 34.1293 26.8717 33.9325 26.6749C33.7356 26.4782 33.4166 26.4782 33.2198 26.6749C31.1423 28.7525 31.1423 32.1327 33.2198 34.2103C33.3182 34.3086 33.4472 34.3577 33.5761 34.3577Z" fill="#8AC9FE"/>
<path d="M34.6358 32.4001C34.744 32.4001 34.8522 32.3588 34.9348 32.2762C35.0999 32.1111 35.0999 31.8434 34.9347 31.6783C34.6046 31.3483 34.4228 30.9093 34.4228 30.4424C34.4228 29.9756 34.6046 29.5367 34.9347 29.2066C35.0999 29.0415 35.0999 28.7738 34.9348 28.6087C34.7696 28.4436 34.5019 28.4436 34.3369 28.6087C33.847 29.0985 33.5772 29.7497 33.5772 30.4424C33.5772 31.1352 33.847 31.7864 34.3369 32.2763C34.4193 32.3587 34.5276 32.4001 34.6358 32.4001Z" fill="#8AC9FE"/>
<path d="M27.1713 41.5347L27.1713 43.4539C27.1713 43.8359 26.8617 44.1455 26.4797 44.1455C26.0976 44.1455 25.7881 43.8359 25.7881 43.4539L25.7881 41.5347C25.7881 41.1527 26.0976 40.8431 26.4797 40.8431C26.8617 40.8431 27.1713 41.1527 27.1713 41.5347Z" fill="#B3DAFE"/>
<path d="M37.5342 19.7964C37.5342 18.9119 38.1118 18.1138 38.9777 17.9335C40.3924 17.639 41.5238 17.6511 42.9209 17.9388C43.7961 18.1191 44.3858 18.9219 44.3858 19.8155V42.0421C44.3858 42.9071 43.8339 43.6929 42.9918 43.8912C41.5575 44.2289 40.3936 44.2319 38.9318 43.8895C38.0881 43.6918 37.5342 42.9055 37.5342 42.039V19.7964Z" fill="#EAF6FF"/>
<path d="M39.9952 34.3577C39.8662 34.3577 39.7372 34.3086 39.6388 34.2102C39.442 34.0133 39.442 33.6943 39.6388 33.4975C41.3234 31.813 41.3234 29.0721 39.6388 27.3875C39.442 27.1907 39.442 26.8717 39.6388 26.6749C39.8357 26.4782 40.1547 26.4782 40.3515 26.6749C42.429 28.7525 42.429 32.1327 40.3515 34.2103C40.2531 34.3086 40.1241 34.3577 39.9952 34.3577Z" fill="#8AC9FE"/>
<path d="M38.9355 32.4001C38.8273 32.4001 38.7191 32.3588 38.6365 32.2762C38.4714 32.1111 38.4714 31.8434 38.6366 31.6783C38.9666 31.3483 39.1485 30.9093 39.1485 30.4424C39.1485 29.9756 38.9666 29.5367 38.6366 29.2066C38.4714 29.0415 38.4714 28.7738 38.6365 28.6087C38.8017 28.4436 39.0694 28.4436 39.2344 28.6087C39.7243 29.0985 39.9941 29.7497 39.9941 30.4424C39.9941 31.1352 39.7243 31.7864 39.2344 32.2763C39.1519 32.3587 39.0437 32.4001 38.9355 32.4001Z" fill="#8AC9FE"/>
<defs>
<filter id="filter0_i_2351_2399" x="15" y="11" width="21.5547" height="38" 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_2351_2399"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,19 @@
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="30" cy="30" r="30" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.6277 34.7848L12.0206 21.9742C11.9545 21.7877 12.0527 21.581 12.2393 21.5129C18.2964 19.3343 25.1218 17.3082 30.9563 14.8187C31.2171 14.6542 31.4217 14.8167 31.534 15.1276L38.7725 33.7858L40.7381 39.2523C40.8043 39.4388 40.7081 39.6475 40.5215 39.7137L26.6702 44.6947L21.2709 46.6366C21.0843 46.7048 20.8777 46.6065 20.8096 46.4199L16.6277 34.7848Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.4689 30.5338L18.1684 17.1174C18.1343 16.9208 18.2667 16.7342 18.4613 16.7001L34.3042 13.9839L37.9325 13.3861C38.1311 13.2999 38.454 13.4001 38.5302 13.8435L42.4493 33.4146L43.4301 39.1398C43.4642 39.3345 43.3318 39.523 43.1372 39.5571L28.6301 42.0446L22.974 43.0155C22.7795 43.0477 22.5909 42.9152 22.5568 42.7206L20.4689 30.5338Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.9063 26.5779V39.4768C24.9063 39.6835 25.0748 39.854 25.2814 39.854H31.2684H40.1315H41.4051H46.624C46.8305 39.854 46.999 39.6835 46.999 39.4768V33.4166V16.6761V16.5016H43.1882C42.8212 16.5016 42.059 16.5537 42.059 15.7213L42.0509 12H25.2813C25.0748 12 24.9062 12.1685 24.9062 12.3752V15.5949V16.957V26.5779H24.9063Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5492 19.3423C16.4031 20.0645 14.277 20.7806 12.2393 21.5128C12.0527 21.581 11.9545 21.7876 12.0206 21.9742L16.6277 34.7848L20.8096 46.4199C20.8778 46.6065 21.0844 46.7048 21.2709 46.6365L26.6702 44.6947L38.9732 40.2713L18.5492 19.3423Z" fill="#B5C4CF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.9076 15.5947L18.4613 16.7C18.2667 16.7341 18.1343 16.9207 18.1684 17.1173L18.5495 19.342L20.469 30.5337L22.5569 42.7205C22.591 42.9151 22.7795 43.0474 22.9741 43.0154L28.6301 42.0445L38.9735 40.2711L41.4064 39.8538H40.1328L24.9076 15.5947Z" fill="#D7E7EC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.999 33.4166V16.6761V16.5016V16.4434C46.999 16.3351 46.9528 16.317 46.7864 16.1545L42.6727 12.2307C42.4782 12.0461 42.4461 12 42.3318 12H42.0509H25.2813C25.0748 12 24.9062 12.1685 24.9062 12.3752V39.4768C24.9062 39.6835 25.0748 39.854 25.2813 39.854H46.6239C46.8305 39.854 46.999 39.6835 46.999 39.4768V33.4166Z" fill="#EDF3F4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.9077 15.5947L23.3975 15.8535V40.8629C23.3975 41.0716 23.566 41.2401 23.7725 41.2401H29.7595H33.3216L38.9736 40.2712L41.4065 39.8539H40.1329H38.5665H31.2698H25.2828C25.0762 39.8539 24.9077 39.6834 24.9077 39.4768C24.9077 31.5167 24.9077 23.5547 24.9077 15.5947Z" fill="#B5C4CF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.469 30.5336L18.5495 19.3418C18.03 19.5163 17.5126 19.6908 16.9971 19.8654L17.2358 21.2556L19.1552 32.4473L21.2452 44.6341C21.2772 44.8286 21.4658 44.961 21.6603 44.929L27.3164 43.9581L30 43.4987L38.0829 40.59L37.9867 40.4395L33.3214 41.2399L28.6302 42.0444L22.9741 43.0153C22.7796 43.0474 22.591 42.915 22.5569 42.7204L20.469 30.5336Z" fill="#9AAFB7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.9998 33.4166V16.6761V16.5016C46.9998 16.299 46.9337 16.297 46.7873 16.1545L42.6736 12.2307C42.4791 12.0461 42.447 12 42.3326 12H42.0518H37.8779C42.9784 18.8286 43.2692 31.1377 39.4845 38.8209C39.31 39.178 39.1275 39.521 38.937 39.854H40.1323H41.4059H46.6248C46.8313 39.854 46.9998 39.6835 46.9998 39.4768V33.4166Z" fill="#D7E7EC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M42.0607 15.7213C42.0607 16.5537 42.8229 16.5016 43.19 16.5016H47.0008V16.4434C47.0008 16.3351 46.9546 16.317 46.7882 16.1545L42.6745 12.2307C42.48 12.0461 42.4479 12 42.3336 12H42.0527L42.0607 15.7213Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.7882 16.1545L42.6745 12.2307C42.48 12.0461 42.4479 12 42.3336 12H42.0527L42.0607 15.7212C42.0607 16.5537 42.8229 16.5015 43.19 16.5015H47.0008V16.4433C47.0008 16.3351 46.9546 16.317 46.7882 16.1545Z" fill="#B5C4CF"/>
<path d="M43.6094 20.2037H28.5086C28.2169 20.2037 27.9805 19.9671 27.9805 19.6753C27.9805 19.3835 28.2169 19.147 28.5086 19.147H43.6094C43.9011 19.147 44.1376 19.3835 44.1376 19.6753C44.1376 19.9671 43.9012 20.2037 43.6094 20.2037Z" fill="#9AAFB7"/>
<path d="M43.6094 23.9566H28.5086C28.2169 23.9566 27.9805 23.7201 27.9805 23.4283C27.9805 23.1364 28.2169 22.8999 28.5086 22.8999H43.6094C43.9011 22.8999 44.1376 23.1364 44.1376 23.4283C44.1376 23.7201 43.9012 23.9566 43.6094 23.9566Z" fill="#9AAFB7"/>
<path d="M43.6094 27.7105H28.5086C28.2169 27.7105 27.9805 27.474 27.9805 27.1822C27.9805 26.8903 28.2169 26.6538 28.5086 26.6538H43.6094C43.9011 26.6538 44.1376 26.8903 44.1376 27.1822C44.1376 27.474 43.9012 27.7105 43.6094 27.7105Z" fill="#9AAFB7"/>
<path d="M43.6094 31.4634H28.5086C28.2169 31.4634 27.9805 31.2269 27.9805 30.9351C27.9805 30.6433 28.2169 30.4067 28.5086 30.4067H43.6094C43.9011 30.4067 44.1376 30.6433 44.1376 30.9351C44.1376 31.2269 43.9012 31.4634 43.6094 31.4634Z" fill="#9AAFB7"/>
<path d="M43.6094 35.2169H28.5086C28.2169 35.2169 27.9805 34.9803 27.9805 34.6885C27.9805 34.3967 28.2169 34.1602 28.5086 34.1602H43.6094C43.9011 34.1602 44.1376 34.3967 44.1376 34.6885C44.1376 34.9803 43.9012 35.2169 43.6094 35.2169Z" fill="#9AAFB7"/>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,104 @@
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.39648 12.4951H35.6037V37.8285H2.39648V12.4951Z" fill="url(#paint0_linear_3415_1104)"/>
<path d="M2.40332 20.3789H14.3054V38.0005H2.40332V20.3789Z" fill="url(#paint1_linear_3415_1104)"/>
<g clip-path="url(#clip0_3415_1104)">
<path d="M2.45801 10.3135H35.6149V14.2625H2.45801V10.3135Z" fill="url(#paint2_linear_3415_1104)"/>
<path d="M2.45801 13.4424H35.6149V17.3914H2.45801V13.4424Z" fill="url(#paint3_linear_3415_1104)"/>
<path d="M2.45801 16.5723H35.6149V20.5213H2.45801V16.5723Z" fill="url(#paint4_linear_3415_1104)"/>
</g>
<path d="M36.3054 9.43704L22.7255 0.961176C21.6987 0.320392 20.3494 0 19 0C17.6506 0 16.3013 0.320392 15.2745 0.961176L1.69458 9.43704C0.640486 10.095 0 11.2497 0 12.4923V35.6368C0 36.942 1.05804 38 2.36323 38C3.03367 38 3.57722 37.4565 3.57722 36.786V15.833C3.57722 14.4546 4.69464 13.3373 6.07292 13.3373H31.9271C33.3054 13.3373 34.4228 14.4546 34.4228 15.833V36.786C34.4228 37.4565 34.9663 38 35.6368 38C36.942 38 38 36.942 38 35.6368V12.4923C38 11.2497 37.3595 10.095 36.3054 9.43704Z" fill="url(#paint5_linear_3415_1104)"/>
<path d="M36.3054 9.43704L22.7255 0.961177C21.6987 0.320392 20.3494 0 19 0C17.6506 0 16.3013 0.320392 15.2745 0.961177L1.69458 9.43704C0.640486 10.095 0 11.2497 0 12.4923V16.0686C0 14.8261 0.640486 13.6713 1.69458 13.0134L15.2745 4.53743C16.3013 3.89664 17.6506 3.57625 19 3.57625C20.3494 3.57625 21.6987 3.89664 22.7255 4.53743L36.3054 13.0133C37.3595 13.6712 38 14.826 38 16.0686V12.4923C38 11.2497 37.3595 10.095 36.3054 9.43704Z" fill="url(#paint6_linear_3415_1104)"/>
<path d="M14.7543 8.44803H23.2456C23.7264 8.44803 24.1161 8.05827 24.1161 7.57753C24.1161 7.09672 23.7264 6.70703 23.2456 6.70703H14.7543C14.2735 6.70703 13.8838 7.09679 13.8838 7.57753C13.8838 8.05827 14.2735 8.44803 14.7543 8.44803Z" fill="url(#paint7_linear_3415_1104)"/>
<path d="M14.7543 11.6512H23.2456C23.7264 11.6512 24.1161 11.2614 24.1161 10.7807C24.1161 10.2998 23.7264 9.91016 23.2456 9.91016H14.7543C14.2735 9.91016 13.8838 10.2999 13.8838 10.7807C13.8838 11.2614 14.2735 11.6512 14.7543 11.6512Z" fill="url(#paint8_linear_3415_1104)"/>
<path d="M38 16.0685V35.6363C38 36.289 37.7355 36.8798 37.3078 37.3075C36.8801 37.7352 36.2893 37.9997 35.6366 37.9997C34.966 37.9997 34.4228 37.4565 34.4228 36.7859V15.8323C34.4228 14.4546 33.3051 13.337 31.9267 13.337H6.07329C4.69486 13.337 3.57722 14.4546 3.57722 15.8323V36.7859C3.57722 37.1212 3.44161 37.4245 3.2218 37.6443C3.002 37.8641 2.69875 37.9997 2.36345 37.9997C1.05804 37.9997 0 36.9417 0 35.6363V16.0685C0 14.8257 0.640784 13.6708 1.69435 13.0128L15.2745 4.53735C16.3013 3.89656 17.6506 3.57617 19 3.57617C20.3494 3.57617 21.6987 3.89656 22.7255 4.53735L36.3056 13.0128C37.3592 13.6708 38 14.8257 38 16.0685Z" fill="url(#paint9_linear_3415_1104)"/>
<path d="M19.0745 1.49121C16.8994 1.49121 14.7908 2.11724 12.9767 3.30173C12.4945 3.61653 12.3588 4.2626 12.6736 4.74476L14.39 6.46646C14.3263 6.69416 14.3564 6.94682 14.4952 7.16066L16.0917 8.77879C16.0317 8.96194 16.0515 9.16945 16.1637 9.34417L17.8679 11.0139C17.7547 11.4323 17.8613 11.8978 18.1898 12.2264L19.3006 13.3372H31.927C33.3054 13.3372 34.4227 14.4546 34.4227 15.8329V28.4594L38 32.0366V16.1358L25.1723 3.30173C23.3583 2.11732 21.2496 1.49121 19.0745 1.49121Z" fill="url(#paint10_linear_3415_1104)"/>
<path d="M21.7117 8.35279C20.9031 7.83324 19.9655 7.55859 19.0005 7.55859C18.0355 7.55859 17.0981 7.83324 16.2893 8.35272C15.981 8.55084 15.8917 8.96132 16.0897 9.26956C16.2878 9.57781 16.6982 9.66715 17.0066 9.46917C17.6009 9.08739 18.2904 8.88554 19.0005 8.88554C19.7107 8.88554 20.4002 9.08739 20.9945 9.46917C21.1055 9.54048 21.2296 9.57453 21.3525 9.57453C21.5708 9.57453 21.7846 9.46686 21.9113 9.26956C22.1094 8.96139 22.02 8.55084 21.7117 8.35279Z" fill="url(#paint11_linear_3415_1104)"/>
<path d="M23.3287 5.90666C22.0398 5.06947 20.543 4.62695 19.0002 4.62695C17.4574 4.62695 15.9607 5.06947 14.6717 5.90658C14.2766 6.1632 14.1643 6.69155 14.421 7.08667C14.6776 7.4818 15.206 7.59401 15.6011 7.3374C16.6127 6.68037 17.7881 6.33308 19.0002 6.33308C20.2123 6.33308 21.3878 6.68037 22.3994 7.3374C22.5429 7.43061 22.704 7.47517 22.8632 7.47517C23.1424 7.47517 23.416 7.33822 23.5794 7.08667C23.8361 6.69155 23.7238 6.16327 23.3287 5.90666Z" fill="url(#paint12_linear_3415_1104)"/>
<path d="M25.0982 3.22758C23.2841 2.0431 21.1755 1.41699 19.0003 1.41699C16.8252 1.41699 14.7166 2.04302 12.9024 3.22751C12.4203 3.54231 12.2846 4.18838 12.5994 4.67054C12.9142 5.15269 13.5603 5.28837 14.0424 4.97357C15.5167 4.01105 17.2311 3.5023 19.0003 3.5023C20.7696 3.5023 22.484 4.01105 23.9582 4.97364C24.134 5.08846 24.3317 5.14338 24.5272 5.14338C24.8676 5.14338 25.2013 4.97692 25.4012 4.67061C25.716 4.18846 25.5804 3.54238 25.0982 3.22758Z" fill="url(#paint13_linear_3415_1104)"/>
<path d="M19.0002 12.5189C19.6912 12.5189 20.2514 11.9588 20.2514 11.2678C20.2514 10.5768 19.6912 10.0166 19.0002 10.0166C18.3092 10.0166 17.749 10.5768 17.749 11.2678C17.749 11.9588 18.3092 12.5189 19.0002 12.5189Z" fill="url(#paint14_linear_3415_1104)"/>
<defs>
<linearGradient id="paint0_linear_3415_1104" x1="19.0001" y1="22.0548" x2="19.0001" y2="35.447" 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_3415_1104" x1="6.55642" y1="29.1897" x2="2.75642" y2="29.1897" 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_3415_1104" x1="19.0364" y1="11.8037" x2="19.0364" y2="13.8913" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint3_linear_3415_1104" x1="19.0364" y1="14.9326" x2="19.0364" y2="17.0202" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint4_linear_3415_1104" x1="19.0364" y1="18.0625" x2="19.0364" y2="20.1501" gradientUnits="userSpaceOnUse">
<stop stop-color="#017297"/>
<stop offset="1" stop-color="#024C67"/>
</linearGradient>
<linearGradient id="paint5_linear_3415_1104" x1="8.5956" y1="5.36746" x2="26.3289" y2="36.9596" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint6_linear_3415_1104" x1="19" y1="-5.51269" x2="19" y2="16.7501" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint7_linear_3415_1104" x1="18.9999" y1="8.21578" x2="18.9999" y2="6.61255" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint8_linear_3415_1104" x1="18.9999" y1="11.4189" x2="18.9999" y2="9.81568" gradientUnits="userSpaceOnUse">
<stop stop-color="#EAF9FA"/>
<stop offset="1" stop-color="#B3DAFE"/>
</linearGradient>
<linearGradient id="paint9_linear_3415_1104" x1="13.1332" y1="14.0993" x2="9.70572" y2="7.31888" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint10_linear_3415_1104" x1="28.616" y1="14.9578" x2="17.9611" y2="0.279385" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BACDF" stop-opacity="0"/>
<stop offset="1" stop-color="#7BACDF"/>
</linearGradient>
<linearGradient id="paint11_linear_3415_1104" x1="18.4669" y1="7.38439" x2="19.3768" y2="9.98784" 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="paint12_linear_3415_1104" x1="18.2352" y1="3.84222" x2="19.2715" y2="7.60831" 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="paint13_linear_3415_1104" x1="18.1995" y1="1.17089" x2="19.3116" y2="5.24031" 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="paint14_linear_3415_1104" x1="17.7869" y1="10.0545" x2="19.7964" y2="12.064" 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_3415_1104">
<rect width="33.2119" height="25.9556" fill="white" transform="translate(2.40332 11.9824)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -0,0 +1,3 @@
<svg width="13" height="23" viewBox="0 0 13 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.95088 0L0.141105 11.2883H4.3742L0 23L11.5706 9.17177H7.47851L12.8404 0H3.95088Z" fill="#F7CF52"/>
</svg>

After

Width:  |  Height:  |  Size: 213 B

View File

@ -0,0 +1,20 @@
<svg width="36" height="33" viewBox="0 0 36 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32.7404 13.0391H30.5674V19.5582H32.7404C34.5406 19.5582 36 18.0988 36 16.2986C36 14.4984 34.5406 13.0391 32.7404 13.0391Z" fill="#A5A8AB"/>
<path d="M30.5674 13.0391H3.25956C1.45934 13.0391 0 14.4984 0 16.2986C0 18.0988 1.45934 19.5582 3.25956 19.5582H30.5674C32.3676 19.5582 33.827 18.0988 33.827 16.2986C33.827 14.4984 32.3676 13.0391 30.5674 13.0391Z" fill="#C2C4C6"/>
<path d="M32.7404 15.2119H30.5674V17.385H32.7404C33.3405 17.385 33.8269 16.8985 33.8269 16.2984C33.8269 15.6984 33.3405 15.2119 32.7404 15.2119Z" fill="#414851"/>
<path d="M30.5672 15.2119H3.25937C2.65932 15.2119 2.17285 15.6984 2.17285 16.2984C2.17285 16.8985 2.65932 17.385 3.25937 17.385H30.5672C31.1673 17.385 31.6537 16.8985 31.6537 16.2984C31.6537 15.6984 31.1673 15.2119 30.5672 15.2119Z" fill="#62676F"/>
<path d="M11.9521 10.8652V21.7304C14.9525 21.7304 17.3847 19.2981 17.3847 16.2978C17.3847 13.2975 14.9525 10.8652 11.9521 10.8652Z" fill="#FCBE64"/>
<path d="M15.2117 16.2978C15.2117 13.2975 13.7523 10.8652 11.9521 10.8652C8.95181 10.8652 6.51953 13.2975 6.51953 16.2978C6.51953 19.2981 8.95181 21.7304 11.9521 21.7304C13.7523 21.7304 15.2117 19.2981 15.2117 16.2978Z" fill="#FBDB63"/>
<path d="M32.7404 2.17285H30.5674V8.69197H32.7404C34.5406 8.69197 36 7.23263 36 5.43241C36 3.63219 34.5406 2.17285 32.7404 2.17285Z" fill="#A5A8AB"/>
<path d="M30.5674 2.17285H3.25956C1.45934 2.17285 0 3.63219 0 5.43241C0 7.23263 1.45934 8.69197 3.25956 8.69197H30.5674C32.3676 8.69197 33.827 7.23263 33.827 5.43241C33.827 3.63219 32.3676 2.17285 30.5674 2.17285Z" fill="#C2C4C6"/>
<path d="M32.7404 4.3457H30.5674V6.51874H32.7404C33.3405 6.51874 33.8269 6.03227 33.8269 5.43222C33.8269 4.83217 33.3405 4.3457 32.7404 4.3457Z" fill="#414851"/>
<path d="M30.5672 4.3457H3.25937C2.65932 4.3457 2.17285 4.83217 2.17285 5.43222C2.17285 6.03227 2.65932 6.51874 3.25937 6.51874H30.5672C31.1673 6.51874 31.6537 6.03227 31.6537 5.43222C31.6537 4.83217 31.1673 4.3457 30.5672 4.3457Z" fill="#62676F"/>
<path d="M24.0479 0V10.8652C27.0482 10.8652 29.4804 8.43291 29.4804 5.4326C29.4804 2.43228 27.0482 0 24.0479 0Z" fill="#FA342D"/>
<path d="M27.3074 5.4326C27.3074 2.43228 25.848 0 24.0478 0C21.0475 0 18.6152 2.43228 18.6152 5.4326C18.6152 8.43291 21.0475 10.8652 24.0478 10.8652C25.848 10.8652 27.3074 8.43291 27.3074 5.4326Z" fill="#FE5E49"/>
<path d="M32.7404 23.9033H30.5674V30.4224H32.7404C34.5406 30.4224 36 28.9631 36 27.1629C36 25.3627 34.5406 23.9033 32.7404 23.9033Z" fill="#A5A8AB"/>
<path d="M30.5674 23.9033H3.25956C1.45934 23.9033 0 25.3627 0 27.1629C0 28.9631 1.45934 30.4224 3.25956 30.4224H30.5674C32.3676 30.4224 33.827 28.9631 33.827 27.1629C33.827 25.3627 32.3676 23.9033 30.5674 23.9033Z" fill="#C2C4C6"/>
<path d="M32.7404 26.0762H30.5674V28.2492H32.7404C33.3405 28.2492 33.8269 27.7627 33.8269 27.1627C33.8269 26.5626 33.3405 26.0762 32.7404 26.0762Z" fill="#414851"/>
<path d="M30.5672 26.0762H3.25937C2.65932 26.0762 2.17285 26.5626 2.17285 27.1627C2.17285 27.7627 2.65932 28.2492 3.25937 28.2492H30.5672C31.1673 28.2492 31.6537 27.7627 31.6537 27.1627C31.6537 26.5626 31.1673 26.0762 30.5672 26.0762Z" fill="#62676F"/>
<path d="M24.0479 21.7295V32.5947C27.0482 32.5947 29.4804 30.1624 29.4804 27.1621C29.4804 24.1618 27.0482 21.7295 24.0479 21.7295Z" fill="#7D99E8"/>
<path d="M27.3074 27.1621C27.3074 24.1618 25.848 21.7295 24.0478 21.7295C21.0475 21.7295 18.6152 24.1618 18.6152 27.1621C18.6152 30.1624 21.0475 32.5947 24.0478 32.5947C25.848 32.5947 27.3074 30.1624 27.3074 27.1621Z" fill="#83B3F1"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

18
assets/icons/records.svg Normal file
View File

@ -0,0 +1,18 @@
<svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.62771 22.7853L0.0206433 9.9747C-0.0455284 9.78815 0.0527038 9.5815 0.239256 9.51335C6.29643 7.33481 13.1218 5.30864 18.9563 2.81914C19.2171 2.65467 19.4217 2.81716 19.534 3.12805L26.7725 21.7863L28.7381 27.2528C28.8043 27.4393 28.7081 27.6479 28.5215 27.7142L14.6702 32.6952L9.27087 34.6371C9.08432 34.7053 8.87774 34.607 8.80958 34.4204L4.62771 22.7853Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.46894 18.5343L6.16844 5.11787C6.13433 4.92127 6.26674 4.73472 6.46129 4.70061L22.3042 1.98442L25.9325 1.38662C26.1311 1.30035 26.454 1.40063 26.5302 1.84401L30.4493 21.415L31.4301 27.1403C31.4642 27.3349 31.3318 27.5235 31.1372 27.5576L16.6301 30.0451L10.974 31.016C10.7795 31.0481 10.5909 30.9157 10.5568 30.7211L8.46894 18.5343Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9063 14.5779V27.4768C12.9063 27.6835 13.0748 27.854 13.2814 27.854H19.2684H28.1315H29.4051H34.624C34.8305 27.854 34.999 27.6835 34.999 27.4768V21.4166V4.67611V4.50159H31.1882C30.8212 4.50159 30.059 4.55375 30.059 3.72127L30.0509 0H13.2813C13.0748 0 12.9062 0.168505 12.9062 0.375155V3.59487V4.957V14.5779H12.9063Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.54915 7.3418C4.40308 8.06401 2.27704 8.78014 0.239256 9.51234C0.0527037 9.58056 -0.0455284 9.78714 0.0206433 9.97369L4.62771 22.7843L8.80958 34.4194C8.87781 34.606 9.08439 34.7043 9.27087 34.636L14.6702 32.6942L26.9732 28.2709L6.54915 7.3418Z" fill="#B5C4CF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9076 3.59473L6.46129 4.70003C6.26674 4.73414 6.13433 4.92069 6.16844 5.11729L6.54955 7.34197L8.469 18.5337L10.5569 30.7205C10.591 30.9151 10.7795 31.0474 10.9741 31.0154L16.6301 30.0445L26.9735 28.2711L29.4064 27.8538H28.1328L12.9076 3.59473Z" fill="#D7E7EC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.999 21.4166V4.67611V4.50159V4.44342C34.999 4.33507 34.9528 4.31702 34.7864 4.15453L30.6727 0.230712C30.4782 0.0461424 30.4461 0 30.3318 0H30.0509H13.2813C13.0748 0 12.9062 0.168505 12.9062 0.375155V27.4768C12.9062 27.6835 13.0748 27.854 13.2813 27.854H34.6239C34.8305 27.854 34.999 27.6835 34.999 27.4768V21.4166Z" fill="#EDF3F4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9077 3.59473L11.3975 3.85353V28.8629C11.3975 29.0716 11.566 29.2401 11.7725 29.2401H17.7595H21.3216L26.9736 28.2712L29.4065 27.8539H28.1329H26.5665H19.2698H13.2828C13.0762 27.8539 12.9077 27.6834 12.9077 27.4768C12.9077 19.5167 12.9077 11.5547 12.9077 3.59473Z" fill="#B5C4CF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.46896 18.5336L6.54951 7.3418C6.03005 7.51632 5.51257 7.69084 4.99707 7.86536L5.23578 9.25558L7.15524 20.4473L9.24518 32.6341C9.27724 32.8286 9.46578 32.961 9.66033 32.929L15.3164 31.9581L18 31.4987L26.0829 28.59L25.9867 28.4395L21.3214 29.2399L16.6302 30.0444L10.9741 31.0153C10.7796 31.0474 10.591 30.915 10.5569 30.7204L8.46896 18.5336Z" fill="#9AAFB7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.9998 21.4166V4.67611V4.50159C34.9998 4.29897 34.9337 4.29699 34.7873 4.15453L30.6736 0.230712C30.4791 0.0461424 30.447 0 30.3326 0H30.0518H25.8779C30.9784 6.8286 31.2692 19.1377 27.4845 26.8209C27.31 27.178 27.1275 27.521 26.937 27.854H28.1323H29.4059H34.6248C34.8313 27.854 34.9998 27.6835 34.9998 27.4768V21.4166Z" fill="#D7E7EC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.0607 3.72127C30.0607 4.55375 30.8229 4.50159 31.19 4.50159H35.0008V4.44342C35.0008 4.33507 34.9546 4.31702 34.7882 4.15453L30.6745 0.230712C30.48 0.0461424 30.4479 0 30.3336 0H30.0527L30.0607 3.72127Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.7882 4.15453L30.6745 0.230712C30.48 0.0461424 30.4479 0 30.3336 0H30.0527L30.0607 3.7212C30.0607 4.55368 30.8229 4.50152 31.19 4.50152H35.0008V4.44335C35.0008 4.33507 34.9546 4.31702 34.7882 4.15453Z" fill="#B5C4CF"/>
<path d="M31.6094 8.20318H16.5086C16.2169 8.20318 15.9805 7.96666 15.9805 7.67483C15.9805 7.38301 16.2169 7.14648 16.5086 7.14648H31.6094C31.9011 7.14648 32.1376 7.38301 32.1376 7.67483C32.1376 7.96666 31.9012 8.20318 31.6094 8.20318Z" fill="#9AAFB7"/>
<path d="M31.6094 11.9571H16.5086C16.2169 11.9571 15.9805 11.7206 15.9805 11.4287C15.9805 11.1369 16.2169 10.9004 16.5086 10.9004H31.6094C31.9011 10.9004 32.1376 11.1369 32.1376 11.4287C32.1376 11.7206 31.9012 11.9571 31.6094 11.9571Z" fill="#9AAFB7"/>
<path d="M31.6094 15.71H16.5086C16.2169 15.71 15.9805 15.4735 15.9805 15.1817C15.9805 14.8898 16.2169 14.6533 16.5086 14.6533H31.6094C31.9011 14.6533 32.1376 14.8898 32.1376 15.1817C32.1376 15.4735 31.9012 15.71 31.6094 15.71Z" fill="#9AAFB7"/>
<path d="M31.6094 19.4639H16.5086C16.2169 19.4639 15.9805 19.2274 15.9805 18.9356C15.9805 18.6437 16.2169 18.4072 16.5086 18.4072H31.6094C31.9011 18.4072 32.1376 18.6437 32.1376 18.9356C32.1376 19.2274 31.9012 19.4639 31.6094 19.4639Z" fill="#9AAFB7"/>
<path d="M31.6094 23.2169H16.5086C16.2169 23.2169 15.9805 22.9803 15.9805 22.6885C15.9805 22.3967 16.2169 22.1602 16.5086 22.1602H31.6094C31.9011 22.1602 32.1376 22.3967 32.1376 22.6885C32.1376 22.9803 31.9012 23.2169 31.6094 23.2169Z" fill="#9AAFB7"/>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.9333 20H9.06667C8.43583 20 7.90333 19.5275 7.82833 18.9L7.62917 17.3367C7.23167 17.2075 6.84833 17.0483 6.48417 16.8625L5.23917 17.83C4.73417 18.2208 4.02333 18.1758 3.585 17.725L2.2725 16.4125C1.825 15.9783 1.78 15.2675 2.17083 14.7633L3.13833 13.5175C2.95167 13.1533 2.7925 12.77 2.66417 12.3725L1.0975 12.1733C0.4725 12.0967 0 11.5642 0 10.9333V9.06667C0 8.43583 0.4725 7.90333 1.1 7.82833L2.66333 7.62917C2.7925 7.23167 2.95167 6.84833 3.1375 6.48417L2.17083 5.23917C1.77917 4.73417 1.825 4.0225 2.27667 3.58417L3.58917 2.27167C4.02333 1.82417 4.735 1.78 5.23833 2.17L6.48333 3.13833C6.8475 2.9525 7.23083 2.79333 7.62917 2.66417L7.82833 1.0975C7.90333 0.4725 8.43583 0 9.06667 0H10.9333C11.5642 0 12.0967 0.4725 12.1717 1.1L12.3708 2.66333C12.7692 2.7925 13.1525 2.95167 13.5167 3.1375L14.7617 2.17C15.2675 1.77917 15.9775 1.82417 16.4158 2.27583L17.7283 3.58833C18.1758 4.0225 18.2208 4.73333 17.83 5.2375L16.8625 6.48333C17.0492 6.8475 17.2083 7.23083 17.3367 7.62833L18.9033 7.8275C19.5275 7.90333 20 8.43583 20 9.06667V10.9333C20 11.5642 19.5275 12.0967 18.9 12.1717L17.3367 12.3708C17.2075 12.7683 17.0483 13.1517 16.8625 13.5158L17.83 14.7608C18.2217 15.2658 18.1758 15.9767 17.7242 16.415L16.4117 17.7275C15.9775 18.175 15.2658 18.2208 14.7625 17.8292L13.5167 16.8617C13.1525 17.0483 12.7692 17.2075 12.3717 17.3358L12.1725 18.9025C12.0967 19.5275 11.5642 20 10.9333 20ZM6.44167 15.95C6.51083 15.95 6.58167 15.9675 6.645 16.0025C7.10417 16.2592 7.60167 16.4658 8.12333 16.6158C8.28333 16.6617 8.40083 16.7983 8.42167 16.9633L8.655 18.7967C8.68 19.0058 8.86083 19.1667 9.06667 19.1667H10.9333C11.1392 19.1667 11.32 19.0058 11.3442 18.8008L11.5783 16.9642C11.5992 16.7992 11.7167 16.6625 11.8767 16.6167C12.3983 16.4667 12.8958 16.26 13.355 16.0033C13.5008 15.9217 13.6825 15.9358 13.8133 16.0383L15.2717 17.1717C15.4392 17.3017 15.6742 17.2908 15.8175 17.1433L17.1383 15.8225C17.2892 15.6758 17.3008 15.4408 17.1708 15.2725L16.0375 13.8142C15.935 13.6825 15.9208 13.5017 16.0025 13.3558C16.2592 12.8967 16.4658 12.3992 16.6158 11.8775C16.6617 11.7175 16.7983 11.6 16.9633 11.5792L18.7967 11.3458C19.0058 11.32 19.1667 11.1392 19.1667 10.9333V9.06667C19.1667 8.86083 19.0058 8.68 18.8008 8.65583L16.9642 8.42167C16.7992 8.40083 16.6625 8.28333 16.6167 8.12333C16.4667 7.60167 16.26 7.10417 16.0033 6.645C15.9217 6.49917 15.935 6.31833 16.0383 6.18667L17.1717 4.72833C17.3025 4.56 17.2908 4.325 17.1442 4.18333L15.8233 2.8625C15.6775 2.71083 15.4417 2.69917 15.2733 2.83L13.815 3.96333C13.6825 4.06583 13.5017 4.08 13.3558 3.99833C12.8983 3.74167 12.4008 3.53583 11.8775 3.385C11.7175 3.33917 11.6 3.2025 11.5792 3.0375L11.3458 1.20417C11.32 0.994167 11.1392 0.833333 10.9333 0.833333H9.06667C8.86083 0.833333 8.68 0.994167 8.65583 1.19917L8.42167 3.03583C8.40083 3.20083 8.28333 3.3375 8.12333 3.38417C7.6 3.53417 7.1025 3.74083 6.645 3.99667C6.49917 4.07917 6.31833 4.06417 6.18583 3.9625L4.7275 2.82917C4.55917 2.69833 4.325 2.71 4.1825 2.85667L2.86167 4.17833C2.71083 4.325 2.69917 4.56 2.82917 4.72833L3.9625 6.18667C4.065 6.31833 4.07917 6.49917 3.9975 6.645C3.74 7.10417 3.53417 7.60167 3.38417 8.12333C3.33833 8.28333 3.20167 8.40083 3.03667 8.42167L1.20333 8.655C0.994167 8.68 0.833333 8.86083 0.833333 9.06667V10.9333C0.833333 11.1392 0.994167 11.32 1.19917 11.3442L3.03583 11.5783C3.20083 11.5992 3.3375 11.7167 3.38333 11.8767C3.53333 12.3983 3.74 12.8958 3.99667 13.355C4.07833 13.5008 4.065 13.6817 3.96167 13.8133L2.82833 15.2717C2.6975 15.44 2.70917 15.675 2.85583 15.8167L4.17667 17.1375C4.3225 17.2883 4.55667 17.3 4.72667 17.17L6.185 16.0367C6.26083 15.98 6.35083 15.95 6.44167 15.95Z" fill="black"/>
<path d="M10.0002 14.1666C7.70266 14.1666 5.8335 12.2974 5.8335 9.99992C5.8335 7.70242 7.70266 5.83325 10.0002 5.83325C12.2977 5.83325 14.1668 7.70242 14.1668 9.99992C14.1668 12.2974 12.2977 14.1666 10.0002 14.1666ZM10.0002 6.66659C8.16183 6.66659 6.66683 8.16159 6.66683 9.99992C6.66683 11.8383 8.16183 13.3333 10.0002 13.3333C11.8385 13.3333 13.3335 11.8383 13.3335 9.99992C13.3335 8.16159 11.8385 6.66659 10.0002 6.66659Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 10C20 10 20 10.0017 20 10.0025C19.9983 10.5633 19.7783 11.0892 19.3783 11.4825L15.9267 14.88C15.8458 14.96 15.74 15 15.6342 15C15.5267 15 15.4192 14.9583 15.3375 14.8758C15.1767 14.7125 15.1783 14.4483 15.3425 14.2867L18.7942 10.8892C18.9308 10.7542 19.0283 10.5925 19.0908 10.4175H5.41667C5.18667 10.4175 5 10.2308 5 10.0008C5 9.77083 5.18667 9.58417 5.41667 9.58417H19.0917C19.0292 9.40667 18.9317 9.24333 18.7933 9.1075L15.3425 5.71417C15.1783 5.55333 15.1758 5.28917 15.3375 5.125C15.4983 4.96 15.7625 4.95833 15.9267 5.12L19.3775 8.51333C19.7783 8.90833 20 9.435 20 9.99833C20 9.99833 20 9.99917 20 10ZM9.58333 12.5C9.35333 12.5 9.16667 12.6867 9.16667 12.9167V16.25C9.16667 17.8583 7.85833 19.1667 6.25 19.1667H3.75C2.14167 19.1667 0.833333 17.8583 0.833333 16.25V3.75C0.833333 2.14167 2.14167 0.833333 3.75 0.833333H6.25C7.85833 0.833333 9.16667 2.14167 9.16667 3.75V7.08333C9.16667 7.31333 9.35333 7.5 9.58333 7.5C9.81333 7.5 10 7.31333 10 7.08333V3.75C10 1.6825 8.3175 0 6.25 0H3.75C1.6825 0 0 1.6825 0 3.75V16.25C0 18.3175 1.6825 20 3.75 20H6.25C8.3175 20 10 18.3175 10 16.25V12.9167C10 12.6867 9.81333 12.5 9.58333 12.5Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

23
assets/icons/sos.svg Normal file
View File

@ -0,0 +1,23 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.9985 35.3366C13.3686 35.3366 9.01577 33.5305 5.74189 30.2509C2.46802 26.9714 0.665039 22.611 0.665039 17.973C0.665039 13.3351 2.46802 8.97466 5.74197 5.69509C9.01577 2.41552 13.3686 0.609375 17.9985 0.609375C22.6284 0.609375 26.9813 2.41552 30.2552 5.69509C33.5291 8.97459 35.3321 13.3351 35.3321 17.973C35.3321 22.611 33.5291 26.9714 30.2552 30.251C26.9814 33.5305 22.6285 35.3366 17.9985 35.3366Z" fill="#CBC4CC"/>
<path d="M17.9971 32.1589C25.8176 32.1589 32.1574 25.8081 32.1574 17.974C32.1574 10.1399 25.8176 3.78906 17.9971 3.78906C10.1767 3.78906 3.83691 10.1399 3.83691 17.974C3.83691 25.8081 10.1767 32.1589 17.9971 32.1589Z" fill="#F3F0F3"/>
<path d="M17.9987 29.9667C24.6119 29.9667 29.9729 24.5963 29.9729 17.9716C29.9729 11.3469 24.6119 5.97656 17.9987 5.97656C11.3855 5.97656 6.02441 11.3469 6.02441 17.9716C6.02441 24.5963 11.3855 29.9667 17.9987 29.9667Z" fill="#FD4755"/>
<path d="M17.998 5.97656C17.5223 5.97656 17.0532 6.00539 16.5918 6.05967C22.5342 6.75926 27.1598 11.8341 27.1598 17.9716C27.1598 24.1091 22.5342 29.184 16.5918 29.8835C17.0532 29.9379 17.5223 29.9666 17.998 29.9666C24.6007 29.9666 29.9723 24.5857 29.9723 17.9716C29.9723 11.3574 24.6007 5.97656 17.998 5.97656Z" fill="#FB2B3A"/>
<path d="M11.9123 11.6183C11.7669 11.6183 11.6221 11.5585 11.5179 11.4412C11.3245 11.2235 11.3441 10.8903 11.5618 10.6968C13.3402 9.1164 15.6268 8.24609 18.0005 8.24609C18.2918 8.24609 18.5278 8.4822 18.5278 8.77342C18.5278 9.06465 18.2918 9.30075 18.0005 9.30075C15.8853 9.30075 13.8475 10.0766 12.2624 11.4852C12.162 11.5744 12.0369 11.6183 11.9123 11.6183Z" fill="#FD8087"/>
<path d="M18 27.6995C17.7087 27.6995 17.4727 27.4634 17.4727 27.1722C17.4727 26.881 17.7087 26.6449 18 26.6449C20.0643 26.6449 22.0648 25.9017 23.6329 24.5524C23.8537 24.3625 24.1866 24.3874 24.3765 24.6082C24.5665 24.8289 24.5416 25.1619 24.3208 25.3518C22.5614 26.8658 20.3167 27.6995 18 27.6995Z" fill="#FD8087"/>
<path d="M12.6912 17.52C12.5691 17.4748 12.4351 17.4321 12.2934 17.3867C11.8625 17.2491 11.2115 17.041 11.0522 16.7438C10.9746 16.5988 10.9675 16.4474 11.0312 16.2938C11.1145 16.0925 11.3047 15.9258 11.5275 15.8585C12.368 15.605 13.1315 16.2164 13.1479 16.2296C13.3707 16.4153 13.7018 16.3863 13.8889 16.1642C14.0765 15.9414 14.0479 15.6087 13.8252 15.4211C13.7768 15.3804 12.6225 14.4266 11.2228 14.8488C10.6971 15.0074 10.2613 15.3967 10.0569 15.89C9.87159 16.3369 9.89493 16.8171 10.1227 17.242C10.4838 17.9157 11.3442 18.1906 11.9724 18.3913C12.1027 18.433 12.2257 18.4723 12.3257 18.5093C12.8999 18.7215 13.1921 19.0502 13.1275 19.4114C13.0627 19.7734 12.6382 20.148 12.0399 20.148C11.4628 20.148 10.9059 19.9133 10.5502 19.5201C10.3549 19.3041 10.0214 19.2875 9.80543 19.4828C9.58943 19.6782 9.5727 20.0116 9.76816 20.2276C10.3204 20.8382 11.1697 21.2027 12.0399 21.2027C13.088 21.2027 14.0019 20.5124 14.1656 19.5971C14.2899 18.9022 13.9679 17.9917 12.6912 17.52Z" fill="white"/>
<path d="M24.8679 17.52C24.7458 17.4749 24.6119 17.4321 24.4701 17.3868C24.0393 17.2491 23.3882 17.0411 23.2289 16.7438C23.1512 16.5989 23.1441 16.4475 23.2078 16.2938C23.2912 16.0926 23.4814 15.9258 23.7042 15.8586C24.5432 15.6052 25.3058 16.2145 25.3245 16.2296C25.5472 16.4154 25.8785 16.3864 26.0655 16.1642C26.2531 15.9415 26.2246 15.6088 26.0019 15.4212C25.9535 15.3804 24.7992 14.4266 23.3995 14.8488C22.8739 15.0075 22.438 15.3967 22.2335 15.89C22.0483 16.337 22.0716 16.8171 22.2994 17.242C22.6605 17.9157 23.5209 18.1906 24.1492 18.3914C24.2795 18.4331 24.4025 18.4724 24.5025 18.5094C25.0766 18.7216 25.3688 19.0503 25.3042 19.4114C25.2395 19.7735 24.8149 20.1481 24.2166 20.1481C23.6396 20.1481 23.0827 19.9134 22.727 19.5202C22.5317 19.3042 22.1982 19.2876 21.9822 19.4829C21.7662 19.6783 21.7495 20.0117 21.9449 20.2277C22.4971 20.8383 23.3464 21.2027 24.2166 21.2027C25.2648 21.2027 26.1787 20.5125 26.3424 19.5972C26.4666 18.9022 26.1446 17.9917 24.8679 17.52Z" fill="white"/>
<path d="M18.0001 14.7412C16.2214 14.7412 14.7744 16.1905 14.7744 17.9718C14.7744 19.7532 16.2214 21.2025 18.0001 21.2025C19.7787 21.2025 21.2257 19.7532 21.2257 17.9718C21.2257 16.1905 19.7787 14.7412 18.0001 14.7412ZM18.0001 20.1478C16.803 20.1478 15.8291 19.1717 15.8291 17.9718C15.8291 16.772 16.803 15.7959 18.0001 15.7959C19.1971 15.7959 20.171 16.772 20.171 17.9718C20.171 19.1717 19.1972 20.1478 18.0001 20.1478Z" fill="white"/>
<path d="M3.46424 31.8394L1.62871 33.6782C1.42298 33.8844 1.42327 34.2182 1.62942 34.4239C1.73242 34.5267 1.86721 34.578 2.00199 34.578C2.13713 34.578 2.27227 34.5264 2.3752 34.4232L4.21073 32.5844C4.41646 32.3782 4.41618 32.0444 4.21003 31.8387C4.00374 31.6329 3.66983 31.6332 3.46424 31.8394Z" fill="#F3F0F3"/>
<path d="M2.02488 29.2304C1.85768 28.992 1.5287 28.9343 1.29041 29.1015L0.224575 29.8492C-0.0139194 30.0165 -0.0715742 30.3453 0.095695 30.5837C0.198278 30.73 0.361751 30.8082 0.527825 30.8082C0.632377 30.8082 0.738054 30.7772 0.830161 30.7126L1.896 29.9649C2.1345 29.7977 2.19215 29.4688 2.02488 29.2304Z" fill="#F3F0F3"/>
<path d="M6.81289 34.0297C6.57418 33.8629 6.24555 33.9212 6.07856 34.1598L5.37152 35.1714C5.20467 35.4101 5.26296 35.7389 5.50166 35.9057C5.5937 35.97 5.69902 36.0008 5.80329 36.0008C5.96965 36.0008 6.1334 35.9223 6.23599 35.7756L6.94303 34.764C7.10988 34.5253 7.05159 34.1965 6.81289 34.0297Z" fill="#F3F0F3"/>
<path d="M32.5324 31.8394C32.3266 31.6333 31.9927 31.6329 31.7866 31.8387C31.5805 32.0444 31.5802 32.3783 31.7859 32.5844L33.6215 34.4233C33.7245 34.5265 33.8595 34.5781 33.9947 34.5781C34.1295 34.5781 34.2643 34.5267 34.3673 34.424C34.5734 34.2182 34.5737 33.8843 34.368 33.6782L32.5324 31.8394Z" fill="#F3F0F3"/>
<path d="M35.77 29.8492L34.7042 29.1015C34.4656 28.9343 34.1369 28.992 33.9697 29.2304C33.8024 29.4688 33.8601 29.7977 34.0986 29.9649L35.1644 30.7126C35.2566 30.7772 35.3622 30.8082 35.4668 30.8082C35.6328 30.8082 35.7964 30.73 35.8989 30.5837C36.0661 30.3453 36.0084 30.0165 35.77 29.8492Z" fill="#F3F0F3"/>
<path d="M29.9157 34.1579C29.7488 33.9193 29.4202 33.8609 29.1813 34.0277C28.9426 34.1946 28.8844 34.5234 29.0512 34.7621L29.7582 35.7736C29.8608 35.9203 30.0245 35.9989 30.1909 35.9989C30.2952 35.9989 30.4005 35.968 30.4926 35.9038C30.7313 35.7369 30.7896 35.4082 30.6227 35.1695L29.9157 34.1579Z" fill="#F3F0F3"/>
<path d="M32.1591 4.31343C32.2943 4.31343 32.4294 4.26182 32.5324 4.1586L34.3679 2.31977C34.5736 2.11362 34.5733 1.77978 34.3672 1.57405C34.1609 1.36825 33.827 1.3686 33.6215 1.57476L31.7859 3.41359C31.5802 3.61974 31.5805 3.95358 31.7866 4.15931C31.8896 4.2621 32.0244 4.31343 32.1591 4.31343Z" fill="#F3F0F3"/>
<path d="M33.9697 6.76829C34.0723 6.91461 34.2358 6.9928 34.4018 6.9928C34.5064 6.9928 34.6121 6.96179 34.7042 6.89717L35.77 6.14949C36.0085 5.98222 36.0662 5.65338 35.8989 5.41495C35.7317 5.17653 35.4027 5.11888 35.1644 5.28607L34.0986 6.03376C33.8601 6.20103 33.8024 6.52987 33.9697 6.76829Z" fill="#F3F0F3"/>
<path d="M30.4926 0.0950873C30.2538 -0.0716194 29.9252 -0.0134724 29.7582 0.225232L29.0512 1.23672C28.8844 1.47543 28.9426 1.8042 29.1813 1.97105C29.2734 2.03531 29.3787 2.06618 29.483 2.06618C29.6493 2.06618 29.8131 1.98764 29.9157 1.8409L30.6227 0.829342C30.7895 0.590707 30.7312 0.261935 30.4926 0.0950873Z" fill="#F3F0F3"/>
<path d="M2.37513 1.57476C2.16933 1.3686 1.83543 1.36825 1.62942 1.57405C1.42327 1.77978 1.42298 2.11369 1.62871 2.31977L3.46424 4.1586C3.56725 4.26182 3.70232 4.31343 3.83745 4.31343C3.97224 4.31343 4.1071 4.2621 4.21003 4.15931C4.41618 3.95358 4.41646 3.61967 4.21073 3.41359L2.37513 1.57476Z" fill="#F3F0F3"/>
<path d="M0.224575 6.14949L1.29041 6.89717C1.38259 6.96179 1.48813 6.9928 1.59275 6.9928C1.75882 6.9928 1.92237 6.91454 2.02488 6.76829C2.19215 6.52987 2.1345 6.20103 1.896 6.03376L0.830161 5.28607C0.591737 5.11888 0.262894 5.17653 0.095695 5.41495C-0.0715742 5.65338 -0.0139194 5.98222 0.224575 6.14949Z" fill="#F3F0F3"/>
<path d="M6.23599 0.225178C6.06914 -0.0133866 5.74051 -0.0716742 5.50166 0.0951028C5.26296 0.26195 5.20467 0.590723 5.37152 0.829428L6.07856 1.84099C6.18114 1.98766 6.34483 2.06626 6.51125 2.06626C6.61552 2.06626 6.72085 2.0354 6.81289 1.97113C7.05159 1.80429 7.10988 1.47551 6.94303 1.23681L6.23599 0.225178Z" fill="#F3F0F3"/>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1,23 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.9974 35.3421C13.3675 35.3421 9.0147 33.536 5.74086 30.2564C2.46702 26.977 0.664062 22.6166 0.664062 17.9787C0.664062 13.3408 2.46702 8.98043 5.74093 5.70089C9.0147 2.42136 13.3675 0.615234 17.9974 0.615234C22.6272 0.615234 26.98 2.42136 30.2539 5.70089C33.5278 8.98036 35.3307 13.3408 35.3307 17.9787C35.3307 22.6166 33.5278 26.977 30.2539 30.2565C26.9801 33.536 22.6273 35.3421 17.9974 35.3421Z" fill="#CBC4CC"/>
<path d="M17.998 32.1683C25.8184 32.1683 32.158 25.8176 32.158 17.9836C32.158 10.1496 25.8184 3.79883 17.998 3.79883C10.1776 3.79883 3.83789 10.1496 3.83789 17.9836C3.83789 25.8176 10.1776 32.1683 17.998 32.1683Z" fill="#F3F0F3"/>
<path d="M17.9995 29.9762C24.6127 29.9762 29.9737 24.6059 29.9737 17.9813C29.9737 11.3566 24.6127 5.98633 17.9995 5.98633C11.3864 5.98633 6.02539 11.3566 6.02539 17.9813C6.02539 24.6059 11.3864 29.9762 17.9995 29.9762Z" fill="#97D729"/>
<path d="M17.998 5.98633C17.5223 5.98633 17.0532 6.01516 16.5918 6.06943C22.5341 6.76902 27.1597 11.8438 27.1597 17.9812C27.1597 24.1186 22.5341 29.1935 16.5918 29.893C17.0532 29.9474 17.5223 29.9761 17.998 29.9761C24.6006 29.9761 29.9721 24.5953 29.9721 17.9812C29.9721 11.3671 24.6006 5.98633 17.998 5.98633Z" fill="#8BC727"/>
<path d="M11.9045 11.6241C11.7591 11.6241 11.6143 11.5643 11.5101 11.447C11.3167 11.2294 11.3363 10.8961 11.554 10.7026C13.3324 9.12225 15.6189 8.25195 17.9926 8.25195C18.2839 8.25195 18.5199 8.48805 18.5199 8.77928C18.5199 9.0705 18.2839 9.3066 17.9926 9.3066C15.8775 9.3066 13.8397 10.0824 12.2546 11.491C12.1541 11.5802 12.0291 11.6241 11.9045 11.6241Z" fill="#8BC727"/>
<path d="M17.9883 27.7083C17.697 27.7083 17.4609 27.4722 17.4609 27.1809C17.4609 26.8897 17.697 26.6536 17.9883 26.6536C20.0526 26.6536 22.053 25.9105 23.6211 24.5612C23.8419 24.3713 24.1748 24.3962 24.3647 24.617C24.5547 24.8377 24.5298 25.1706 24.309 25.3606C22.5496 26.8745 20.3049 27.7083 17.9883 27.7083Z" fill="#8BC727"/>
<path d="M12.6882 17.5248C12.5661 17.4797 12.4322 17.437 12.2904 17.3916C11.8596 17.2539 11.2086 17.0459 11.0492 16.7486C10.9716 16.6037 10.9645 16.4523 11.0282 16.2986C11.1116 16.0974 11.3018 15.9306 11.5245 15.8634C12.365 15.6099 13.1285 16.2213 13.145 16.2345C13.3677 16.4202 13.6989 16.3912 13.8859 16.1691C14.0735 15.9463 14.0449 15.6136 13.8222 15.426C13.7738 15.3852 12.6195 14.4315 11.2198 14.8537C10.6942 15.0123 10.2583 15.4015 10.0539 15.8948C9.86866 16.3418 9.892 16.822 10.1197 17.2468C10.4808 17.9205 11.3412 18.1955 11.9694 18.3962C12.0997 18.4378 12.2227 18.4771 12.3228 18.5141C12.8969 18.7263 13.1891 19.0551 13.1245 19.4162C13.0597 19.7783 12.6353 20.1528 12.0369 20.1528C11.4598 20.1528 10.903 19.9181 10.5473 19.5249C10.352 19.309 10.0185 19.2924 9.8025 19.4876C9.58651 19.683 9.56977 20.0164 9.76523 20.2324C10.3174 20.843 11.1668 21.2075 12.0369 21.2075C13.0851 21.2075 13.9989 20.5172 14.1626 19.6019C14.2869 18.9071 13.9649 17.9965 12.6882 17.5248Z" fill="white"/>
<path d="M24.866 17.5249C24.7438 17.4797 24.6099 17.437 24.4681 17.3916C24.0373 17.254 23.3862 17.0459 23.2269 16.7486C23.1493 16.6037 23.1422 16.4524 23.2059 16.2987C23.2893 16.0974 23.4795 15.9307 23.7023 15.8634C24.5412 15.6101 25.3038 16.2193 25.3225 16.2345C25.5452 16.4202 25.8765 16.3913 26.0635 16.1691C26.2511 15.9463 26.2226 15.6137 25.9999 15.426C25.9515 15.3853 24.7972 14.4314 23.3975 14.8537C22.8719 15.0123 22.4361 15.4016 22.2316 15.8949C22.0463 16.3418 22.0697 16.822 22.2974 17.2469C22.6585 17.9206 23.519 18.1955 24.1473 18.3963C24.2775 18.4379 24.4005 18.4772 24.5005 18.5142C25.0746 18.7264 25.3669 19.0552 25.3022 19.4163C25.2375 19.7784 24.8129 20.1529 24.2146 20.1529C23.6376 20.1529 23.0807 19.9182 22.725 19.525C22.5297 19.309 22.1962 19.2925 21.9802 19.4877C21.7642 19.6831 21.7475 20.0165 21.943 20.2325C22.4952 20.8431 23.3445 21.2076 24.2146 21.2076C25.2628 21.2076 26.1767 20.5173 26.3404 19.602C26.4646 18.9071 26.1426 17.9966 24.866 17.5249Z" fill="white"/>
<path d="M18.001 14.7461C16.2224 14.7461 14.7754 16.1953 14.7754 17.9767C14.7754 19.7581 16.2224 21.2073 18.001 21.2073C19.7796 21.2073 21.2266 19.7581 21.2266 17.9767C21.2266 16.1953 19.7796 14.7461 18.001 14.7461ZM18.001 20.1526C16.804 20.1526 15.83 19.1765 15.83 17.9767C15.83 16.7769 16.804 15.8007 18.001 15.8007C19.198 15.8007 20.172 16.7769 20.172 17.9767C20.172 19.1765 19.1981 20.1526 18.001 20.1526Z" fill="white"/>
<path d="M3.46422 31.8345L1.62871 33.6733C1.42298 33.8795 1.42327 34.2133 1.62941 34.419C1.73242 34.5217 1.8672 34.5731 2.00199 34.5731C2.13712 34.5731 2.27226 34.5215 2.37519 34.4183L4.2107 32.5795C4.41643 32.3733 4.41615 32.0395 4.21 31.8338C4.00371 31.6281 3.66981 31.6283 3.46422 31.8345Z" fill="#F3F0F3"/>
<path d="M2.02486 29.2284C1.85766 28.99 1.52868 28.9324 1.2904 29.0996L0.224572 29.8472C-0.0139193 30.0145 -0.0715734 30.3433 0.0956939 30.5818C0.198276 30.7281 0.361747 30.8063 0.527819 30.8063C0.63237 30.8063 0.738045 30.7752 0.830151 30.7106L1.89598 29.963C2.13447 29.7957 2.19213 29.4668 2.02486 29.2284Z" fill="#F3F0F3"/>
<path d="M6.80994 34.0306C6.57124 33.8639 6.24261 33.9222 6.07562 34.1608L5.36859 35.1723C5.20174 35.411 5.26003 35.7398 5.49873 35.9067C5.59076 35.9709 5.69609 36.0018 5.80036 36.0018C5.96671 36.0018 6.13046 35.9232 6.23305 35.7765L6.94008 34.765C7.10693 34.5263 7.04864 34.1975 6.80994 34.0306Z" fill="#F3F0F3"/>
<path d="M32.5314 31.8345C32.3256 31.6284 31.9917 31.628 31.7857 31.8338C31.5795 32.0395 31.5792 32.3734 31.785 32.5795L33.6205 34.4183C33.7235 34.5216 33.8585 34.5732 33.9937 34.5732C34.1285 34.5732 34.2633 34.5218 34.3662 34.419C34.5724 34.2133 34.5727 33.8794 34.367 33.6733L32.5314 31.8345Z" fill="#F3F0F3"/>
<path d="M35.7729 29.8472L34.7071 29.0996C34.4685 28.9324 34.1398 28.99 33.9726 29.2284C33.8054 29.4668 33.863 29.7957 34.1015 29.963L35.1674 30.7106C35.2595 30.7752 35.3651 30.8063 35.4697 30.8063C35.6358 30.8063 35.7993 30.728 35.9018 30.5818C36.069 30.3433 36.0114 30.0145 35.7729 29.8472Z" fill="#F3F0F3"/>
<path d="M29.9147 34.1608C29.7478 33.9222 29.4192 33.8638 29.1804 34.0307C28.9417 34.1975 28.8834 34.5263 29.0502 34.765L29.7573 35.7765C29.8598 35.9232 30.0235 36.0018 30.1899 36.0018C30.2942 36.0018 30.3995 35.9709 30.4916 35.9067C30.7303 35.7398 30.7886 35.4111 30.6217 35.1724L29.9147 34.1608Z" fill="#F3F0F3"/>
<path d="M32.1582 4.30949C32.2933 4.30949 32.4284 4.25788 32.5314 4.15467L34.3669 2.31585C34.5726 2.1097 34.5723 1.77587 34.3662 1.57014C34.1599 1.36435 33.826 1.3647 33.6205 1.57085L31.785 3.40966C31.5792 3.61581 31.5795 3.94964 31.7857 4.15537C31.8886 4.25816 32.0234 4.30949 32.1582 4.30949Z" fill="#F3F0F3"/>
<path d="M33.9726 6.76339C34.0752 6.90971 34.2387 6.98789 34.4048 6.98789C34.5093 6.98789 34.615 6.95689 34.7071 6.89227L35.7729 6.1446C36.0114 5.97733 36.0691 5.64849 35.9018 5.41007C35.7346 5.17165 35.4056 5.11399 35.1674 5.28119L34.1015 6.02887C33.863 6.19613 33.8054 6.52497 33.9726 6.76339Z" fill="#F3F0F3"/>
<path d="M30.4916 0.0950863C30.2528 -0.0716186 29.9242 -0.0134723 29.7573 0.22523L29.0502 1.23671C28.8834 1.47541 28.9417 1.80418 29.1804 1.97103C29.2724 2.03529 29.3777 2.06615 29.482 2.06615C29.6484 2.06615 29.8121 1.98762 29.9147 1.84088L30.6217 0.829333C30.7885 0.590701 30.7302 0.261932 30.4916 0.0950863Z" fill="#F3F0F3"/>
<path d="M2.37512 1.57085C2.16932 1.3647 1.83542 1.36435 1.62941 1.57014C1.42327 1.77587 1.42298 2.10977 1.62871 2.31585L3.46422 4.15467C3.56723 4.25788 3.70229 4.30949 3.83743 4.30949C3.97221 4.30949 4.10707 4.25816 4.21 4.15537C4.41615 3.94964 4.41643 3.61574 4.2107 3.40966L2.37512 1.57085Z" fill="#F3F0F3"/>
<path d="M0.224572 6.1446L1.2904 6.89227C1.38258 6.95689 1.48811 6.98789 1.59273 6.98789C1.75881 6.98789 1.92235 6.90964 2.02486 6.76339C2.19213 6.52497 2.13447 6.19613 1.89598 6.02887L0.830151 5.28119C0.59173 5.11399 0.262891 5.17165 0.0956939 5.41007C-0.0715734 5.64849 -0.0139193 5.97733 0.224572 6.1446Z" fill="#F3F0F3"/>
<path d="M6.23305 0.225175C6.0662 -0.0133865 5.73757 -0.0716734 5.49873 0.0951017C5.26003 0.261947 5.20174 0.590716 5.36859 0.829419L6.07562 1.84097C6.1782 1.98763 6.34189 2.06624 6.50831 2.06624C6.61258 2.06624 6.7179 2.03537 6.80994 1.97111C7.04864 1.80427 7.10693 1.4755 6.94008 1.23679L6.23305 0.225175Z" fill="#F3F0F3"/>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1,16 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 24C8.8072 24 5.79717 22.7483 3.52439 20.4756C1.25166 18.2028 0 15.1928 0 12C0 8.8072 1.25166 5.79717 3.52444 3.52444C5.79717 1.25166 8.8072 0 12 0C15.1928 0 18.2028 1.25166 20.4756 3.52444C22.7483 5.79717 24 8.8072 24 12C24 15.1928 22.7483 18.2028 20.4756 20.4756C18.2028 22.7483 15.1928 24 12 24Z" fill="#EDF3F9"/>
<path d="M20.4756 20.4756C22.7483 18.2028 24 15.1928 24 12C24 8.8072 22.7483 5.79717 20.4756 3.52444C18.2028 1.25166 15.1928 0 12 0V24C15.1928 24 18.2028 22.7483 20.4756 20.4756Z" fill="#C2DBF2"/>
<path d="M12 22.5938C17.8508 22.5938 22.5938 17.8508 22.5938 12C22.5938 6.14923 17.8508 1.40625 12 1.40625C6.14923 1.40625 1.40625 6.14923 1.40625 12C1.40625 17.8508 6.14923 22.5938 12 22.5938Z" fill="#465A61"/>
<path d="M22.5938 12C22.5938 6.15858 17.8414 1.40625 12 1.40625V22.5938C17.8414 22.5938 22.5938 17.8414 22.5938 12Z" fill="#3B4A51"/>
<path d="M7.88953 9.29576C7.37672 10.072 7.07812 11.002 7.07812 12V12.7031H2.85938V12C2.85938 9.83717 3.61453 7.84779 4.87453 6.28076L7.88953 9.29576Z" fill="#F36A3D"/>
<path d="M21.1408 12V12.7031H16.922V12C16.922 11.002 16.6234 10.072 16.1106 9.29576L19.1256 6.28076C20.3856 7.84779 21.1408 9.83717 21.1408 12Z" fill="#66A6FF"/>
<path d="M19.1255 6.28078L16.1105 9.29578C15.2292 7.96078 13.7161 7.07812 12 7.07812V2.85938C14.8772 2.85938 17.4488 4.19578 19.1255 6.28078Z" fill="#FFDF40"/>
<path d="M12 2.85938V7.07812C10.2839 7.07812 8.77076 7.96078 7.88951 9.29578L4.87451 6.28078C6.55123 4.19578 9.12279 2.85938 12 2.85938Z" fill="#FF9F40"/>
<path d="M11.2969 8.48438H12.7031V14.8594H11.2969V8.48438Z" fill="#F36A3D"/>
<path d="M12 8.48438H12.7031V14.8594H12V8.48438Z" fill="#EC4C36"/>
<path d="M12 24C15.1066 24 17.625 21.4816 17.625 18.375C17.625 15.2684 15.1066 12.75 12 12.75C8.8934 12.75 6.375 15.2684 6.375 18.375C6.375 21.4816 8.8934 24 12 24Z" fill="#FFDF40"/>
<path d="M17.625 18.375C17.625 15.2734 15.1016 12.75 12 12.75V24C15.1016 24 17.625 21.4766 17.625 18.375Z" fill="#FFBE40"/>
<path d="M11.8818 21.5776L10.7118 20.7976L11.7983 19.1678L10.3921 17.7615L12.1182 15.1724L13.2882 15.9524L12.2017 17.5823L13.6079 18.9886L11.8818 21.5776Z" fill="#465A61"/>
<path d="M12.1182 15.1724L12 15.3496V21.4004L13.6079 18.9886L12.2017 17.5823L13.2882 15.9524L12.1182 15.1724Z" fill="#3B4A51"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,26 @@
<svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.1346 0H3.09615C1.3862 0 0 1.3862 0 3.09615V19.9038C0 21.6138 1.3862 23 3.09615 23H18.1346C19.8446 23 21.2308 21.6138 21.2308 19.9038V3.09615C21.2308 1.3862 19.8446 0 18.1346 0Z" fill="#EF5350"/>
<path d="M20.6445 1.29056C17.6514 17.7494 4.15071 20.9781 0.482071 21.5556C0.760501 21.9974 1.14622 22.3615 1.6033 22.6141C2.06038 22.8666 2.57394 22.9994 3.09615 23H18.1346C18.9555 22.999 19.7424 22.6725 20.3228 22.0921C20.9033 21.5116 21.2298 20.7247 21.2308 19.9038V3.09615C21.2306 2.44752 21.0254 1.81554 20.6445 1.29056Z" fill="#E53935"/>
<path d="M18.1346 1.76923H3.09615C2.36331 1.76923 1.76923 2.36331 1.76923 3.09615V12.8269C1.76923 13.5598 2.36331 14.1538 3.09615 14.1538H18.1346C18.8675 14.1538 19.4615 13.5598 19.4615 12.8269V3.09615C19.4615 2.36331 18.8675 1.76923 18.1346 1.76923Z" fill="#BBDEFB"/>
<path d="M16.5513 12.3846C16.8258 11.4606 16.8808 10.4852 16.7119 9.53621C16.543 8.58718 16.1549 7.69068 15.5785 6.91809C15.0021 6.14549 14.2532 5.51814 13.3916 5.08598C12.53 4.65381 11.5793 4.42877 10.6154 4.42877C9.65145 4.42877 8.70082 4.65381 7.83918 5.08598C6.97755 5.51814 6.2287 6.14549 5.65227 6.91809C5.07583 7.69068 4.68773 8.58718 4.51885 9.53621C4.34997 10.4852 4.40498 11.4606 4.67951 12.3846L2.875 12.1635V2.875H18.3558V12.1635L16.5513 12.3846Z" fill="#90CAF9"/>
<path d="M10.6154 5.30769C10.5573 5.30772 10.4998 5.2963 10.4461 5.27408C10.3924 5.25187 10.3436 5.21929 10.3026 5.17821C10.2615 5.13713 10.2289 5.08836 10.2067 5.03468C10.1845 4.981 10.173 4.92347 10.1731 4.86538V3.09615C10.1731 2.97884 10.2197 2.86634 10.3026 2.78339C10.3856 2.70044 10.4981 2.65384 10.6154 2.65384C10.7327 2.65384 10.8452 2.70044 10.9281 2.78339C11.0111 2.86634 11.0577 2.97884 11.0577 3.09615V4.86538C11.0577 4.92347 11.0463 4.981 11.0241 5.03468C11.0019 5.08836 10.9693 5.13713 10.9282 5.17821C10.8871 5.21929 10.8384 5.25187 10.7847 5.27408C10.731 5.2963 10.6735 5.30772 10.6154 5.30769Z" fill="#37474F"/>
<path d="M6.54953 6.99182C6.49143 6.99189 6.4339 6.98047 6.38024 6.95823C6.32657 6.93599 6.27783 6.90336 6.23681 6.86223L4.99498 5.62039C4.91328 5.5372 4.86774 5.42511 4.86827 5.30851C4.8688 5.19191 4.91535 5.08024 4.9978 4.99779C5.08025 4.91534 5.19192 4.86879 5.30852 4.86826C5.42512 4.86773 5.53721 4.91327 5.62041 4.99497L6.86224 6.2368C6.92408 6.29866 6.96619 6.37746 6.98325 6.46325C7.0003 6.54904 6.99155 6.63796 6.95808 6.71877C6.92461 6.79958 6.86793 6.86865 6.79521 6.91725C6.72249 6.96585 6.63699 6.9918 6.54953 6.99182Z" fill="#37474F"/>
<path d="M14.6812 6.99184C14.5938 6.99182 14.5083 6.96587 14.4356 6.91727C14.3628 6.86867 14.3062 6.79959 14.2727 6.71878C14.2392 6.63797 14.2305 6.54906 14.2475 6.46327C14.2646 6.37748 14.3067 6.29868 14.3685 6.23682L15.6104 4.99499C15.6513 4.95331 15.7001 4.92015 15.7539 4.89743C15.8077 4.87471 15.8655 4.86288 15.9239 4.86261C15.9823 4.86235 16.0402 4.87366 16.0942 4.89589C16.1482 4.91812 16.1973 4.95084 16.2386 4.99214C16.2799 5.03345 16.3127 5.08253 16.3349 5.13655C16.3571 5.19057 16.3684 5.24846 16.3682 5.30687C16.3679 5.36529 16.3561 5.42307 16.3333 5.47689C16.3106 5.5307 16.2775 5.57948 16.2358 5.62041L14.994 6.86224C14.9529 6.90338 14.9042 6.93601 14.8505 6.95825C14.7969 6.98049 14.7393 6.99191 14.6812 6.99184Z" fill="#37474F"/>
<path d="M10.6154 11.0577C10.5573 11.0578 10.4998 11.0463 10.4461 11.0241C10.3924 11.0019 10.3437 10.9692 10.3027 10.9281L7.48771 8.11314C7.40477 8.0302 7.35818 7.91771 7.35818 7.80041C7.35818 7.68312 7.40477 7.57063 7.48771 7.48769C7.57065 7.40475 7.68314 7.35815 7.80044 7.35815C7.91773 7.35815 8.03022 7.40475 8.11316 7.48769L10.9281 10.3027C10.9899 10.3645 11.032 10.4433 11.0491 10.5291C11.0662 10.6149 11.0574 10.7038 11.0239 10.7846C10.9905 10.8654 10.9338 10.9345 10.8611 10.9831C10.7883 11.0317 10.7029 11.0577 10.6154 11.0577Z" fill="#37474F"/>
<path d="M3.98077 19.9039C5.20217 19.9039 6.19231 18.9137 6.19231 17.6923C6.19231 16.4709 5.20217 15.4808 3.98077 15.4808C2.75937 15.4808 1.76923 16.4709 1.76923 17.6923C1.76923 18.9137 2.75937 19.9039 3.98077 19.9039Z" fill="#CFD8DC"/>
<path d="M5.70351 16.3228C5.784 16.7463 5.75973 17.1831 5.63281 17.5952C5.5059 18.0072 5.28018 18.382 4.97531 18.6868C4.67045 18.9917 4.29568 19.2174 3.88364 19.3443C3.4716 19.4713 3.03478 19.4955 2.61122 19.415C2.99872 19.7293 3.4819 19.9017 3.98077 19.9038C4.56709 19.9032 5.12921 19.6699 5.5438 19.2553C5.9584 18.8407 6.19162 18.2786 6.19231 17.6923C6.19017 17.1934 6.01772 16.7103 5.70351 16.3228Z" fill="#B0BEC5"/>
<path d="M17.25 19.9039C18.4714 19.9039 19.4615 18.9137 19.4615 17.6923C19.4615 16.4709 18.4714 15.4808 17.25 15.4808C16.0286 15.4808 15.0385 16.4709 15.0385 17.6923C15.0385 18.9137 16.0286 19.9039 17.25 19.9039Z" fill="#CFD8DC"/>
<path d="M18.9727 16.3228C19.0532 16.7463 19.029 17.1831 18.902 17.5952C18.7751 18.0072 18.5494 18.382 18.2445 18.6868C17.9397 18.9917 17.5649 19.2174 17.1529 19.3443C16.7408 19.4713 16.304 19.4955 15.8805 19.415C16.2679 19.7293 16.7511 19.9017 17.25 19.9038C17.8363 19.9032 18.3984 19.6699 18.813 19.2553C19.2276 18.8407 19.4609 18.2786 19.4615 17.6923C19.4594 17.1934 19.2869 16.7103 18.9727 16.3228Z" fill="#B0BEC5"/>
<path d="M4.42308 17.6923C4.42273 17.8095 4.37602 17.9218 4.29314 18.0047C4.21027 18.0876 4.09797 18.1343 3.98077 18.1346H1.81346C1.7545 17.8427 1.7545 17.5419 1.81346 17.25H3.98077C4.09797 17.2504 4.21027 17.2971 4.29314 17.3799C4.37602 17.4628 4.42273 17.5751 4.42308 17.6923Z" fill="#546E7A"/>
<path d="M19.0988 16.4716L17.564 18.0064C17.4802 18.0886 17.3674 18.1346 17.25 18.1346C17.1326 18.1346 17.0198 18.0886 16.936 18.0064C16.8531 17.9228 16.8066 17.81 16.8066 17.6923C16.8066 17.5747 16.8531 17.4618 16.936 17.3783L18.4708 15.8435C18.718 16.0111 18.9312 16.2243 19.0988 16.4716Z" fill="#546E7A"/>
<path d="M15.4808 21.6731H5.75C5.63269 21.6731 5.52019 21.6265 5.43724 21.5435C5.35429 21.4606 5.30769 21.3481 5.30769 21.2308C5.30769 21.1135 5.35429 21.001 5.43724 20.918C5.52019 20.8351 5.63269 20.7885 5.75 20.7885H15.4808C15.5981 20.7885 15.7106 20.8351 15.7935 20.918C15.8765 21.001 15.9231 21.1135 15.9231 21.2308C15.9231 21.3481 15.8765 21.4606 15.7935 21.5435C15.7106 21.6265 15.5981 21.6731 15.4808 21.6731Z" fill="#37474F"/>
<path d="M14.1538 19.9038H7.07692C6.95962 19.9038 6.84711 19.8572 6.76417 19.7743C6.68122 19.6913 6.63462 19.5788 6.63462 19.4615C6.63462 19.3442 6.68122 19.2317 6.76417 19.1488C6.84711 19.0658 6.95962 19.0192 7.07692 19.0192H14.1538C14.2712 19.0192 14.3837 19.0658 14.4666 19.1488C14.5496 19.2317 14.5962 19.3442 14.5962 19.4615C14.5962 19.5788 14.5496 19.6913 14.4666 19.7743C14.3837 19.8572 14.2712 19.9038 14.1538 19.9038Z" fill="#37474F"/>
<path d="M14.1538 16.3654H7.07692C6.95962 16.3654 6.84711 16.3188 6.76417 16.2358C6.68122 16.1529 6.63462 16.0404 6.63462 15.9231C6.63462 15.8058 6.68122 15.6933 6.76417 15.6103C6.84711 15.5274 6.95962 15.4808 7.07692 15.4808H14.1538C14.2712 15.4808 14.3837 15.5274 14.4666 15.6103C14.5496 15.6933 14.5962 15.8058 14.5962 15.9231C14.5962 16.0404 14.5496 16.1529 14.4666 16.2358C14.3837 16.3188 14.2712 16.3654 14.1538 16.3654Z" fill="#37474F"/>
<path d="M18.1346 1.76923H3.09615C2.74435 1.76961 2.40706 1.90953 2.1583 2.1583C1.90954 2.40706 1.76961 2.74435 1.76923 3.09615V12.8269C1.76961 13.1787 1.90954 13.516 2.1583 13.7648C2.40706 14.0135 2.74435 14.1535 3.09615 14.1538H18.1346C18.4864 14.1535 18.8237 14.0135 19.0725 13.7648C19.3212 13.516 19.4612 13.1787 19.4615 12.8269V3.09615C19.4612 2.74435 19.3212 2.40706 19.0725 2.1583C18.8237 1.90953 18.4864 1.76961 18.1346 1.76923ZM17.25 11.0577H13.7115C13.6534 11.0577 13.5959 11.0463 13.5422 11.0241C13.4886 11.0019 13.4398 10.9693 13.3987 10.9282C13.3576 10.8871 13.325 10.8384 13.3028 10.7847C13.2806 10.731 13.2692 10.6735 13.2692 10.6154C13.2692 9.91154 12.9896 9.23652 12.4919 8.73883C11.9942 8.24113 11.3192 7.96153 10.6154 7.96153C9.91154 7.96153 9.23652 8.24113 8.73883 8.73883C8.24114 9.23652 7.96154 9.91154 7.96154 10.6154C7.96157 10.6735 7.95015 10.731 7.92794 10.7847C7.90572 10.8384 7.87314 10.8871 7.83206 10.9282C7.79098 10.9693 7.74221 11.0019 7.68853 11.0241C7.63486 11.0463 7.57732 11.0577 7.51923 11.0577H3.98077C3.92267 11.0577 3.86514 11.0463 3.81147 11.0241C3.75779 11.0019 3.70901 10.9693 3.66794 10.9282C3.62686 10.8871 3.59428 10.8384 3.57206 10.7847C3.54985 10.731 3.53843 10.6735 3.53846 10.6154C3.53846 8.73846 4.28406 6.93842 5.61124 5.61124C6.93842 4.28406 8.73847 3.53846 10.6154 3.53846C12.4923 3.53846 14.2923 4.28406 15.6195 5.61124C16.9467 6.93842 17.6923 8.73846 17.6923 10.6154C17.6923 10.6735 17.6809 10.731 17.6587 10.7847C17.6365 10.8384 17.6039 10.8871 17.5628 10.9282C17.5218 10.9693 17.473 11.0019 17.4193 11.0241C17.3656 11.0463 17.3081 11.0577 17.25 11.0577Z" fill="#FFEE58"/>
<path d="M18.1346 1.76923H18.1031C17.434 11.9799 5.19336 12.4807 1.76923 12.4194V12.8269C1.76961 13.1787 1.90954 13.516 2.1583 13.7648C2.40706 14.0135 2.74435 14.1535 3.09615 14.1538H18.1346C18.4864 14.1535 18.8237 14.0135 19.0725 13.7648C19.3212 13.516 19.4612 13.1787 19.4615 12.8269V3.09615C19.4612 2.74435 19.3212 2.40706 19.0725 2.1583C18.8237 1.90953 18.4864 1.76961 18.1346 1.76923Z" fill="#90CAF9"/>
<path d="M18.1346 1.76923H18.1031C18.0217 3.53365 17.4778 5.24565 16.5259 6.7335C17.2873 7.88491 17.693 9.23498 17.6923 10.6154C17.6923 10.6735 17.6809 10.731 17.6587 10.7847C17.6365 10.8384 17.6039 10.8871 17.5628 10.9282C17.5218 10.9693 17.473 11.0019 17.4193 11.0241C17.3656 11.0463 17.3081 11.0577 17.25 11.0577H13.7115C13.6534 11.0577 13.5959 11.0463 13.5422 11.0241C13.4886 11.0019 13.4398 10.9693 13.3987 10.9282C13.3576 10.8871 13.325 10.8384 13.3028 10.7847C13.2806 10.731 13.2692 10.6735 13.2692 10.6154C13.2687 10.3667 13.2331 10.1193 13.1635 9.88054C9.14978 12.2871 3.84298 12.4565 1.76923 12.4194V12.8269C1.76961 13.1787 1.90954 13.516 2.1583 13.7648C2.40706 14.0135 2.74435 14.1535 3.09615 14.1538H18.1346C18.4864 14.1535 18.8237 14.0135 19.0725 13.7648C19.3212 13.516 19.4612 13.1787 19.4615 12.8269V3.09615C19.4612 2.74435 19.3212 2.40706 19.0725 2.1583C18.8237 1.90953 18.4864 1.76961 18.1346 1.76923Z" fill="#FDD835"/>
<path d="M10.6154 12.3846C11.5925 12.3846 12.3846 11.5925 12.3846 10.6154C12.3846 9.63827 11.5925 8.84616 10.6154 8.84616C9.63826 8.84616 8.84615 9.63827 8.84615 10.6154C8.84615 11.5925 9.63826 12.3846 10.6154 12.3846Z" fill="#CFD8DC"/>
<path d="M11.9108 9.41928C11.9288 9.52222 11.9393 9.62632 11.9423 9.73076C11.9417 10.3171 11.7085 10.8793 11.2939 11.2939C10.8793 11.7085 10.3171 11.9417 9.73077 11.9423C9.62632 11.9393 9.52223 11.9288 9.41929 11.9108C9.75344 12.2224 10.1955 12.392 10.6523 12.3841C11.1091 12.3761 11.5449 12.191 11.868 11.868C12.191 11.5449 12.376 11.1091 12.384 10.6523C12.392 10.1955 12.2224 9.75343 11.9108 9.41928Z" fill="#B0BEC5"/>
<path d="M3.53846 4.86538C4.02702 4.86538 4.42308 4.37031 4.42308 3.75961C4.42308 3.14891 4.02702 2.65384 3.53846 2.65384C3.0499 2.65384 2.65385 3.14891 2.65385 3.75961C2.65385 4.37031 3.0499 4.86538 3.53846 4.86538Z" fill="white"/>
<path d="M3.09615 6.63462C3.34043 6.63462 3.53846 6.43659 3.53846 6.19231C3.53846 5.94803 3.34043 5.75 3.09615 5.75C2.85187 5.75 2.65385 5.94803 2.65385 6.19231C2.65385 6.43659 2.85187 6.63462 3.09615 6.63462Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,26 @@
<svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.1346 0H3.09615C1.3862 0 0 1.3862 0 3.09615V19.9038C0 21.6138 1.3862 23 3.09615 23H18.1346C19.8446 23 21.2308 21.6138 21.2308 19.9038V3.09615C21.2308 1.3862 19.8446 0 18.1346 0Z" fill="#EF5350"/>
<path d="M20.6445 1.29056C17.6514 17.7494 4.1507 20.9781 0.482056 21.5556C0.760485 21.9974 1.1462 22.3615 1.60328 22.6141C2.06036 22.8666 2.57393 22.9994 3.09614 23H18.1346C18.9554 22.999 19.7424 22.6725 20.3228 22.0921C20.9032 21.5116 21.2298 20.7247 21.2308 19.9038V3.09615C21.2306 2.44752 21.0254 1.81554 20.6445 1.29056Z" fill="#E53935"/>
<path d="M18.1347 1.76923H3.09621C2.36337 1.76923 1.76929 2.36331 1.76929 3.09615V12.8269C1.76929 13.5598 2.36337 14.1538 3.09621 14.1538H18.1347C18.8675 14.1538 19.4616 13.5598 19.4616 12.8269V3.09615C19.4616 2.36331 18.8675 1.76923 18.1347 1.76923Z" fill="#BBDEFB"/>
<path d="M16.5513 12.3846C16.8258 11.4606 16.8808 10.4852 16.7119 9.53621C16.543 8.58718 16.1549 7.69068 15.5785 6.91809C15.0021 6.14549 14.2532 5.51814 13.3916 5.08598C12.53 4.65381 11.5793 4.42877 10.6154 4.42877C9.65145 4.42877 8.70082 4.65381 7.83918 5.08598C6.97755 5.51814 6.2287 6.14549 5.65227 6.91809C5.07583 7.69068 4.68773 8.58718 4.51885 9.53621C4.34997 10.4852 4.40498 11.4606 4.67951 12.3846L2.875 12.1635V2.875H18.3558V12.1635L16.5513 12.3846Z" fill="#90CAF9"/>
<path d="M10.6154 5.30769C10.5573 5.30772 10.4998 5.2963 10.4461 5.27408C10.3924 5.25187 10.3436 5.21929 10.3026 5.17821C10.2615 5.13713 10.2289 5.08836 10.2067 5.03468C10.1845 4.981 10.1731 4.92347 10.1731 4.86538V3.09615C10.1731 2.97884 10.2197 2.86634 10.3026 2.78339C10.3856 2.70044 10.4981 2.65384 10.6154 2.65384C10.7327 2.65384 10.8452 2.70044 10.9282 2.78339C11.0111 2.86634 11.0577 2.97884 11.0577 3.09615V4.86538C11.0577 4.92347 11.0463 4.981 11.0241 5.03468C11.0019 5.08836 10.9693 5.13713 10.9282 5.17821C10.8872 5.21929 10.8384 5.25187 10.7847 5.27408C10.731 5.2963 10.6735 5.30772 10.6154 5.30769Z" fill="#37474F"/>
<path d="M6.54954 6.99182C6.49145 6.99189 6.43392 6.98047 6.38026 6.95823C6.32659 6.93599 6.27785 6.90336 6.23683 6.86223L4.995 5.62039C4.9133 5.5372 4.86776 5.42511 4.86829 5.30851C4.86882 5.19191 4.91537 5.08024 4.99782 4.99779C5.08027 4.91534 5.19194 4.86879 5.30854 4.86826C5.42514 4.86773 5.53723 4.91327 5.62043 4.99497L6.86226 6.2368C6.9241 6.29866 6.96621 6.37746 6.98327 6.46325C7.00032 6.54904 6.99156 6.63796 6.9581 6.71877C6.92463 6.79958 6.86795 6.86865 6.79523 6.91725C6.72251 6.96585 6.63701 6.9918 6.54954 6.99182Z" fill="#37474F"/>
<path d="M14.6812 6.99184C14.5938 6.99182 14.5083 6.96587 14.4355 6.91727C14.3628 6.86867 14.3061 6.79959 14.2727 6.71878C14.2392 6.63797 14.2304 6.54906 14.2475 6.46327C14.2646 6.37748 14.3067 6.29868 14.3685 6.23682L15.6103 4.99499C15.6513 4.95331 15.7001 4.92015 15.7539 4.89743C15.8077 4.87471 15.8655 4.86288 15.9239 4.86261C15.9823 4.86235 16.0402 4.87366 16.0942 4.89589C16.1482 4.91812 16.1973 4.95084 16.2386 4.99214C16.2799 5.03345 16.3126 5.08253 16.3349 5.13655C16.3571 5.19057 16.3684 5.24846 16.3681 5.30687C16.3679 5.36529 16.356 5.42307 16.3333 5.47689C16.3106 5.5307 16.2774 5.57948 16.2358 5.62041L14.9939 6.86224C14.9529 6.90338 14.9042 6.93601 14.8505 6.95825C14.7969 6.98049 14.7393 6.99191 14.6812 6.99184Z" fill="#37474F"/>
<path d="M10.6154 11.0577C10.5573 11.0578 10.4997 11.0463 10.4461 11.0241C10.3924 11.0019 10.3437 10.9692 10.3026 10.9281L7.48769 8.11314C7.40475 8.0302 7.35815 7.91771 7.35815 7.80041C7.35815 7.68312 7.40475 7.57063 7.48769 7.48769C7.57063 7.40475 7.68312 7.35815 7.80041 7.35815C7.91771 7.35815 8.0302 7.40475 8.11314 7.48769L10.9281 10.3027C10.9899 10.3645 11.032 10.4433 11.0491 10.5291C11.0661 10.6149 11.0574 10.7038 11.0239 10.7846C10.9904 10.8654 10.9338 10.9345 10.861 10.9831C10.7883 11.0317 10.7028 11.0577 10.6154 11.0577Z" fill="#37474F"/>
<path d="M3.98083 19.9039C5.20222 19.9039 6.19236 18.9137 6.19236 17.6923C6.19236 16.4709 5.20222 15.4808 3.98083 15.4808C2.75943 15.4808 1.76929 16.4709 1.76929 17.6923C1.76929 18.9137 2.75943 19.9039 3.98083 19.9039Z" fill="#CFD8DC"/>
<path d="M5.7035 16.3228C5.78399 16.7463 5.75972 17.1831 5.6328 17.5952C5.50588 18.0072 5.28016 18.382 4.9753 18.6868C4.67043 18.9917 4.29567 19.2174 3.88363 19.3443C3.47159 19.4713 3.03477 19.4955 2.61121 19.415C2.9987 19.7293 3.48188 19.9017 3.98075 19.9038C4.56708 19.9032 5.12919 19.6699 5.54379 19.2553C5.95838 18.8407 6.1916 18.2786 6.19229 17.6923C6.19015 17.1934 6.0177 16.7103 5.7035 16.3228Z" fill="#B0BEC5"/>
<path d="M17.25 19.9039C18.4714 19.9039 19.4615 18.9137 19.4615 17.6923C19.4615 16.4709 18.4714 15.4808 17.25 15.4808C16.0286 15.4808 15.0385 16.4709 15.0385 17.6923C15.0385 18.9137 16.0286 19.9039 17.25 19.9039Z" fill="#CFD8DC"/>
<path d="M18.9728 16.3228C19.0533 16.7463 19.029 17.1831 18.9021 17.5952C18.7752 18.0072 18.5495 18.382 18.2446 18.6868C17.9397 18.9917 17.565 19.2174 17.1529 19.3443C16.7409 19.4713 16.3041 19.4955 15.8805 19.415C16.268 19.7293 16.7512 19.9017 17.25 19.9038C17.8364 19.9032 18.3985 19.6699 18.8131 19.2553C19.2277 18.8407 19.4609 18.2786 19.4616 17.6923C19.4594 17.1934 19.287 16.7103 18.9728 16.3228Z" fill="#B0BEC5"/>
<path d="M4.42312 17.6923C4.42277 17.8095 4.37606 17.9218 4.29319 18.0047C4.21032 18.0876 4.09802 18.1343 3.98082 18.1346H1.81351C1.75455 17.8427 1.75455 17.5419 1.81351 17.25H3.98082C4.09802 17.2504 4.21032 17.2971 4.29319 17.3799C4.37606 17.4628 4.42277 17.5751 4.42312 17.6923Z" fill="#546E7A"/>
<path d="M19.0989 16.4716L17.5641 18.0064C17.4802 18.0886 17.3675 18.1346 17.25 18.1346C17.1326 18.1346 17.0199 18.0886 16.936 18.0064C16.8531 17.9228 16.8066 17.81 16.8066 17.6923C16.8066 17.5747 16.8531 17.4618 16.936 17.3783L18.4708 15.8435C18.7181 16.0111 18.9312 16.2243 19.0989 16.4716Z" fill="#546E7A"/>
<path d="M15.4808 21.6731H5.75005C5.63274 21.6731 5.52024 21.6265 5.43729 21.5435C5.35434 21.4606 5.30774 21.3481 5.30774 21.2308C5.30774 21.1135 5.35434 21.0009 5.43729 20.918C5.52024 20.8351 5.63274 20.7885 5.75005 20.7885H15.4808C15.5981 20.7885 15.7106 20.8351 15.7936 20.918C15.8765 21.0009 15.9231 21.1135 15.9231 21.2308C15.9231 21.3481 15.8765 21.4606 15.7936 21.5435C15.7106 21.6265 15.5981 21.6731 15.4808 21.6731Z" fill="#37474F"/>
<path d="M14.1539 19.9038H7.07695C6.95964 19.9038 6.84714 19.8572 6.76419 19.7743C6.68124 19.6913 6.63464 19.5788 6.63464 19.4615C6.63464 19.3442 6.68124 19.2317 6.76419 19.1488C6.84714 19.0658 6.95964 19.0192 7.07695 19.0192H14.1539C14.2712 19.0192 14.3837 19.0658 14.4666 19.1488C14.5496 19.2317 14.5962 19.3442 14.5962 19.4615C14.5962 19.5788 14.5496 19.6913 14.4666 19.7743C14.3837 19.8572 14.2712 19.9038 14.1539 19.9038Z" fill="#37474F"/>
<path d="M14.1539 16.3654H7.07695C6.95964 16.3654 6.84714 16.3188 6.76419 16.2358C6.68124 16.1529 6.63464 16.0404 6.63464 15.9231C6.63464 15.8058 6.68124 15.6933 6.76419 15.6103C6.84714 15.5274 6.95964 15.4808 7.07695 15.4808H14.1539C14.2712 15.4808 14.3837 15.5274 14.4666 15.6103C14.5496 15.6933 14.5962 15.8058 14.5962 15.9231C14.5962 16.0404 14.5496 16.1529 14.4666 16.2358C14.3837 16.3188 14.2712 16.3654 14.1539 16.3654Z" fill="#37474F"/>
<path d="M18.1347 1.76923H3.09621C2.74441 1.76961 2.40712 1.90953 2.15836 2.1583C1.90959 2.40706 1.76967 2.74435 1.76929 3.09615V12.8269C1.76967 13.1787 1.90959 13.516 2.15836 13.7648C2.40712 14.0135 2.74441 14.1535 3.09621 14.1538H18.1347C18.4865 14.1535 18.8238 14.0135 19.0725 13.7648C19.3213 13.516 19.4612 13.1787 19.4616 12.8269V3.09615C19.4612 2.74435 19.3213 2.40706 19.0725 2.1583C18.8238 1.90953 18.4865 1.76961 18.1347 1.76923ZM17.2501 11.0577H13.7116C13.6535 11.0577 13.596 11.0463 13.5423 11.0241C13.4886 11.0019 13.4398 10.9693 13.3988 10.9282C13.3577 10.8871 13.3251 10.8384 13.3029 10.7847C13.2807 10.731 13.2693 10.6735 13.2693 10.6154C13.2693 9.91154 12.9897 9.23652 12.492 8.73883C11.9943 8.24113 11.3193 7.96153 10.6154 7.96153C9.9116 7.96153 9.23658 8.24113 8.73889 8.73883C8.2412 9.23652 7.9616 9.91154 7.9616 10.6154C7.96163 10.6735 7.95021 10.731 7.92799 10.7847C7.90578 10.8384 7.8732 10.8871 7.83212 10.9282C7.79104 10.9693 7.74227 11.0019 7.68859 11.0241C7.63491 11.0463 7.57738 11.0577 7.51929 11.0577H3.98083C3.92273 11.0577 3.8652 11.0463 3.81152 11.0241C3.75784 11.0019 3.70907 10.9693 3.66799 10.9282C3.62691 10.8871 3.59434 10.8384 3.57212 10.7847C3.5499 10.731 3.53848 10.6735 3.53852 10.6154C3.53852 8.73846 4.28412 6.93842 5.6113 5.61124C6.93848 4.28406 8.73852 3.53846 10.6154 3.53846C12.4924 3.53846 14.2924 4.28406 15.6196 5.61124C16.9468 6.93842 17.6924 8.73846 17.6924 10.6154C17.6924 10.6735 17.681 10.731 17.6588 10.7847C17.6365 10.8384 17.604 10.8871 17.5629 10.9282C17.5218 10.9693 17.473 11.0019 17.4194 11.0241C17.3657 11.0463 17.3082 11.0577 17.2501 11.0577Z" fill="#FFEE58"/>
<path d="M18.1347 1.76923H18.1031C17.4341 11.9799 5.19342 12.4807 1.76929 12.4194V12.8269C1.76967 13.1787 1.90959 13.516 2.15836 13.7648C2.40712 14.0135 2.74441 14.1535 3.09621 14.1538H18.1347C18.4865 14.1535 18.8238 14.0135 19.0725 13.7648C19.3213 13.516 19.4612 13.1787 19.4616 12.8269V3.09615C19.4612 2.74435 19.3213 2.40706 19.0725 2.1583C18.8238 1.90953 18.4865 1.76961 18.1347 1.76923Z" fill="#90CAF9"/>
<path d="M18.1347 1.76923H18.1031C18.0218 3.53365 17.4778 5.24565 16.5259 6.7335C17.2874 7.88491 17.693 9.23498 17.6924 10.6154C17.6924 10.6735 17.681 10.731 17.6588 10.7847C17.6365 10.8384 17.604 10.8871 17.5629 10.9282C17.5218 10.9693 17.473 11.0019 17.4194 11.0241C17.3657 11.0463 17.3082 11.0577 17.2501 11.0577H13.7116C13.6535 11.0577 13.596 11.0463 13.5423 11.0241C13.4886 11.0019 13.4398 10.9693 13.3988 10.9282C13.3577 10.8871 13.3251 10.8384 13.3029 10.7847C13.2807 10.731 13.2693 10.6735 13.2693 10.6154C13.2688 10.3667 13.2332 10.1193 13.1635 9.88054C9.14984 12.2871 3.84304 12.4565 1.76929 12.4194V12.8269C1.76967 13.1787 1.90959 13.516 2.15836 13.7648C2.40712 14.0135 2.74441 14.1535 3.09621 14.1538H18.1347C18.4865 14.1535 18.8238 14.0135 19.0725 13.7648C19.3213 13.516 19.4612 13.1787 19.4616 12.8269V3.09615C19.4612 2.74435 19.3213 2.40706 19.0725 2.1583C18.8238 1.90953 18.4865 1.76961 18.1347 1.76923Z" fill="#FDD835"/>
<path d="M10.6154 12.3846C11.5925 12.3846 12.3847 11.5925 12.3847 10.6154C12.3847 9.63827 11.5925 8.84616 10.6154 8.84616C9.6383 8.84616 8.84619 9.63827 8.84619 10.6154C8.84619 11.5925 9.6383 12.3846 10.6154 12.3846Z" fill="#CFD8DC"/>
<path d="M11.9109 9.41928C11.9288 9.52222 11.9393 9.62632 11.9423 9.73076C11.9418 10.3171 11.7086 10.8793 11.2939 11.2939C10.8793 11.7085 10.3172 11.9417 9.73079 11.9423C9.62635 11.9393 9.52225 11.9288 9.41931 11.9108C9.75346 12.2224 10.1955 12.392 10.6523 12.3841C11.1091 12.3761 11.545 12.191 11.868 11.868C12.1911 11.5449 12.3761 11.1091 12.3841 10.6523C12.3921 10.1955 12.2224 9.75343 11.9109 9.41928Z" fill="#B0BEC5"/>
<path d="M3.53842 4.86538C4.02698 4.86538 4.42304 4.37031 4.42304 3.75961C4.42304 3.14891 4.02698 2.65384 3.53842 2.65384C3.04986 2.65384 2.65381 3.14891 2.65381 3.75961C2.65381 4.37031 3.04986 4.86538 3.53842 4.86538Z" fill="white"/>
<path d="M3.09612 6.63462C3.3404 6.63462 3.53842 6.43659 3.53842 6.19231C3.53842 5.94803 3.3404 5.75 3.09612 5.75C2.85184 5.75 2.65381 5.94803 2.65381 6.19231C2.65381 6.43659 2.85184 6.63462 3.09612 6.63462Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,41 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.998 2.5882C11.8004 2.5882 11.6403 2.42817 11.6403 2.23069V0.357516C11.6403 0.160078 11.8004 0 11.998 0C12.1956 0 12.3558 0.160031 12.3558 0.357516V2.23073C12.3558 2.42817 12.1956 2.5882 11.998 2.5882Z" fill="#E6E2E6"/>
<path d="M5.22457 2.5882C5.02699 2.5882 4.86682 2.42817 4.86682 2.23069V0.357516C4.86682 0.160078 5.02699 0 5.22457 0C5.42215 0 5.58232 0.160031 5.58232 0.357516V2.23073C5.58232 2.42817 5.42215 2.5882 5.22457 2.5882Z" fill="#E6E2E6"/>
<path d="M18.7714 2.5882C18.5738 2.5882 18.4137 2.42817 18.4137 2.23069V0.357516C18.4137 0.160078 18.5739 0 18.7714 0C18.969 0 19.1292 0.160031 19.1292 0.357516V2.23073C19.1292 2.42817 18.969 2.5882 18.7714 2.5882Z" fill="#E6E2E6"/>
<path d="M17.6937 1.7467H19.8492C20.0782 1.7467 20.2814 1.8937 20.3528 2.1112L20.7326 3.26672C20.7832 3.42084 20.6683 3.57942 20.506 3.57942H17.0369C16.8746 3.57942 16.7596 3.42084 16.8103 3.26672L17.19 2.1112C17.2615 1.8937 17.4647 1.7467 17.6937 1.7467Z" fill="#545454"/>
<path d="M17.6935 3.57938H19.8492C20.0782 3.57938 20.2814 3.72638 20.3528 3.94383L20.7326 5.0993C20.7832 5.25342 20.6683 5.412 20.506 5.412H17.0369C16.8746 5.412 16.7596 5.25342 16.8103 5.0993L17.1901 3.94359C17.2615 3.72628 17.4646 3.57938 17.6935 3.57938Z" fill="#545454"/>
<path d="M17.6935 5.41205H19.8492C20.0782 5.41205 20.2814 5.55905 20.3528 5.77655L20.7326 6.93206C20.7832 7.08619 20.6683 7.24477 20.506 7.24477H17.0369C16.8746 7.24477 16.7596 7.08619 16.8103 6.93206L17.1901 5.77636C17.2615 5.55895 17.4646 5.41205 17.6935 5.41205Z" fill="#545454"/>
<path d="M13.0759 1.7467H10.9203C10.6912 1.7467 10.488 1.8937 10.4166 2.1112L10.0369 3.26672C9.9862 3.42084 10.1011 3.57942 10.2635 3.57942H13.7325C13.8949 3.57942 14.0098 3.42084 13.9591 3.26672L13.5793 2.11102C13.5079 1.89361 13.3049 1.7467 13.0759 1.7467Z" fill="#545454"/>
<path d="M13.0757 3.57938H10.9203C10.6912 3.57938 10.4881 3.72638 10.4166 3.94383L10.0369 5.0993C9.9862 5.25342 10.1011 5.412 10.2635 5.412H13.7325C13.8949 5.412 14.0098 5.25342 13.9591 5.0993L13.5794 3.94378C13.508 3.72638 13.3048 3.57938 13.0757 3.57938Z" fill="#545454"/>
<path d="M13.0759 5.41205H10.9203C10.6912 5.41205 10.4881 5.55905 10.4166 5.77655L10.0369 6.93206C9.9862 7.08619 10.1011 7.24477 10.2635 7.24477H13.7325C13.8949 7.24477 14.0098 7.08619 13.9591 6.93206L13.5793 5.77636C13.5079 5.55895 13.3049 5.41205 13.0759 5.41205Z" fill="#545454"/>
<path d="M6.30253 1.7467H4.14689C3.91781 1.7467 3.71465 1.8937 3.64321 2.1112L3.26343 3.26667C3.21276 3.4208 3.3277 3.57938 3.49003 3.57938H6.9591C7.12143 3.57938 7.23637 3.4208 7.1857 3.26667L6.80592 2.11097C6.73448 1.89361 6.53146 1.7467 6.30253 1.7467Z" fill="#545454"/>
<path d="M3.44264 2.72137L3.26343 3.26667C3.21276 3.4208 3.3277 3.57937 3.49003 3.57937H6.9591C7.12143 3.57937 7.23637 3.4208 7.1857 3.26667L7.0065 2.72137H3.44264Z" fill="#494949"/>
<path d="M6.30248 3.57938H4.14684C3.91776 3.57938 3.71461 3.72638 3.64317 3.94383L3.26343 5.0993C3.21276 5.25342 3.3277 5.412 3.49003 5.412H6.95911C7.12143 5.412 7.23637 5.25342 7.1857 5.0993L6.80592 3.94359C6.73443 3.72628 6.53142 3.57938 6.30248 3.57938Z" fill="#545454"/>
<path d="M3.44264 4.55405L3.26343 5.09934C3.21276 5.25347 3.3277 5.41205 3.49003 5.41205H6.9591C7.12143 5.41205 7.23637 5.25347 7.1857 5.09934L7.0065 4.55405H3.44264Z" fill="#494949"/>
<path d="M6.30225 5.41205H4.14684C3.91776 5.41205 3.71461 5.55905 3.64317 5.77655L3.26343 6.93206C3.21276 7.08619 3.3277 7.24477 3.49003 7.24477H6.95911C7.12143 7.24477 7.23637 7.08619 7.1857 6.93206L6.80596 5.77655C6.73448 5.55905 6.53132 5.41205 6.30225 5.41205Z" fill="#545454"/>
<path d="M3.44264 6.38666L3.26343 6.93196C3.21276 7.08608 3.3277 7.24466 3.49003 7.24466H6.9591C7.12143 7.24466 7.23637 7.08608 7.1857 6.93196L7.0065 6.38666H3.44264Z" fill="#494949"/>
<path d="M10.2161 2.72137L10.0369 3.26667C9.9862 3.4208 10.1011 3.57937 10.2635 3.57937H13.7325C13.8949 3.57937 14.0098 3.4208 13.9591 3.26667L13.7799 2.72137H10.2161Z" fill="#494949"/>
<path d="M10.2161 4.55405L10.0369 5.09934C9.9862 5.25347 10.1011 5.41205 10.2635 5.41205H13.7325C13.8949 5.41205 14.0098 5.25347 13.9591 5.09934L13.7799 4.55405H10.2161Z" fill="#494949"/>
<path d="M10.2161 6.38666L10.0369 6.93196C9.9862 7.08608 10.1011 7.24466 10.2635 7.24466H13.7325C13.8949 7.24466 14.0098 7.08608 13.9591 6.93196L13.7799 6.38666H10.2161Z" fill="#494949"/>
<path d="M16.9895 2.72137L16.8103 3.26667C16.7596 3.4208 16.8746 3.57937 17.0369 3.57937H20.506C20.6683 3.57937 20.7832 3.4208 20.7326 3.26667L20.5534 2.72137H16.9895Z" fill="#494949"/>
<path d="M16.9895 4.55405L16.8103 5.09934C16.7596 5.25347 16.8746 5.41205 17.0369 5.41205H20.506C20.6683 5.41205 20.7832 5.25347 20.7326 5.09934L20.5534 4.55405H16.9895Z" fill="#494949"/>
<path d="M16.9895 6.38666L16.8103 6.93196C16.7596 7.08608 16.8746 7.24466 17.0369 7.24466H20.506C20.6683 7.24466 20.7832 7.08608 20.7326 6.93196L20.5534 6.38666H16.9895Z" fill="#494949"/>
<path d="M11.0522 7.24466H12.9437V8.88885H11.0522V7.24466Z" fill="#545454"/>
<path d="M4.27881 7.24466H6.17031V8.88885H4.27881V7.24466Z" fill="#545454"/>
<path d="M19.7172 8.88892H17.8257V7.24473H19.7172V8.88892Z" fill="#545454"/>
<path d="M1.21143 10.9806H22.7886V21.9083H1.21143V10.9806Z" fill="#545454"/>
<path d="M1.21143 10.9806H22.7886V11.8386H1.21143V10.9806Z" fill="#494949"/>
<path d="M11.998 12.3605C11.8004 12.3605 11.6403 12.2004 11.6403 12.003V10.7935C11.6403 10.596 11.8004 10.436 11.998 10.436C12.1956 10.436 12.3558 10.596 12.3558 10.7935V12.003C12.3558 12.2004 12.1956 12.3605 11.998 12.3605Z" fill="#E6E2E6"/>
<path d="M5.22457 12.3605C5.02699 12.3605 4.86682 12.2004 4.86682 12.003V10.7935C4.86682 10.596 5.02699 10.436 5.22457 10.436C5.42215 10.436 5.58232 10.596 5.58232 10.7935V12.003C5.58232 12.2004 5.42215 12.3605 5.22457 12.3605Z" fill="#E6E2E6"/>
<path d="M18.7714 12.3605C18.5738 12.3605 18.4137 12.2004 18.4137 12.003V10.7935C18.4137 10.596 18.5739 10.436 18.7714 10.436C18.969 10.436 19.1292 10.596 19.1292 10.7935V12.003C19.1292 12.2004 18.969 12.3605 18.7714 12.3605Z" fill="#E6E2E6"/>
<path d="M23.5233 10.9806H0.476672C0.213422 10.9806 0 10.7672 0 10.5039V9.36559C0 9.10234 0.213422 8.88892 0.476672 8.88892H23.5233C23.7865 8.88892 24 9.10234 24 9.36559V10.5039C24 10.7672 23.7866 10.9806 23.5233 10.9806Z" fill="#A8A7A8"/>
<path d="M23.5231 10.1226H0.476859C0.213516 10.1226 0 9.90929 0 9.64609V10.5041C0 10.7673 0.213516 10.9806 0.476859 10.9806H23.5231C23.7865 10.9806 24 10.7673 24 10.5041V9.64609C24 9.90929 23.7865 10.1226 23.5231 10.1226Z" fill="#818181"/>
<path d="M23.5233 24H0.476672C0.213422 24 0 23.7866 0 23.5234V22.385C0 22.1217 0.213422 21.9083 0.476672 21.9083H23.5233C23.7865 21.9083 24 22.1217 24 22.385V23.5234C24 23.7866 23.7866 24 23.5233 24Z" fill="#A8A7A8"/>
<path d="M23.5231 23.142H0.476859C0.213516 23.142 0 22.9287 0 22.6655V23.5235C0 23.7867 0.213516 24 0.476859 24H23.5231C23.7865 24 24 23.7867 24 23.5235V22.6655C24 22.9287 23.7865 23.142 23.5231 23.142Z" fill="#818181"/>
<path d="M15.6454 19.172L12.6056 14.0633C12.3317 13.6029 11.6644 13.6029 11.3904 14.0633L8.35062 19.172C8.07068 19.6425 8.4102 20.2384 8.95816 20.2384H15.0378C15.5858 20.2384 15.9253 19.6425 15.6454 19.172Z" fill="#F6E266"/>
<path d="M15.6023 19.0995C15.4767 19.2667 15.2772 19.3804 15.0379 19.3804H8.95829C8.71894 19.3804 8.51944 19.2667 8.39387 19.0995L8.35074 19.172C8.0708 19.6425 8.41032 20.2384 8.95829 20.2384H15.0379C15.5859 20.2384 15.9254 19.6425 15.6454 19.172L15.6023 19.0995Z" fill="#FFC239"/>
<path d="M11.0522 8.06677H12.9437V8.88887H11.0522V8.06677Z" fill="#494949"/>
<path d="M4.27881 8.06677H6.17031V8.88887H4.27881V8.06677Z" fill="#494949"/>
<path d="M17.8257 8.06677H19.7172V8.88887H17.8257V8.06677Z" fill="#494949"/>
<path d="M11.9225 15.9461L10.9958 17.4033C10.9256 17.5136 10.9211 17.6534 10.9841 17.7679C11.0471 17.8825 11.1675 17.9536 11.2983 17.9536H11.7902L11.2135 18.8605C11.1073 19.0275 11.1567 19.2488 11.3237 19.355C11.4658 19.449 11.7038 19.4221 11.8185 19.2448L12.7453 17.7876C12.8154 17.6773 12.8198 17.5376 12.7569 17.423C12.6939 17.3085 12.5735 17.2373 12.4427 17.2373H11.9508L12.5276 16.3304C12.6338 16.1634 12.5844 15.942 12.4173 15.8359C12.2503 15.7298 12.0287 15.7792 11.9225 15.9461Z" fill="#DD636E"/>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1,22 @@
<svg width="25" height="36" viewBox="0 0 25 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.67036 31.6755C9.37913 31.6755 9.14303 31.9116 9.14303 32.2029V33.5343C9.14303 34.3122 8.5101 34.9452 7.73219 34.9452H6.41014C6.11891 34.9452 5.88281 35.1813 5.88281 35.4725C5.88281 35.7637 6.11891 35.9998 6.41014 35.9998H7.73219C9.09163 35.9998 10.1977 34.8938 10.1977 33.5343V32.2029C10.1977 31.9116 9.96158 31.6755 9.67036 31.6755Z" fill="#72BBFF"/>
<path d="M10.6115 29.458H8.7285C8.43727 29.458 8.20117 29.6941 8.20117 29.9853V31.2785C8.20117 32.0885 8.86012 32.7473 9.67002 32.7473C10.4799 32.7473 11.1389 32.0884 11.1389 31.2785V29.9853C11.1389 29.6941 10.9028 29.458 10.6115 29.458Z" fill="#6B717D"/>
<path d="M14.4785 31.6755C14.7697 31.6755 15.0058 31.9116 15.0058 32.2029V33.5343C15.0058 34.3122 15.6388 34.9452 16.4167 34.9452H17.7387C18.0299 34.9452 18.266 35.1813 18.266 35.4725C18.266 35.7637 18.0299 35.9998 17.7387 35.9998H16.4167C15.0572 35.9998 13.9512 34.8938 13.9512 33.5343V32.2029C13.9512 31.9116 14.1873 31.6755 14.4785 31.6755Z" fill="#FF6C6C"/>
<path d="M13.5371 29.4583H15.4201C15.7114 29.4583 15.9475 29.6944 15.9475 29.9856V31.2787C15.9475 32.0887 15.2885 32.7476 14.4786 32.7476C13.6687 32.7476 13.0098 32.0886 13.0098 31.2787V29.9856C13.0098 29.6944 13.2459 29.4583 13.5371 29.4583Z" fill="#6B717D"/>
<path d="M2.14594 3.29248H0.527327C0.236102 3.29248 0 3.52858 0 3.81981C0 4.11103 0.236102 4.34714 0.527327 4.34714H2.14594C2.43717 4.34714 2.67327 4.11103 2.67327 3.81981C2.67327 3.52858 2.43717 3.29248 2.14594 3.29248Z" fill="#6B717D"/>
<path d="M2.14594 5.75342H0.527327C0.236102 5.75342 0 5.98952 0 6.28075C0 6.57197 0.236102 6.80807 0.527327 6.80807H2.14594C2.43717 6.80807 2.67327 6.57197 2.67327 6.28075C2.67327 5.98952 2.43717 5.75342 2.14594 5.75342Z" fill="#6B717D"/>
<path d="M23.6186 17.7485H22C21.7088 17.7485 21.4727 17.9846 21.4727 18.2759C21.4727 18.5671 21.7088 18.8032 22 18.8032H23.6186C23.9098 18.8032 24.1459 18.5671 24.1459 18.2759C24.1459 17.9846 23.9098 17.7485 23.6186 17.7485Z" fill="#6B717D"/>
<path d="M19.5902 27.5019V29.9663C19.5902 30.2574 19.354 30.4936 19.0629 30.4936H5.08592C4.79484 30.4936 4.55859 30.2574 4.55859 29.9663V27.5019C4.55859 27.2109 4.79484 26.9746 5.08592 26.9746H19.0629C19.354 26.9746 19.5902 27.2109 19.5902 27.5019Z" fill="#D6EAEC"/>
<path d="M19.5898 27.5019V29.9663C19.5898 30.2574 19.3535 30.4936 19.0624 30.4936H16.9531C17.2442 30.4936 17.4805 30.2574 17.4805 29.9663V27.5019C17.4805 27.2109 17.2442 26.9746 16.9531 26.9746H19.0624C19.3535 26.9746 19.5898 27.2109 19.5898 27.5019Z" fill="#B5D9DD"/>
<path d="M22.5287 1.66214V22.3242L20.4194 22.8994L12.0736 25.1767L1.61914 22.3242V1.66214C1.61914 0.745289 2.36443 0 3.28128 0H20.8666C21.7827 0 22.5287 0.745289 22.5287 1.66214Z" fill="#D6EAEC"/>
<path d="M22.5273 1.66214V22.3242L20.418 22.8994V1.66214C20.418 0.745289 19.672 0 18.7559 0H20.8652C21.7813 0 22.5273 0.745289 22.5273 1.66214Z" fill="#B5D9DD"/>
<path d="M22.5287 22.3242V26.3671C22.5287 27.2839 21.7827 28.0292 20.8666 28.0292H3.28128C2.36443 28.0292 1.61914 27.2839 1.61914 26.3671V22.3242H22.5287Z" fill="#6B717D"/>
<path d="M22.5273 22.3242V26.3671C22.5273 27.2839 21.7813 28.0292 20.8652 28.0292H18.7559C19.672 28.0292 20.418 27.2839 20.418 26.3671V22.3242H22.5273Z" fill="#47505E"/>
<path d="M12.43 13.9283C12.2285 13.744 11.9196 13.744 11.7181 13.9283C11.6376 14.0019 9.74805 15.7519 9.74805 17.6083C9.74805 18.8909 10.7915 19.9344 12.0741 19.9344C13.3567 19.9344 14.4001 18.8909 14.4001 17.6083C14.4 15.7519 12.5104 14.0019 12.43 13.9283Z" fill="#72BBFF"/>
<path d="M16.1576 8.85955C17.0908 6.60807 16.0222 4.02635 13.7707 3.0931C11.5192 2.15986 8.93748 3.2285 8.00424 5.47998C7.071 7.73146 8.13964 10.3132 10.3911 11.2464C12.6426 12.1797 15.2243 11.111 16.1576 8.85955Z" fill="#B5D9DD"/>
<path d="M14.7283 7.16982C14.7283 9.02109 13.9254 10.5271 12.0741 10.5271C11.7957 10.5271 11.525 10.4927 11.2655 10.428C9.80379 10.0659 8.7168 8.74266 8.7168 7.16982C8.7168 5.59698 9.80379 4.27374 11.2655 3.91164C11.525 3.84695 11.7957 3.8125 12.0741 3.8125C13.9254 3.8125 14.7283 5.31855 14.7283 7.16982Z" fill="white"/>
<path d="M15.4315 7.16982C15.4315 9.02109 13.9255 10.5271 12.0742 10.5271C11.7958 10.5271 11.5251 10.4927 11.2656 10.428C12.7274 10.0659 13.8144 8.74266 13.8144 7.16982C13.8144 5.59698 12.7274 4.27374 11.2656 3.91164C11.5251 3.84695 11.7958 3.8125 12.0742 3.8125C13.9255 3.8125 15.4315 5.31855 15.4315 7.16982Z" fill="#D6EAEC"/>
<path d="M12.4478 6.79706C12.2418 6.59105 11.908 6.59112 11.7021 6.79706L10.5783 7.92094C10.3723 8.12688 10.3723 8.4608 10.5783 8.66667C10.6812 8.76961 10.8162 8.82115 10.9512 8.82115C11.0861 8.82115 11.2211 8.76968 11.324 8.66667L12.4478 7.5428C12.6538 7.33685 12.6538 7.00294 12.4478 6.79706Z" fill="#FF6C6C"/>
<path d="M5.55469 25.7041C5.84593 25.7041 6.08203 25.468 6.08203 25.1768C6.08203 24.8855 5.84593 24.6494 5.55469 24.6494C5.26344 24.6494 5.02734 24.8855 5.02734 25.1768C5.02734 25.468 5.26344 25.7041 5.55469 25.7041Z" fill="#47505E"/>
<path d="M18.5918 25.7041C18.883 25.7041 19.1191 25.468 19.1191 25.1768C19.1191 24.8855 18.883 24.6494 18.5918 24.6494C18.3006 24.6494 18.0645 24.8855 18.0645 25.1768C18.0645 25.468 18.3006 25.7041 18.5918 25.7041Z" fill="#47505E"/>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,11 @@
<svg width="33" height="38" viewBox="0 0 33 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M29.788 23.1188C29.788 31.3375 23.1198 38 14.894 38C6.66832 38 0 31.3375 0 23.1188C0 15.8539 11.6379 3.1015 14.3389 0.239633C14.6404 -0.0798778 15.1477 -0.0798778 15.4492 0.239633C18.1502 3.10158 29.788 15.8539 29.788 23.1188Z" fill="#B3DAFE"/>
<path d="M15.4491 0.239633C15.1476 -0.0798778 14.6403 -0.0798778 14.3388 0.239633C14.1736 0.414715 13.9745 0.627277 13.7471 0.872793C17.2371 4.64154 27.4942 16.2982 27.4942 23.1187C27.4942 30.9518 21.4369 37.3714 13.7471 37.9564C14.1256 37.9852 14.508 37.9999 14.894 37.9999C23.1197 37.9999 29.788 31.3374 29.788 23.1187C29.788 15.8539 18.1502 3.10158 15.4491 0.239633Z" fill="#8AC9FE"/>
<path d="M29.7489 24.1975C25.598 22.4389 21.0994 22.7823 9.48614 25.2106C6.87119 25.7574 3.87944 26.4133 0.56543 27.1942C2.33903 33.4317 8.08252 38.0002 14.8941 38.0002C22.7568 38.0002 29.1958 31.9126 29.7489 24.1975Z" fill="#60B7FF"/>
<path d="M32.164 10.3818C32.164 12.4699 31.3533 14.4352 29.8815 15.9156C28.4104 17.3949 26.4523 18.2168 24.3669 18.23C24.3617 18.23 24.3561 18.2304 24.3509 18.23C24.3393 18.2304 24.3274 18.2304 24.3154 18.2304C22.2192 18.2304 20.2482 17.4142 18.7658 15.9316C17.2832 14.4493 16.4668 12.4782 16.4668 10.3818C16.4668 8.28539 17.2832 6.31462 18.7658 4.83199C20.2482 3.34961 22.2192 2.5332 24.3154 2.5332C24.3274 2.5332 24.339 2.5332 24.3509 2.53356C24.3565 2.53356 24.362 2.53356 24.3675 2.5338C26.4526 2.54733 28.4107 3.36901 29.8815 4.84828C31.3533 6.32875 32.164 8.29389 32.164 10.3818Z" fill="#FF4756"/>
<path d="M32.1636 10.3814C32.1636 12.4696 31.3529 14.4348 29.8811 15.9153C28.4101 17.3946 26.4519 18.2165 24.3665 18.2296C24.3614 18.2296 24.3557 18.23 24.3506 18.2296V2.5332C24.3561 2.5332 24.3616 2.5332 24.3671 2.53344C26.4523 2.54698 28.4103 3.36865 29.8811 4.84792C31.3529 6.32839 32.1636 8.29353 32.1636 10.3814Z" fill="#FF656F"/>
<path d="M25.6615 7.14579V10.6543C25.6615 11.3755 25.0749 11.9622 24.3538 11.9622H24.3504C24.0136 11.9524 23.6658 11.8163 23.4289 11.5793C23.1821 11.3322 23.0459 11.0039 23.0459 10.6543V7.14579C23.0459 6.43262 23.638 5.85837 24.3504 5.83789H24.3538C25.0749 5.83789 25.6615 6.42471 25.6615 7.14579Z" fill="white"/>
<path d="M25.5919 13.6205C25.5919 14.3033 25.0367 14.8585 24.3539 14.8585H24.3508C23.6699 14.8569 23.1162 14.3023 23.1162 13.6205C23.1162 12.939 23.6699 12.3844 24.3508 12.3828H24.3539C25.0367 12.3828 25.5919 12.938 25.5919 13.6205Z" fill="white"/>
<path d="M25.5926 13.6215C25.5926 14.3043 25.0374 14.8595 24.3547 14.8595H24.3516V12.3838H24.3547C25.0374 12.3838 25.5926 12.939 25.5926 13.6215Z" fill="#DDEBF0"/>
<path d="M25.6626 7.14676V10.6552C25.6626 11.3764 25.076 11.9631 24.3549 11.9631H24.3516V5.83887H24.3549C25.076 5.83887 25.6626 6.42569 25.6626 7.14676Z" fill="#DDEBF0"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,11 @@
<svg width="33" height="38" viewBox="0 0 33 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M29.788 23.1188C29.788 31.3375 23.1198 38 14.894 38C6.66832 38 0 31.3375 0 23.1188C0 15.8539 11.6379 3.1015 14.3389 0.239633C14.6404 -0.0798778 15.1477 -0.0798778 15.4492 0.239633C18.1502 3.10158 29.788 15.8539 29.788 23.1188Z" fill="#B3DAFE"/>
<path d="M15.4491 0.239633C15.1476 -0.0798778 14.6403 -0.0798778 14.3388 0.239633C14.1736 0.414715 13.9745 0.627277 13.7471 0.872793C17.2371 4.64154 27.4942 16.2982 27.4942 23.1187C27.4942 30.9518 21.4369 37.3714 13.7471 37.9564C14.1256 37.9852 14.508 37.9999 14.894 37.9999C23.1197 37.9999 29.788 31.3374 29.788 23.1187C29.788 15.8539 18.1502 3.10158 15.4491 0.239633Z" fill="#8AC9FE"/>
<path d="M29.7489 24.1975C25.598 22.4389 21.0994 22.7823 9.48614 25.2106C6.87119 25.7574 3.87944 26.4133 0.56543 27.1942C2.33903 33.4317 8.08252 38.0002 14.8941 38.0002C22.7568 38.0002 29.1958 31.9126 29.7489 24.1975Z" fill="#60B7FF"/>
<path d="M24.4503 18.2356C28.7786 18.2356 32.2874 14.7268 32.2874 10.3986C32.2874 6.07029 28.7786 2.56152 24.4503 2.56152C20.122 2.56152 16.6133 6.07029 16.6133 10.3986C16.6133 14.7268 20.122 18.2356 24.4503 18.2356Z" fill="#97D729"/>
<path d="M24.4809 2.55176C24.0912 2.55176 23.7084 2.58063 23.334 2.63562C27.1139 3.19056 30.0157 6.44645 30.0157 10.3804C30.0157 14.3144 27.1139 17.5703 23.334 18.1252C23.7083 18.1802 24.0912 18.2091 24.4809 18.2091C28.8046 18.2091 32.3095 14.7041 32.3095 10.3804C32.3095 6.05673 28.8046 2.55176 24.4809 2.55176Z" fill="#8BC727"/>
<path d="M23.5955 13.7687C23.152 13.7687 22.7351 13.596 22.4217 13.2823L20.0277 10.8884C19.5415 10.4023 19.5415 9.61415 20.0277 9.12794C20.5139 8.64181 21.3021 8.64166 21.7882 9.12794L23.5956 10.9352L27.174 7.35679C27.6602 6.87065 28.4484 6.87065 28.9345 7.35679C29.4207 7.84292 29.4207 8.6312 28.9345 9.11725L24.7693 13.2825C24.4557 13.5961 24.0389 13.7687 23.5955 13.7687Z" fill="#F9F7F8"/>
<path d="M29.7489 24.1905C29.0405 23.8904 28.2551 23.6536 27.4901 23.4795C27.457 24.9292 27.2331 26.2952 26.8027 27.6092L28.6417 28.8525C28.9343 28.1675 29.2026 27.3281 29.4251 26.3498C29.6058 25.5549 29.7017 24.8258 29.7489 24.1905Z" fill="#26A6FE"/>
<path d="M20.4549 26.3653C12.6679 25.0828 8.6078 20.1017 0.369386 20.6401C0.132109 21.5158 0 22.3486 0 23.1191C0 31.3378 6.66825 38.0003 14.894 38.0003C22.1215 38.0003 28.1457 32.8566 29.5018 26.0334C25.8167 26.8563 22.8019 26.7518 20.4549 26.3653Z" fill="#0593FC"/>
<path d="M27.1164 26.4548C25.6828 32.7081 20.3073 37.4589 13.7412 37.9562C14.1215 37.9853 14.5057 38.0001 14.8935 38.0001C22.1209 38.0001 28.1451 32.8564 29.5012 26.0332C28.6723 26.2183 27.8776 26.3561 27.1164 26.4548Z" fill="#0182FC"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -2,11 +2,11 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:go_router/go_router.dart';
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:syncrow_web/services/locator.dart';
import 'package:syncrow_web/utils/app_routes.dart';
import 'package:syncrow_web/utils/constants/routes_const.dart';
@ -14,8 +14,7 @@ import 'package:syncrow_web/utils/theme/theme.dart';
Future<void> main() async {
try {
const environment =
String.fromEnvironment('FLAVOR', defaultValue: 'development');
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development');
await dotenv.load(fileName: '.env.$environment');
WidgetsFlutterBinding.ensureInitialized();
initialSetup();
@ -45,11 +44,9 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//HomeBloc.fetchUserInfo();
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => HomeBloc()..add(const FetchUserInfo())),
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
BlocProvider<VisitorPasswordBloc>(
create: (context) => VisitorPasswordBloc(),
)

View File

@ -27,7 +27,8 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
List<PasswordModel> filteredData = [];
List<PasswordModel> data = [];
Future<void> _onFetchTableData(FetchTableData event, Emitter<AccessState> emit) async {
Future<void> _onFetchTableData(
FetchTableData event, Emitter<AccessState> emit) async {
try {
emit(AccessLoaded());
data = await AccessMangApi().fetchVisitorPassword();
@ -40,19 +41,28 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
}
void updateTabsCount() {
int toBeEffectiveCount =
data.where((item) => item.passwordStatus.value == 'To be effective').length;
int effectiveCount = data.where((item) => item.passwordStatus.value == 'Effective').length;
int expiredCount = data.where((item) => item.passwordStatus.value == 'Expired').length;
int toBeEffectiveCount = data
.where((item) => item.passwordStatus.value == 'To be effective')
.length;
int effectiveCount =
data.where((item) => item.passwordStatus.value == 'Effective').length;
int expiredCount =
data.where((item) => item.passwordStatus.value == 'Expired').length;
tabs[1] = 'To Be Effective ($toBeEffectiveCount)';
tabs[2] = 'Effective ($effectiveCount)';
tabs[3] = 'Expired ($expiredCount)';
}
int selectedIndex = 0;
final List<String> tabs = ['All', 'To Be Effective (0)', 'Effective (0)', 'Expired'];
final List<String> tabs = [
'All',
'To Be Effective (0)',
'Effective (0)',
'Expired'
];
Future selectFilterTap(TabChangedEvent event, Emitter<AccessState> emit) async {
Future selectFilterTap(
TabChangedEvent event, Emitter<AccessState> emit) async {
try {
emit(AccessLoaded());
selectedIndex = event.selectedIndex;
@ -64,14 +74,33 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
}
}
Future<void> selectTime(SelectTime event, Emitter<AccessState> emit,) async {
Future<void> selectTime(
SelectTime event,
Emitter<AccessState> emit,
) async {
emit(AccessLoaded());
final DateTime? picked = await showDatePicker(
context: event.context,
initialDate: DateTime.now(),
firstDate: DateTime.now().add(const Duration(days: -5095)),
firstDate: DateTime.now().add(const Duration(days: -5095)),
lastDate: DateTime.now().add(const Duration(days: 2095)),
builder: (BuildContext context, Widget? child) {
return Theme(
data: ThemeData.light().copyWith(
colorScheme: ColorScheme.light(
primary: ColorsManager.blackColor,
onPrimary: Colors.white,
onSurface: ColorsManager.grayColor,
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: Colors.blue,
),
),
),
child: child!,
);
},
);
if (picked != null) {
final TimeOfDay? timePicked = await showHourPicker(
@ -87,17 +116,22 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
timePicked.hour,
timePicked.minute,
);
final int selectedTimestamp = selectedDateTime.millisecondsSinceEpoch ~/ 1000;
final int selectedTimestamp =
selectedDateTime.millisecondsSinceEpoch ~/ 1000;
if (event.isStart) {
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
if (expirationTimeTimeStamp != null &&
selectedTimestamp > expirationTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Effective Time cannot be later than Expiration Time.');
} else {
startTime = selectedDateTime.toString().split('.').first;
effectiveTimeTimeStamp = selectedTimestamp;
}
} else {
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
if (effectiveTimeTimeStamp != null &&
selectedTimestamp < effectiveTimeTimeStamp!) {
CustomSnackBar.displaySnackBar(
'Expiration Time cannot be earlier than Effective Time.');
} else {
endTime = selectedDateTime.toString().split('.').first;
expirationTimeTimeStamp = selectedTimestamp;
@ -106,40 +140,52 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
}
}
emit(ChangeTimeState());
}
Future<void> _filterData(FilterDataEvent event, Emitter<AccessState> emit) async {
Future<void> _filterData(
FilterDataEvent event, Emitter<AccessState> emit) async {
emit(AccessLoaded());
try {
print(event.emailAuthorizer?.toLowerCase());
// Convert search text to lower case for case-insensitive search
final searchText = event.passwordName?.toLowerCase() ?? '';
final searchEmailText = event.emailAuthorizer?.toLowerCase() ?? '';
filteredData = data.where((item) {
bool matchesCriteria = true;
// Convert timestamp to DateTime and extract date component
DateTime effectiveDate =
DateTime.fromMillisecondsSinceEpoch(int.parse(item.effectiveTime.toString()) * 1000)
DateTime effectiveDate = DateTime.fromMillisecondsSinceEpoch(
int.parse(item.effectiveTime.toString()) * 1000)
.toUtc()
.toLocal();
DateTime invalidDate =
DateTime.fromMillisecondsSinceEpoch(int.parse(item.invalidTime.toString()) * 1000)
DateTime invalidDate = DateTime.fromMillisecondsSinceEpoch(
int.parse(item.invalidTime.toString()) * 1000)
.toUtc()
.toLocal();
DateTime effectiveDateAndTime = DateTime(effectiveDate.year, effectiveDate.month, effectiveDate.day,effectiveDate.hour,effectiveDate.minute);
DateTime invalidDateAndTime = DateTime(invalidDate.year, invalidDate.month, invalidDate.day,invalidDate.hour,invalidDate.minute);
DateTime effectiveDateAndTime = DateTime(
effectiveDate.year,
effectiveDate.month,
effectiveDate.day,
effectiveDate.hour,
effectiveDate.minute);
DateTime invalidDateAndTime = DateTime(
invalidDate.year,
invalidDate.month,
invalidDate.day,
invalidDate.hour,
invalidDate.minute);
// Filter by password name, making the search case-insensitive
if (searchText.isNotEmpty) {
final bool matchesName = item.passwordName.toString().toLowerCase().contains(searchText);
final bool matchesName =
item.passwordName.toString().toLowerCase().contains(searchText);
if (!matchesName) {
matchesCriteria = false;
}
}
if (searchEmailText.isNotEmpty) {
final bool matchesName = item.authorizerEmail.toString().toLowerCase().contains(searchEmailText);
final bool matchesName = item.authorizerEmail
.toString()
.toLowerCase()
.contains(searchEmailText);
if (!matchesName) {
matchesCriteria = false;
}
@ -147,13 +193,11 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
// Filter by start date only
if (event.startTime != null && event.endTime == null) {
DateTime startDateTime =
DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000).toUtc().toLocal();
startDateTime = DateTime(
startDateTime.year,
startDateTime.month,
startDateTime.day,
startDateTime.hour,
startDateTime.minute);
DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000)
.toUtc()
.toLocal();
startDateTime = DateTime(startDateTime.year, startDateTime.month,
startDateTime.day, startDateTime.hour, startDateTime.minute);
if (effectiveDateAndTime.isBefore(startDateTime)) {
matchesCriteria = false;
}
@ -161,14 +205,11 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
// Filter by end date only
if (event.endTime != null && event.startTime == null) {
DateTime startDateTime =
DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000).toUtc().toLocal();
startDateTime = DateTime(
startDateTime.year,
startDateTime.month,
startDateTime.day,
startDateTime.hour,
startDateTime.minute
);
DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000)
.toUtc()
.toLocal();
startDateTime = DateTime(startDateTime.year, startDateTime.month,
startDateTime.day, startDateTime.hour, startDateTime.minute);
if (invalidDateAndTime.isAfter(startDateTime)) {
matchesCriteria = false;
}
@ -177,22 +218,32 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
// Filter by both start date and end date
if (event.startTime != null && event.endTime != null) {
DateTime startDateTime =
DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000).toUtc().toLocal();
DateTime.fromMillisecondsSinceEpoch(event.startTime! * 1000)
.toUtc()
.toLocal();
DateTime endDateTime =
DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000).toUtc().toLocal();
startDateTime = DateTime(startDateTime.year, startDateTime.month, startDateTime.day,startDateTime.hour,startDateTime.minute);
endDateTime = DateTime(endDateTime.year, endDateTime.month, endDateTime.day,endDateTime.hour,endDateTime.minute);
if (effectiveDateAndTime.isBefore(startDateTime) || invalidDateAndTime.isAfter(endDateTime)) {
DateTime.fromMillisecondsSinceEpoch(event.endTime! * 1000)
.toUtc()
.toLocal();
startDateTime = DateTime(startDateTime.year, startDateTime.month,
startDateTime.day, startDateTime.hour, startDateTime.minute);
endDateTime = DateTime(endDateTime.year, endDateTime.month,
endDateTime.day, endDateTime.hour, endDateTime.minute);
if (effectiveDateAndTime.isBefore(startDateTime) ||
invalidDateAndTime.isAfter(endDateTime)) {
matchesCriteria = false;
}
}
// Filter by selected tab index
if (event.selectedTabIndex == 1 && item.passwordStatus.value != 'To be effective') {
if (event.selectedTabIndex == 1 &&
item.passwordStatus.value != 'To be effective') {
matchesCriteria = false;
} else if (event.selectedTabIndex == 2 && item.passwordStatus.value != 'Effective') {
} else if (event.selectedTabIndex == 2 &&
item.passwordStatus.value != 'Effective') {
matchesCriteria = false;
} else if (event.selectedTabIndex == 3 && item.passwordStatus.value != 'Expired') {
} else if (event.selectedTabIndex == 3 &&
item.passwordStatus.value != 'Expired') {
matchesCriteria = false;
}
@ -205,7 +256,6 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
}
}
resetSearch(ResetSearch event, Emitter<AccessState> emit) async {
emit(AccessLoaded());
startTime = 'Start Time';
@ -219,13 +269,14 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
}
String timestampToDate(dynamic timestamp) {
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(int.parse(timestamp) * 1000);
DateTime dateTime =
DateTime.fromMillisecondsSinceEpoch(int.parse(timestamp) * 1000);
return "${dateTime.year}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.day.toString().padLeft(2, '0')} "
" ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}";
}
Future<void> onTabChanged(TabChangedEvent event, Emitter<AccessState> emit) async {
Future<void> onTabChanged(
TabChangedEvent event, Emitter<AccessState> emit) async {
try {
emit(AccessLoaded());
selectedIndex = event.selectedIndex;
@ -234,14 +285,19 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
filteredData = data;
break;
case 1: // To Be Effective
filteredData =
data.where((item) => item.passwordStatus.value == "To Be Effective").toList();
filteredData = data
.where((item) => item.passwordStatus.value == "To Be Effective")
.toList();
break;
case 2: // Effective
filteredData = data.where((item) => item.passwordStatus.value == "Effective").toList();
filteredData = data
.where((item) => item.passwordStatus.value == "Effective")
.toList();
break;
case 3: // Expired
filteredData = data.where((item) => item.passwordStatus.value == "Expired").toList();
filteredData = data
.where((item) => item.passwordStatus.value == "Expired")
.toList();
break;
default:
filteredData = data;
@ -257,6 +313,4 @@ class AccessBloc extends Bloc<AccessEvent, AccessState> {
emit(FailedState(e.toString()));
}
}
}

View File

@ -15,8 +15,8 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/app_enum.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/style.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
import 'package:syncrow_web/utils/style.dart';
import 'package:syncrow_web/web_layout/web_scaffold.dart';
class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
@ -24,11 +24,11 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
@override
Widget build(BuildContext context) {
final isLargeScreen = isLargeScreenSize(context);
final isSmallScreen = isSmallScreenSize(context);
final isHalfMediumScreen = isHafMediumScreenSize(context);
final padding = isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15);
final padding =
isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15);
return WebScaffold(
enableMenuSidebar: false,
@ -38,23 +38,10 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
style: Theme.of(context).textTheme.headlineLarge,
),
),
centerBody: Wrap(
children: [
Padding(
padding: EdgeInsets.only(left: MediaQuery.of(context).size.width * 0.09),
child: Align(
alignment: Alignment.bottomLeft,
child: Text(
'Physical Access',
style: Theme.of(context).textTheme.headlineMedium!.copyWith(color: Colors.white),
),
),
),
],
),
rightBody: const NavigateHomeGridView(),
scaffoldBody: BlocProvider(
create: (BuildContext context) => AccessBloc()..add(FetchTableData()),
create: (BuildContext context) =>
AccessBloc()..add(FetchTableData()),
child: BlocConsumer<AccessBloc, AccessState>(
listener: (context, state) {},
builder: (context, state) {
@ -86,7 +73,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
_buildVisitorAdminPasswords(context, accessBloc),
const SizedBox(height: 20),
Expanded(
child: DynamicTable(
child: DynamicTable(
tableName: 'AccessManagement',
uuidIndex: 1,
withSelectAll: true,
@ -108,11 +95,14 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
return [
item.passwordName,
item.passwordType.value,
accessBloc.timestampToDate(item.effectiveTime),
accessBloc.timestampToDate(item.invalidTime),
accessBloc
.timestampToDate(item.effectiveTime),
accessBloc
.timestampToDate(item.invalidTime),
item.deviceName.toString(),
item.authorizerEmail.toString(),
accessBloc.timestampToDate(item.invalidTime),
accessBloc
.timestampToDate(item.invalidTime),
item.passwordStatus.value,
];
}).toList(),
@ -123,7 +113,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
})));
}
Wrap _buildVisitorAdminPasswords(BuildContext context, AccessBloc accessBloc) {
Wrap _buildVisitorAdminPasswords(
BuildContext context, AccessBloc accessBloc) {
return Wrap(
spacing: 10,
runSpacing: 10,
@ -148,8 +139,9 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
},
borderRadius: 8,
child: Text(
'+ Create Visitor Password ',
style: context.textTheme.titleSmall!.copyWith(color: Colors.white, fontSize: 12),
'Create Visitor Password ',
style: context.textTheme.titleSmall!
.copyWith(color: Colors.white, fontSize: 12),
)),
),
Container(
@ -161,7 +153,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
backgroundColor: ColorsManager.whiteColors,
child: Text(
'Admin Password',
style: context.textTheme.titleSmall!.copyWith(color: Colors.black, fontSize: 12),
style: context.textTheme.titleSmall!
.copyWith(color: Colors.black, fontSize: 12),
)),
),
],
@ -169,7 +162,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
}
Row _buildNormalSearchWidgets(BuildContext context, AccessBloc accessBloc) {
TimeOfDay _selectedTime = TimeOfDay.now();
// TimeOfDay _selectedTime = TimeOfDay.now();
return Row(
mainAxisSize: MainAxisSize.min,
@ -184,6 +177,16 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
isRequired: false,
textFieldName: 'Name',
description: '',
onSubmitted: (value) {
accessBloc.add(FilterDataEvent(
emailAuthorizer:
accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp));
},
),
),
const SizedBox(width: 15),
@ -195,6 +198,16 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
isRequired: false,
textFieldName: 'Authorizer',
description: '',
onSubmitted: (value) {
accessBloc.add(FilterDataEvent(
emailAuthorizer:
accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp));
},
),
),
const SizedBox(width: 15),
@ -205,7 +218,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
title: 'Access Time',
size: MediaQuery.of(context).size,
endTime: () {
accessBloc.add(SelectTime(context: context, isStart: false));
accessBloc.add(SelectTime(context: context, isStart: false));
},
startTime: () {
accessBloc.add(SelectTime(context: context, isStart: true));
@ -218,8 +231,9 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
SearchResetButtons(
onSearch: () {
accessBloc.add(FilterDataEvent(
emailAuthorizer:accessBloc.emailAuthorizer.text.toLowerCase() ,
selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp));
@ -240,12 +254,21 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
SizedBox(
width: 300,
child: CustomWebTextField(
controller: accessBloc.passwordName,
isRequired: true,
height: 40,
textFieldName: 'Name',
description: '',
),
controller: accessBloc.passwordName,
isRequired: true,
height: 40,
textFieldName: 'Name',
description: '',
onSubmitted: (value) {
accessBloc.add(FilterDataEvent(
emailAuthorizer:
accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp));
}),
),
DateTimeWebWidget(
icon: Assets.calendarIcon,
@ -264,12 +287,12 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
SearchResetButtons(
onSearch: () {
accessBloc.add(FilterDataEvent(
emailAuthorizer:accessBloc.emailAuthorizer.text.toLowerCase() ,
selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp
));
endTime: accessBloc.expirationTimeTimeStamp));
},
onReset: () {
accessBloc.add(ResetSearch());
@ -278,6 +301,4 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
],
);
}
}

View File

@ -31,7 +31,8 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
////////////////////////////// forget password //////////////////////////////////
final TextEditingController forgetEmailController = TextEditingController();
final TextEditingController forgetPasswordController = TextEditingController();
final TextEditingController forgetPasswordController =
TextEditingController();
final TextEditingController forgetOtp = TextEditingController();
final forgetFormKey = GlobalKey<FormState>();
final forgetEmailKey = GlobalKey<FormState>();
@ -48,7 +49,8 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
return;
}
_remainingTime = 1;
add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
add(UpdateTimerEvent(
remainingTime: _remainingTime, isButtonEnabled: false));
try {
forgetEmailValidate = '';
_remainingTime = (await AuthenticationAPI.sendOtp(
@ -84,7 +86,8 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
_timer?.cancel();
add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true));
} else {
add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
add(UpdateTimerEvent(
remainingTime: _remainingTime, isButtonEnabled: false));
}
});
}
@ -94,37 +97,28 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
}
Future<void> changePassword(ChangePasswordEvent event, Emitter<AuthState> emit) async {
Future<void> changePassword(
ChangePasswordEvent event, Emitter<AuthState> emit) async {
emit(LoadingForgetState());
try {
var response = await AuthenticationAPI.verifyOtp(
email: forgetEmailController.text, otpCode: forgetOtp.text);
if (response == true) {
await AuthenticationAPI.forgetPassword(
password: forgetPasswordController.text,
email: forgetEmailController.text);
_timer?.cancel();
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
emit(SuccessForgetState());
}
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
if (errorMessage == 'this email is not registered') {
validate = 'Invalid Credentials!';
emit(AuthInitialState());
} else if (errorMessage == "You entered wrong otp") {
forgetValidate = 'Wrong one time password.';
emit(AuthInitialState());
} else if (errorMessage == "OTP expired") {
forgetValidate = 'One time password has been expired.';
emit(AuthInitialState());
} else {
validate = '';
emit(AuthInitialState());
}
try {
var response = await AuthenticationAPI.verifyOtp(
email: forgetEmailController.text, otpCode: forgetOtp.text);
if (response == true) {
await AuthenticationAPI.forgetPassword(
otpCode: forgetOtp.text,
password: forgetPasswordController.text,
email: forgetEmailController.text);
_timer?.cancel();
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
emit(SuccessForgetState());
}
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage =
errorData['error']['message'] ?? 'something went wrong';
validate = errorMessage;
emit(AuthInitialState());
}
}
String? validateCode(String? value) {
@ -135,7 +129,9 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
}
void _onUpdateTimer(UpdateTimerEvent event, Emitter<AuthState> emit) {
emit(TimerState(isButtonEnabled: event.isButtonEnabled, remainingTime: event.remainingTime));
emit(TimerState(
isButtonEnabled: event.isButtonEnabled,
remainingTime: event.remainingTime));
}
///////////////////////////////////// login /////////////////////////////////////
@ -167,7 +163,9 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
token = await AuthenticationAPI.loginWithEmail(
model: LoginWithEmailModel(
email: event.username, password: event.password, regionUuid: event.regionUuid),
email: event.username,
password: event.password,
regionUuid: event.regionUuid),
);
} catch (failure) {
validate = 'Invalid Credentials!';
@ -177,7 +175,8 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
if (token.accessTokenIsNotEmpty) {
FlutterSecureStorage storage = const FlutterSecureStorage();
await storage.write(key: Token.loginAccessTokenKey, value: token.accessToken);
await storage.write(
key: Token.loginAccessTokenKey, value: token.accessToken);
const FlutterSecureStorage().write(
key: UserModel.userUuidKey,
value: Token.decodeToken(token.accessToken)['uuid'].toString());
@ -335,12 +334,14 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
static Future<String> getTokenAndValidate() async {
try {
const storage = FlutterSecureStorage();
final firstLaunch =
await SharedPreferencesHelper.readBoolFromSP(StringsManager.firstLaunch) ?? true;
final firstLaunch = await SharedPreferencesHelper.readBoolFromSP(
StringsManager.firstLaunch) ??
true;
if (firstLaunch) {
storage.deleteAll();
}
await SharedPreferencesHelper.saveBoolToSP(StringsManager.firstLaunch, false);
await SharedPreferencesHelper.saveBoolToSP(
StringsManager.firstLaunch, false);
final value = await storage.read(key: Token.loginAccessTokenKey) ?? '';
if (value.isEmpty) {
return 'Token not found';
@ -393,7 +394,9 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
final String formattedTime = [
if (days > 0) '${days}d', // Append 'd' for days
if (days > 0 || hours > 0)
hours.toString().padLeft(2, '0'), // Show hours if there are days or hours
hours
.toString()
.padLeft(2, '0'), // Show hours if there are days or hours
minutes.toString().padLeft(2, '0'),
seconds.toString().padLeft(2, '0'),
].join(':');

View File

@ -48,8 +48,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
late ScrollController _scrollController;
_scrollController = ScrollController();
void _scrollToCenter() {
final double middlePosition =
_scrollController.position.maxScrollExtent / 2;
final double middlePosition = _scrollController.position.maxScrollExtent / 2;
_scrollController.animateTo(
middlePosition,
duration: const Duration(seconds: 1),
@ -66,8 +65,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
second: Center(
child: Stack(
children: [
if (state is AuthLoading)
const Center(child: CircularProgressIndicator()),
if (state is AuthLoading) const Center(child: CircularProgressIndicator()),
ListView(
shrinkWrap: true,
controller: _scrollController,
@ -97,21 +95,16 @@ class ForgetPasswordWebPage extends StatelessWidget {
child: Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius:
const BorderRadius.all(Radius.circular(30)),
border: Border.all(
color:
ColorsManager.graysColor.withOpacity(0.2)),
borderRadius: const BorderRadius.all(Radius.circular(30)),
border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2)),
),
child: Form(
key: forgetBloc.forgetFormKey,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: size.width * 0.02,
vertical: size.width * 0.003),
horizontal: size.width * 0.02, vertical: size.width * 0.003),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 10),
@ -128,66 +121,55 @@ class ForgetPasswordWebPage extends StatelessWidget {
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400),
.copyWith(fontSize: 14, fontWeight: FontWeight.w400),
),
const SizedBox(height: 10),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 10),
Form(
key: forgetBloc.forgetRegionKey,
child: SizedBox(
child: _buildDropdownField(
context, forgetBloc, size)))
Form(
key: forgetBloc.forgetRegionKey,
child: SizedBox(
child:
_buildDropdownField(context, forgetBloc, size)))
],
),
const SizedBox(height: 20),
Form(
key: forgetBloc.forgetEmailKey,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Account",
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
fontSize: 14,
fontWeight:
FontWeight.w400),
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontSize: 14, fontWeight: FontWeight.w400),
),
const SizedBox(height: 10),
SizedBox(
child: TextFormField(
controller: forgetBloc.forgetEmailController,
validator: forgetBloc.validateEmail,
decoration:
textBoxDecoration()!.copyWith(
decoration: textBoxDecoration()!.copyWith(
hintText: 'Enter your email',
hintStyle: Theme.of(context)
.textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400),
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400),
),
style: const TextStyle(
color: Colors.black),
style: const TextStyle(color: Colors.black),
),
),
],
)),
const SizedBox(height: 20.0),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
@ -195,35 +177,40 @@ class ForgetPasswordWebPage extends StatelessWidget {
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400),
.copyWith(fontSize: 14, fontWeight: FontWeight.w400),
),
const SizedBox(height: 10),
SizedBox(
child: TextFormField(
validator: forgetBloc.validateCode,
keyboardType:
TextInputType.visiblePassword,
keyboardType: TextInputType.visiblePassword,
controller: forgetBloc.forgetOtp,
decoration:
textBoxDecoration()!.copyWith(
decoration: textBoxDecoration()!.copyWith(
hintText: 'Enter Code',
hintStyle: Theme.of(context).textTheme
.bodySmall!.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400),
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400),
suffixIcon: SizedBox(
width: 100,
child: Center(
child: InkWell(
onTap: state is TimerState &&
!state.isButtonEnabled &&
state.remainingTime != 1
!state.isButtonEnabled &&
state.remainingTime != 1
? null
: () {
if (forgetBloc.forgetEmailKey.currentState!.validate()||forgetBloc.forgetRegionKey.currentState!.validate()) {
if(forgetBloc.forgetRegionKey.currentState!.validate()){
if (forgetBloc
.forgetEmailKey.currentState!
.validate() ||
forgetBloc
.forgetRegionKey.currentState!
.validate()) {
if (forgetBloc
.forgetRegionKey.currentState!
.validate()) {
forgetBloc.add(StartTimerEvent());
}
}
@ -231,28 +218,23 @@ class ForgetPasswordWebPage extends StatelessWidget {
child: Text(
'Get Code ${state is TimerState && !state.isButtonEnabled && state.remainingTime != 1 ? "(${forgetBloc.formattedTime(state.remainingTime)}) " : ""}',
style: TextStyle(
color: state
is TimerState &&
!state
.isButtonEnabled
color: state is TimerState &&
!state.isButtonEnabled
? Colors.grey
: ColorsManager
.btnColor,
: ColorsManager.btnColor,
),
),
),
),
),
),
style: const TextStyle(
color: Colors.black),
style: const TextStyle(color: Colors.black),
),
),
if (forgetBloc.forgetValidate !=
'') // Check if there is a validation message
Padding(
padding:
const EdgeInsets.only(top: 8.0),
padding: const EdgeInsets.only(top: 8.0),
child: Text(
forgetBloc.forgetValidate,
style: const TextStyle(
@ -265,8 +247,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
),
const SizedBox(height: 20.0),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
@ -274,35 +255,26 @@ class ForgetPasswordWebPage extends StatelessWidget {
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400),
.copyWith(fontSize: 14, fontWeight: FontWeight.w400),
),
const SizedBox(height: 10),
SizedBox(
child: TextFormField(
obscureText: forgetBloc.obscureText,
keyboardType:
TextInputType.visiblePassword,
validator:
forgetBloc.passwordValidator,
controller: forgetBloc
.forgetPasswordController,
decoration:
textBoxDecoration()!.copyWith(
keyboardType: TextInputType.visiblePassword,
validator: forgetBloc.passwordValidator,
controller: forgetBloc.forgetPasswordController,
decoration: textBoxDecoration()!.copyWith(
suffixIcon: IconButton(
onPressed: () {
forgetBloc.add(
PasswordVisibleEvent(
newValue: forgetBloc
.obscureText));
forgetBloc.add(PasswordVisibleEvent(
newValue: forgetBloc.obscureText));
},
icon: SizedBox(
child: SvgPicture.asset(
forgetBloc.obscureText
? Assets.visiblePassword
: Assets
.invisiblePassword,
: Assets.invisiblePassword,
height: 15,
width: 15,
),
@ -313,13 +285,10 @@ class ForgetPasswordWebPage extends StatelessWidget {
.textTheme
.bodySmall!
.copyWith(
color:
ColorsManager.grayColor,
fontWeight:
FontWeight.w400),
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400),
),
style: const TextStyle(
color: Colors.black),
style: const TextStyle(color: Colors.black),
),
),
],
@ -329,21 +298,22 @@ class ForgetPasswordWebPage extends StatelessWidget {
),
const SizedBox(height: 20.0),
Row(
crossAxisAlignment:
CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: size.width * 0.2,
child: DefaultButton(
backgroundColor:
ColorsManager.btnColor,
backgroundColor: ColorsManager.btnColor,
child: const Text('Submit'),
onPressed: () {
if (forgetBloc.forgetFormKey.currentState!.validate() ||
forgetBloc.forgetEmailKey.currentState!.validate() ) {
if( forgetBloc.forgetEmailKey.currentState!.validate()
&&forgetBloc.forgetFormKey.currentState!.validate() ){
forgetBloc.forgetEmailKey.currentState!
.validate()) {
if (forgetBloc.forgetEmailKey.currentState!
.validate() &&
forgetBloc.forgetFormKey.currentState!
.validate()) {
forgetBloc.add(ChangePasswordEvent());
}
}
@ -358,8 +328,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
child: Text(
forgetBloc.validate,
style: const TextStyle(
fontWeight: FontWeight.w700,
color: ColorsManager.red),
fontWeight: FontWeight.w700, color: ColorsManager.red),
),
),
),
@ -372,8 +341,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
children: [
const Text(
"Do you have an account? ",
style:
TextStyle(color: Colors.white),
style: TextStyle(color: Colors.white),
),
InkWell(
onTap: () {
@ -407,8 +375,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
));
}
Widget _buildDropdownField(
BuildContext context, AuthBloc loginBloc, Size size) {
Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) {
final TextEditingController textEditingController = TextEditingController();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -434,13 +401,10 @@ class ForgetPasswordWebPage extends StatelessWidget {
builder: (FormFieldState<String> field) {
return InputDecorator(
decoration: InputDecoration(
contentPadding:
const EdgeInsets.symmetric(horizontal: 2, vertical: 10),
contentPadding: const EdgeInsets.symmetric(horizontal: 2, vertical: 10),
errorText: field.errorText,
filled:
true, // Ensure the dropdown is filled with the background color
fillColor: ColorsManager
.boxColor, // Match the dropdown container color
filled: true, // Ensure the dropdown is filled with the background color
fillColor: ColorsManager.boxColor, // Match the dropdown container color
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
@ -451,22 +415,20 @@ class ForgetPasswordWebPage extends StatelessWidget {
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color:
field.hasError ? Colors.red : ColorsManager.grayColor,
color: field.hasError ? Colors.red : ColorsManager.grayColor,
width: 1.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color:
field.hasError ? Colors.red : ColorsManager.grayColor,
color: field.hasError ? Colors.red : ColorsManager.grayColor,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
borderSide: const BorderSide(
color: Colors.red,
width: 1.5,
),
@ -488,24 +450,22 @@ class ForgetPasswordWebPage extends StatelessWidget {
value: region.id,
child: Text(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400,
),
fontSize: 14,
fontWeight: FontWeight.w400,
),
region.name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
);
}).toList(),
value: loginBloc.regionList!
.any((region) => region.id == loginBloc.regionUuid)
value: loginBloc.regionList!.any((region) => region.id == loginBloc.regionUuid)
? loginBloc.regionUuid
: null,
onChanged: (String? value) {
if (value != null) {
loginBloc.add(SelectRegionEvent(val: value));
field.didChange(
value); // Notify the form field of the change
field.didChange(value); // Notify the form field of the change
}
},
buttonStyleData: const ButtonStyleData(
@ -529,8 +489,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
searchInnerWidgetHeight: 50,
searchInnerWidget: Container(
height: 50,
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: TextFormField(
style: const TextStyle(color: Colors.black),
controller: textEditingController,
@ -544,8 +503,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
),
),
searchMatchFn: (item, searchValue) {
final regionName =
(item.child as Text).data?.toLowerCase() ?? '';
final regionName = (item.child as Text).data?.toLowerCase() ?? '';
final search = searchValue.toLowerCase().trim();
return regionName.contains(search);
},
@ -564,6 +522,4 @@ class ForgetPasswordWebPage extends StatelessWidget {
],
);
}
}

View File

@ -24,8 +24,7 @@ class LoginWebPage extends StatefulWidget {
State<LoginWebPage> createState() => _LoginWebPageState();
}
class _LoginWebPageState extends State<LoginWebPage>
with HelperResponsiveLayout {
class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout {
@override
Widget build(BuildContext context) {
return Scaffold(
@ -60,8 +59,7 @@ class _LoginWebPageState extends State<LoginWebPage>
_scrollController = ScrollController();
void _scrollToCenter() {
final double middlePosition =
_scrollController.position.maxScrollExtent / 2;
final double middlePosition = _scrollController.position.maxScrollExtent / 2;
_scrollController.animateTo(
middlePosition,
duration: const Duration(seconds: 1),
@ -123,8 +121,7 @@ class _LoginWebPageState extends State<LoginWebPage>
const Spacer(),
Expanded(
flex: 2,
child: _buildLoginFormFields(
context, loginBloc, size),
child: _buildLoginFormFields(context, loginBloc, size),
),
const Spacer(),
],
@ -135,14 +132,12 @@ class _LoginWebPageState extends State<LoginWebPage>
),
),
),
if (state is AuthLoading)
const Center(child: CircularProgressIndicator())
if (state is AuthLoading) const Center(child: CircularProgressIndicator())
],
);
}
Widget _buildLoginFormFields(
BuildContext context, AuthBloc loginBloc, Size size) {
Widget _buildLoginFormFields(BuildContext context, AuthBloc loginBloc, Size size) {
return Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
@ -152,8 +147,8 @@ class _LoginWebPageState extends State<LoginWebPage>
child: Form(
key: loginBloc.loginFormKey,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: size.width * 0.02, vertical: size.width * 0.003),
padding:
EdgeInsets.symmetric(horizontal: size.width * 0.02, vertical: size.width * 0.003),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
@ -181,9 +176,7 @@ class _LoginWebPageState extends State<LoginWebPage>
);
}
Widget _buildDropdownField(
BuildContext context, AuthBloc loginBloc, Size size) {
Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) {
final TextEditingController textEditingController = TextEditingController();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -192,9 +185,9 @@ class _LoginWebPageState extends State<LoginWebPage>
Text(
"Country/Region",
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400,
),
fontSize: 14,
fontWeight: FontWeight.w400,
),
),
const SizedBox(height: 10),
Container(
@ -211,9 +204,9 @@ class _LoginWebPageState extends State<LoginWebPage>
hint: Text(
'Select your region/country',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400,
),
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400,
),
overflow: TextOverflow.ellipsis,
),
items: loginBloc.regionList!.map((RegionModel region) {
@ -227,7 +220,8 @@ class _LoginWebPageState extends State<LoginWebPage>
);
}).toList(),
value: loginBloc.regionList!.any(
(region) => region.id == loginBloc.regionUuid,)
(region) => region.id == loginBloc.regionUuid,
)
? loginBloc.regionUuid
: null,
onChanged: (String? value) {
@ -286,7 +280,6 @@ class _LoginWebPageState extends State<LoginWebPage>
);
}
Widget _buildEmailField(BuildContext context, AuthBloc loginBloc) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -310,9 +303,10 @@ class _LoginWebPageState extends State<LoginWebPage>
decoration: textBoxDecoration()!.copyWith(
errorStyle: const TextStyle(height: 0),
hintText: 'Enter your email address',
hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400)),
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400)),
style: const TextStyle(color: Colors.black),
),
),
@ -344,18 +338,17 @@ class _LoginWebPageState extends State<LoginWebPage>
controller: loginBloc.loginPasswordController,
decoration: textBoxDecoration()!.copyWith(
hintText: 'At least 8 characters',
hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor, fontWeight: FontWeight.w400),
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400),
suffixIcon: IconButton(
onPressed: () {
loginBloc.add(
PasswordVisibleEvent(newValue: loginBloc.obscureText));
loginBloc.add(PasswordVisibleEvent(newValue: loginBloc.obscureText));
},
icon: SizedBox(
child: SvgPicture.asset(
loginBloc.obscureText
? Assets.visiblePassword
: Assets.invisiblePassword,
loginBloc.obscureText ? Assets.visiblePassword : Assets.invisiblePassword,
height: 15,
width: 15,
),
@ -383,10 +376,10 @@ class _LoginWebPageState extends State<LoginWebPage>
},
child: Text(
"Forgot Password?",
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w400),
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.black, fontSize: 14, fontWeight: FontWeight.w400),
),
),
],
@ -450,8 +443,7 @@ class _LoginWebPageState extends State<LoginWebPage>
);
}
Widget _buildSignInButton(
BuildContext context, AuthBloc loginBloc, Size size) {
Widget _buildSignInButton(BuildContext context, AuthBloc loginBloc, Size size) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
@ -492,8 +484,7 @@ class _LoginWebPageState extends State<LoginWebPage>
SizedBox(
child: Text(
loginBloc.validate,
style: const TextStyle(
fontWeight: FontWeight.w700, color: ColorsManager.red),
style: const TextStyle(fontWeight: FontWeight.w700, color: ColorsManager.red),
),
)
],

View File

@ -0,0 +1,304 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class AccessDeviceTable extends StatefulWidget {
final List<String> headers;
final String? tableName;
final List<List<dynamic>> data;
final BoxDecoration? headerDecoration;
final BoxDecoration? cellDecoration;
final Size size;
final bool withCheckBox;
final bool withSelectAll;
final bool isEmpty;
final void Function(bool?)? selectAll;
final void Function(int, bool, dynamic)? onRowSelected;
final List<String>? initialSelectedIds;
final int uuidIndex;
const AccessDeviceTable({
super.key,
required this.headers,
required this.data,
required this.size,
this.tableName,
required this.isEmpty,
required this.withCheckBox,
required this.withSelectAll,
this.headerDecoration,
this.cellDecoration,
this.selectAll,
this.onRowSelected,
this.initialSelectedIds,
required this.uuidIndex,
});
@override
_DynamicTableState createState() => _DynamicTableState();
}
class _DynamicTableState extends State<AccessDeviceTable> {
late List<bool> _selected;
bool _selectAll = false;
@override
void initState() {
super.initState();
_initializeSelection();
}
@override
void didUpdateWidget(AccessDeviceTable oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.data != widget.data) {
_initializeSelection();
}
}
void _initializeSelection() {
if (widget.data.isEmpty) {
_selected = [];
_selectAll = false;
} else {
_selected = List<bool>.generate(widget.data.length, (index) {
// Check if the initialSelectedIds contains the deviceUuid
// uuidIndex is the index of the column containing the deviceUuid
final deviceUuid = widget.data[index][widget.uuidIndex];
return widget.initialSelectedIds != null &&
widget.initialSelectedIds!.contains(deviceUuid);
});
_selectAll = _selected.every((element) => element == true);
}
}
void _toggleRowSelection(int index) {
setState(() {
_selected[index] = !_selected[index];
if (widget.onRowSelected != null) {
widget.onRowSelected!(index, _selected[index], widget.data[index]);
}
});
}
void _toggleSelectAll(bool? value) {
setState(() {
_selectAll = value ?? false;
_selected = List<bool>.filled(widget.data.length, _selectAll);
if (widget.selectAll != null) {
widget.selectAll!(_selectAll);
}
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: widget.cellDecoration,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: widget.size.width,
child: Column(
children: [
Container(
decoration: widget.headerDecoration ??
BoxDecoration(color: Colors.grey[200]),
child: Row(
children: [
if (widget.withCheckBox) _buildSelectAllCheckbox(),
...widget.headers
.map((header) => _buildTableHeaderCell(header)),
],
),
),
widget.isEmpty
? Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
SvgPicture.asset(Assets.emptyTable),
const SizedBox(
height: 15,
),
Text(
// no password
widget.tableName == 'AccessManagement'
? 'No Password '
: 'No Devices',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.grayColor),
)
],
),
],
),
],
),
)
: Expanded(
child: Container(
color: Colors.white,
child: ListView.builder(
shrinkWrap: true,
itemCount: widget.data.length,
itemBuilder: (context, index) {
final row = widget.data[index];
return Row(
children: [
if (widget.withCheckBox)
_buildRowCheckbox(
index, widget.size.height * 0.10),
...row.map((cell) => _buildTableCell(
cell.toString(),
widget.size.height * 0.10)),
],
);
},
),
),
),
],
),
),
),
);
}
Widget _buildSelectAllCheckbox() {
return Container(
width: 50,
padding: const EdgeInsets.all(8.0),
decoration: const BoxDecoration(
border: Border.symmetric(
vertical: BorderSide(color: ColorsManager.boxDivider),
),
),
child: Checkbox(
value: widget.data.isNotEmpty &&
_selected.every((element) => element == true),
onChanged: widget.withSelectAll && widget.data.isNotEmpty
? _toggleSelectAll
: null,
),
);
}
Widget _buildRowCheckbox(int index, double size) {
return Container(
width: 50,
padding: const EdgeInsets.all(8.0),
height: size,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
color: ColorsManager.boxDivider,
width: 1.0,
),
),
),
alignment: Alignment.centerLeft,
child: Center(
child: Checkbox(
value: _selected[index],
onChanged: (bool? value) {
_toggleRowSelection(index);
},
),
),
);
}
Widget _buildTableHeaderCell(String title) {
return Expanded(
child: Container(
decoration: const BoxDecoration(
border: Border.symmetric(
vertical: BorderSide(color: ColorsManager.boxDivider),
),
),
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
title,
style: const TextStyle(
fontWeight: FontWeight.w400,
fontSize: 13,
color: Color(0xFF999999),
),
maxLines: 2,
),
),
),
);
}
Widget _buildTableCell(String content, double size) {
bool isBatteryLevel = content.endsWith('%');
double? batteryLevel;
if (isBatteryLevel) {
batteryLevel = double.tryParse(content.replaceAll('%', '').trim());
}
Color? statusColor;
switch (content) {
case 'Effective':
statusColor = ColorsManager.textGreen;
break;
case 'Expired':
statusColor = ColorsManager.red;
break;
case 'To be effective':
statusColor = ColorsManager.yaGreen;
break;
case 'Online':
statusColor = ColorsManager.green;
break;
case 'Offline':
statusColor = ColorsManager.red;
break;
default:
statusColor = Colors.black;
}
return Expanded(
child: Container(
height: size,
padding: const EdgeInsets.all(5.0),
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
color: ColorsManager.boxDivider,
width: 1.0,
),
),
),
alignment: Alignment.centerLeft,
child: Text(
content,
style: TextStyle(
color: (batteryLevel != null && batteryLevel < 20)
? ColorsManager.red
: (batteryLevel != null && batteryLevel > 20)
? ColorsManager.green
: statusColor,
fontSize: 10,
fontWeight: FontWeight.w400),
maxLines: 2,
),
),
);
}
}

View File

@ -17,6 +17,8 @@ class DefaultButton extends StatelessWidget {
this.borderRadius,
this.height,
this.padding,
this.borderColor,
this.elevation,
});
final void Function()? onPressed;
final Widget child;
@ -31,6 +33,9 @@ class DefaultButton extends StatelessWidget {
final ButtonStyle? customButtonStyle;
final Color? backgroundColor;
final Color? foregroundColor;
final Color? borderColor;
final double? elevation;
@override
Widget build(BuildContext context) {
return ElevatedButton(
@ -39,40 +44,42 @@ class DefaultButton extends StatelessWidget {
? null
: customButtonStyle ??
ButtonStyle(
textStyle: MaterialStateProperty.all(
textStyle: WidgetStateProperty.all(
customTextStyle ??
Theme.of(context).textTheme.bodySmall!.copyWith(
fontSize: 13,
color: foregroundColor,
fontWeight: FontWeight.normal),
),
foregroundColor: MaterialStateProperty.all(
foregroundColor: WidgetStateProperty.all(
isSecondary
? Colors.black
: enabled
? foregroundColor ?? Colors.white
: Colors.black,
),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
backgroundColor: WidgetStateProperty.resolveWith<Color>(
(Set<WidgetState> states) {
return enabled
? backgroundColor ?? ColorsManager.primaryColor
: Colors.black.withOpacity(0.2);
}),
shape: MaterialStateProperty.all(
shape: WidgetStateProperty.all(
RoundedRectangleBorder(
side: BorderSide(color: borderColor ?? Colors.transparent),
borderRadius: BorderRadius.circular(borderRadius ?? 20),
),
),
fixedSize: MaterialStateProperty.all(
fixedSize: WidgetStateProperty.all(
const Size.fromHeight(50),
),
padding: MaterialStateProperty.all(
padding: WidgetStateProperty.all(
EdgeInsets.all(padding ?? 10),
),
minimumSize: MaterialStateProperty.all(
minimumSize: WidgetStateProperty.all(
const Size.fromHeight(50),
),
elevation: WidgetStateProperty.all(elevation ?? 0),
),
child: SizedBox(
height: height ?? 50,

View File

@ -1,6 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
@ -22,19 +22,16 @@ class CurtainToggle extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(16),
return DeviceControlsContainer(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipOval(
child: Container(
@ -47,6 +44,9 @@ class CurtainToggle extends StatelessWidget {
),
),
),
const SizedBox(
width: 20,
),
SizedBox(
height: 20,
width: 35,

View File

@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_managment_bloc.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 DynamicTable extends StatefulWidget {
final List<String> headers;
@ -17,6 +20,7 @@ class DynamicTable extends StatefulWidget {
final void Function(int, bool, dynamic)? onRowSelected;
final List<String>? initialSelectedIds;
final int uuidIndex;
final Function(dynamic selectedRows)? onSelectionChanged;
const DynamicTable({
super.key,
required this.headers,
@ -32,6 +36,7 @@ class DynamicTable extends StatefulWidget {
this.onRowSelected,
this.initialSelectedIds,
required this.uuidIndex,
this.onSelectionChanged,
});
@override
@ -39,8 +44,10 @@ class DynamicTable extends StatefulWidget {
}
class _DynamicTableState extends State<DynamicTable> {
late List<bool> _selected;
late List<bool> _selectedRows;
bool _selectAll = false;
final ScrollController _verticalScrollController = ScrollController();
final ScrollController _horizontalScrollController = ScrollController();
@override
void initState() {
@ -51,126 +58,128 @@ class _DynamicTableState extends State<DynamicTable> {
@override
void didUpdateWidget(DynamicTable oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.data != widget.data) {
if (!_compareListOfLists(oldWidget.data, widget.data)) {
_initializeSelection();
}
}
void _initializeSelection() {
if (widget.data.isEmpty) {
_selected = [];
_selectAll = false;
} else {
_selected = List<bool>.generate(widget.data.length, (index) {
// Check if the initialSelectedIds contains the deviceUuid
// uuidIndex is the index of the column containing the deviceUuid
final deviceUuid = widget.data[index][widget.uuidIndex];
return widget.initialSelectedIds != null &&
widget.initialSelectedIds!.contains(deviceUuid);
});
_selectAll = _selected.every((element) => element == true);
bool _compareListOfLists(List<List<dynamic>> oldList, List<List<dynamic>> newList) {
// Check if the old and new lists are the same
if (oldList.length != newList.length) return false;
for (int i = 0; i < oldList.length; i++) {
if (oldList[i].length != newList[i].length) return false;
for (int j = 0; j < oldList[i].length; j++) {
if (oldList[i][j] != newList[i][j]) return false;
}
}
return true;
}
void _initializeSelection() {
_selectedRows = List<bool>.filled(widget.data.length, false);
_selectAll = false;
}
void _toggleRowSelection(int index) {
setState(() {
_selected[index] = !_selected[index];
if (widget.onRowSelected != null) {
widget.onRowSelected!(index, _selected[index], widget.data[index]);
}
_selectedRows[index] = !_selectedRows[index];
_selectAll = _selectedRows.every((isSelected) => isSelected);
});
widget.onSelectionChanged?.call(_selectedRows);
context.read<DeviceManagementBloc>().add(UpdateSelection(_selectedRows));
}
void _toggleSelectAll(bool? value) {
setState(() {
_selectAll = value ?? false;
_selected = List<bool>.filled(widget.data.length, _selectAll);
for (int i = 0; i < widget.data.length; i++) {
if (widget.onRowSelected != null) {
widget.onRowSelected!(i, _selectAll, widget.data[i]);
}
}
_selectedRows = List<bool>.filled(widget.data.length, _selectAll);
});
widget.onSelectionChanged?.call(_selectedRows);
context.read<DeviceManagementBloc>().add(UpdateSelection(_selectedRows));
}
@override
Widget build(BuildContext context) {
return Container(
decoration: widget.cellDecoration,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: widget.size.width,
child: Column(
children: [
Container(
decoration: widget.headerDecoration ??
BoxDecoration(color: Colors.grey[200]),
child: Row(
child: Scrollbar(
controller: _verticalScrollController,
thumbVisibility: true,
trackVisibility: true,
child: Scrollbar(
controller: _horizontalScrollController,
thumbVisibility: false,
trackVisibility: false,
notificationPredicate: (notif) => notif.depth == 1,
child: SingleChildScrollView(
controller: _verticalScrollController,
child: SingleChildScrollView(
controller: _horizontalScrollController,
scrollDirection: Axis.horizontal,
child: SizedBox(
width: widget.size.width,
child: Column(
children: [
if (widget.withCheckBox) _buildSelectAllCheckbox(),
...widget.headers
.map((header) => _buildTableHeaderCell(header)),
],
),
),
widget.isEmpty
? Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
Container(
decoration: widget.headerDecoration ??
const BoxDecoration(
color: ColorsManager.boxColor,
),
child: Row(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
if (widget.withCheckBox) _buildSelectAllCheckbox(),
...List.generate(widget.headers.length, (index) {
return _buildTableHeaderCell(widget.headers[index], index);
})
//...widget.headers.map((header) => _buildTableHeaderCell(header)),
],
),
),
widget.isEmpty
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(Assets.emptyTable),
const SizedBox(
height: 15,
Column(
children: [
SvgPicture.asset(Assets.emptyTable),
const SizedBox(
height: 15,
),
Text(
widget.tableName == 'AccessManagement' ? 'No Password ' : 'No Devices',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: ColorsManager.grayColor),
)
],
),
Text(
// no password
widget.tableName == 'AccessManagement'
? 'No Password '
: 'No Devices',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.grayColor),
)
],
),
],
)
: Column(
children: List.generate(widget.data.length, (index) {
final row = widget.data[index];
return Row(
children: [
if (widget.withCheckBox) _buildRowCheckbox(index, widget.size.height * 0.08),
...row.map((cell) => _buildTableCell(cell.toString(), widget.size.height * 0.08)),
],
);
}),
),
],
),
)
: Expanded(
child: Container(
color: Colors.white,
child: ListView.builder(
shrinkWrap: true,
itemCount: widget.data.length,
itemBuilder: (context, index) {
final row = widget.data[index];
return Row(
children: [
if (widget.withCheckBox)
_buildRowCheckbox(
index, widget.size.height * 0.10),
...row.map((cell) => _buildTableCell(
cell.toString(),
widget.size.height * 0.10)),
],
);
},
),
),
),
],
],
),
),
),
),
),
),
@ -180,7 +189,6 @@ class _DynamicTableState extends State<DynamicTable> {
Widget _buildSelectAllCheckbox() {
return Container(
width: 50,
padding: const EdgeInsets.all(8.0),
decoration: const BoxDecoration(
border: Border.symmetric(
vertical: BorderSide(color: ColorsManager.boxDivider),
@ -188,9 +196,7 @@ class _DynamicTableState extends State<DynamicTable> {
),
child: Checkbox(
value: _selectAll,
onChanged: widget.withSelectAll && widget.data.isNotEmpty
? _toggleSelectAll
: null,
onChanged: widget.withSelectAll && widget.data.isNotEmpty ? _toggleSelectAll : null,
),
);
}
@ -207,11 +213,12 @@ class _DynamicTableState extends State<DynamicTable> {
width: 1.0,
),
),
color: ColorsManager.whiteColors,
),
alignment: Alignment.centerLeft,
child: Center(
child: Checkbox(
value: _selected[index],
value: _selectedRows[index],
onChanged: (bool? value) {
_toggleRowSelection(index);
},
@ -220,7 +227,7 @@ class _DynamicTableState extends State<DynamicTable> {
);
}
Widget _buildTableHeaderCell(String title) {
Widget _buildTableHeaderCell(String title, int index) {
return Expanded(
child: Container(
decoration: const BoxDecoration(
@ -228,15 +235,16 @@ class _DynamicTableState extends State<DynamicTable> {
vertical: BorderSide(color: ColorsManager.boxDivider),
),
),
constraints: const BoxConstraints.expand(height: 40),
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
padding: EdgeInsets.symmetric(horizontal: index == widget.headers.length - 1 ? 12 : 8.0, vertical: 4),
child: Text(
title,
style: const TextStyle(
style: context.textTheme.titleSmall!.copyWith(
color: ColorsManager.grayColor,
fontSize: 12,
fontWeight: FontWeight.w400,
fontSize: 13,
color: Color(0xFF999999),
),
maxLines: 2,
),
@ -285,6 +293,7 @@ class _DynamicTableState extends State<DynamicTable> {
width: 1.0,
),
),
color: Colors.white,
),
alignment: Alignment.centerLeft,
child: Text(
@ -295,7 +304,7 @@ class _DynamicTableState extends State<DynamicTable> {
: (batteryLevel != null && batteryLevel > 20)
? ColorsManager.green
: statusColor,
fontSize: 10,
fontSize: 13,
fontWeight: FontWeight.w400),
maxLines: 2,
),

View File

@ -81,7 +81,10 @@ class DateTimeWebWidget extends StatelessWidget {
const SizedBox(
width: 30,
),
const Icon(Icons.arrow_right_alt),
const Icon(
Icons.arrow_right_alt,
color: ColorsManager.grayColor,
),
const SizedBox(
width: 30,
),

View File

@ -1,21 +1,23 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/style.dart';
class StatefulTextField extends StatefulWidget {
const StatefulTextField({
super.key,
required this.title,
this.hintText = 'Please enter',
required this.width,
this.elevation = 0,
required this.controller,
});
const StatefulTextField(
{super.key,
required this.title,
this.hintText = 'Please enter',
required this.width,
this.elevation = 0,
required this.controller,
this.onSubmitted});
final String title;
final String hintText;
final double width;
final double elevation;
final TextEditingController controller;
final Function? onSubmitted;
@override
State<StatefulTextField> createState() => _StatefulTextFieldState();
@ -24,31 +26,34 @@ class StatefulTextField extends StatefulWidget {
class _StatefulTextFieldState extends State<StatefulTextField> {
@override
Widget build(BuildContext context) {
return CustomTextField(
title: widget.title,
controller: widget.controller,
hintText: widget.hintText,
width: widget.width,
elevation: widget.elevation,
return Container(
child: CustomTextField(
title: widget.title,
controller: widget.controller,
hintText: widget.hintText,
width: widget.width,
elevation: widget.elevation,
onSubmittedFun: widget.onSubmitted),
);
}
}
class CustomTextField extends StatelessWidget {
const CustomTextField({
super.key,
required this.title,
required this.controller,
this.hintText = 'Please enter',
required this.width,
this.elevation = 0,
});
const CustomTextField(
{super.key,
required this.title,
required this.controller,
this.hintText = 'Please enter',
required this.width,
this.elevation = 0,
this.onSubmittedFun});
final String title;
final TextEditingController controller;
final String hintText;
final double width;
final double elevation;
final Function? onSubmittedFun;
@override
Widget build(BuildContext context) {
@ -71,10 +76,12 @@ class CustomTextField extends StatelessWidget {
child: Container(
width: width,
height: 45,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
decoration: containerDecoration,
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(8),
// ),
child: TextFormField(
controller: controller,
style: const TextStyle(color: Colors.black),
@ -85,6 +92,9 @@ class CustomTextField extends StatelessWidget {
const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
border: InputBorder.none,
),
onFieldSubmitted: (_) {
onSubmittedFun!();
},
),
),
),

View File

@ -13,6 +13,7 @@ class CustomWebTextField extends StatelessWidget {
this.validator,
this.hintText,
this.height,
this.onSubmitted,
});
final bool isRequired;
@ -22,6 +23,7 @@ class CustomWebTextField extends StatelessWidget {
final String? Function(String?)? validator;
final String? hintText;
final double? height;
final ValueChanged<String>? onSubmitted;
@override
Widget build(BuildContext context) {
@ -32,23 +34,25 @@ class CustomWebTextField extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
if (isRequired)
Text('* ',
Row(
children: [
if (isRequired)
Text(
'* ',
style: Theme.of(context)
.textTheme.bodyMedium!
.textTheme
.bodyMedium!
.copyWith(color: Colors.red),
),
Text(
textFieldName,
style: Theme.of(context)
.textTheme.bodySmall!
.copyWith(color: Colors.black, fontSize: 13),
),
],
),
Text(
textFieldName,
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.black, fontSize: 13),
),
],
),
const SizedBox(
width: 10,
),
@ -68,17 +72,7 @@ class CustomWebTextField extends StatelessWidget {
),
Container(
height: height ?? 35,
decoration: containerDecoration.copyWith(
color: const Color(0xFFF5F6F7),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 3,
offset: const Offset(1, 1), // changes position of shadow
),
]
),
decoration: containerDecoration,
child: TextFormField(
validator: validator,
controller: controller,
@ -88,6 +82,7 @@ class CustomWebTextField extends StatelessWidget {
hintStyle: context.textTheme.titleSmall!
.copyWith(color: Colors.grey, fontSize: 12),
hintText: hintText ?? 'Please enter'),
onFieldSubmitted: onSubmitted,
),
),
],

View File

@ -18,6 +18,7 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
on<AcFetchBatchStatusEvent>(_onFetchAcBatchStatus);
on<AcControlEvent>(_onAcControl);
on<AcBatchControlEvent>(_onAcBatchControl);
on<AcFactoryResetEvent>(_onFactoryReset);
}
FutureOr<void> _onFetchAcStatus(
@ -184,4 +185,22 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
emit: emit,
);
}
FutureOr<void> _onFactoryReset(
AcFactoryResetEvent event, Emitter<AcsState> emit) async {
emit(AcsLoadingState());
try {
final response = await DevicesManagementApi().factoryReset(
event.factoryResetModel,
event.deviceId,
);
if (!response) {
emit(const AcsFailedState(error: 'Failed'));
} else {
add(AcFetchDeviceStatusEvent(event.deviceId));
}
} catch (e) {
emit(AcsFailedState(error: e.toString()));
}
}
}

View File

@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
sealed class AcsEvent extends Equatable {
const AcsEvent();
@ -54,3 +55,16 @@ class AcBatchControlEvent extends AcsEvent {
@override
List<Object> get props => [devicesIds, code, value];
}
class AcFactoryResetEvent extends AcsEvent {
final String deviceId;
final FactoryResetModel factoryResetModel;
const AcFactoryResetEvent({
required this.deviceId,
required this.factoryResetModel,
});
@override
List<Object> get props => [deviceId, factoryResetModel];
}

View File

@ -6,14 +6,16 @@ import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_state.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/batch_ac_mode.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/batch_fan_speed.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_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';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class AcDeviceBatchControlView extends StatelessWidget
with HelperResponsiveLayout {
class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayout {
const AcDeviceBatchControlView({super.key, required this.devicesIds});
final List<String> devicesIds;
@ -24,8 +26,7 @@ class AcDeviceBatchControlView extends StatelessWidget
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return BlocProvider(
create: (context) => AcBloc(deviceId: devicesIds.first)
..add(AcFetchBatchStatusEvent(devicesIds)),
create: (context) => AcBloc(deviceId: devicesIds.first)..add(AcFetchBatchStatusEvent(devicesIds)),
child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) {
if (state is ACStatusLoaded) {
@ -49,6 +50,7 @@ class AcDeviceBatchControlView extends StatelessWidget
code: 'switch',
value: state.status.acSwitch,
label: 'ThermoState',
icon: Assets.ac,
onChange: (value) {
context.read<AcBloc>().add(AcBatchControlEvent(
devicesIds: devicesIds,
@ -62,6 +64,7 @@ class AcDeviceBatchControlView extends StatelessWidget
tempSet: state.status.tempSet,
code: 'temp_set',
devicesIds: devicesIds,
isBatch: true,
),
BatchAcMode(
value: state.status.acMode,
@ -73,13 +76,60 @@ class AcDeviceBatchControlView extends StatelessWidget
code: 'level',
devicesIds: devicesIds,
),
ToggleWidget(
label: '',
labelWidget: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
onPressed: () {},
icon: const Icon(
Icons.remove,
size: 28,
color: ColorsManager.greyColor,
),
),
Text(
'06',
style: context.textTheme.titleLarge!.copyWith(
color: ColorsManager.dialogBlueTitle,
fontWeight: FontWeight.bold,
),
),
Text(
'h',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
),
Text(
'30',
style: context.textTheme.titleLarge!.copyWith(
color: ColorsManager.dialogBlueTitle,
fontWeight: FontWeight.bold,
),
),
Text('m', style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor)),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.add,
size: 28,
color: ColorsManager.greyColor,
),
),
],
),
value: false,
code: 'ac_schedule',
deviceId: devicesIds.first,
icon: Assets.acSchedule,
onChange: (value) {},
),
ToggleWidget(
deviceId: devicesIds.first,
code: 'child_lock',
value: state.status.childLock,
label: 'Child Lock',
icon:
state.status.childLock ? Assets.childLock : Assets.unlock,
icon: state.status.childLock ? Assets.acLock : Assets.unlock,
onChange: (value) {
context.read<AcBloc>().add(AcBatchControlEvent(
devicesIds: devicesIds,
@ -89,7 +139,14 @@ class AcDeviceBatchControlView extends StatelessWidget
},
),
FirmwareUpdateWidget(deviceId: devicesIds.first, version: 5),
FactoryResetWidget(deviceId: devicesIds.first),
FactoryResetWidget(
callFactoryReset: () {
context.read<AcBloc>().add(AcFactoryResetEvent(
deviceId: state.status.uuid,
factoryResetModel: FactoryResetModel(devicesUuid: devicesIds),
));
},
),
],
);
} else if (state is AcsLoadingState) {

View File

@ -4,11 +4,13 @@ import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_state.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/ac_mode.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/ac_toggle.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/current_temp.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/fan_speed.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_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';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
@ -22,8 +24,7 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return BlocProvider(
create: (context) => AcBloc(deviceId: device.uuid!)
..add(AcFetchDeviceStatusEvent(device.uuid!)),
create: (context) => AcBloc(deviceId: device.uuid!)..add(AcFetchDeviceStatusEvent(device.uuid!)),
child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) {
if (state is ACStatusLoaded) {
@ -39,13 +40,24 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
: 1,
mainAxisExtent: 140,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
mainAxisSpacing: 16,
),
children: [
AcToggle(
ToggleWidget(
label: 'Thermostat',
value: state.status.acSwitch,
code: 'switch',
deviceId: device.uuid!,
icon: Assets.ac,
onChange: (value) {
context.read<AcBloc>().add(
AcControlEvent(
deviceId: device.uuid!,
code: 'switch',
value: value,
),
);
},
),
CurrentTemp(
currentTemp: state.status.currentTemp,
@ -63,13 +75,71 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
code: 'level',
deviceId: device.uuid!,
),
AcToggle(
value: state.status.childLock,
code: 'child_lock',
ToggleWidget(
label: '',
labelWidget: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
padding: const EdgeInsets.all(0),
onPressed: () {},
icon: const Icon(
Icons.remove,
size: 28,
color: ColorsManager.greyColor,
),
),
Text(
'06',
style: context.textTheme.titleLarge!.copyWith(
color: ColorsManager.dialogBlueTitle,
fontWeight: FontWeight.bold,
),
),
Text(
'h',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
),
Text(
'30',
style: context.textTheme.titleLarge!.copyWith(
color: ColorsManager.dialogBlueTitle,
fontWeight: FontWeight.bold,
),
),
Text('m', style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor)),
IconButton(
padding: const EdgeInsets.all(0),
onPressed: () {},
icon: const Icon(
Icons.add,
size: 28,
color: ColorsManager.greyColor,
),
),
],
),
value: false,
code: 'ac_schedule',
deviceId: device.uuid!,
description: 'Child Lock',
icon:
state.status.childLock ? Assets.childLock : Assets.unlock,
icon: Assets.acSchedule,
onChange: (value) {},
),
ToggleWidget(
deviceId: device.uuid!,
code: 'child_lock',
value: state.status.childLock,
label: 'Lock',
icon: state.status.childLock ? Assets.acLock : Assets.unlock,
onChange: (value) {
context.read<AcBloc>().add(
AcControlEvent(
deviceId: device.uuid!,
code: 'child_lock',
value: value,
),
);
},
),
],
);

View File

@ -1,11 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class BatchAcMode extends StatelessWidget {
const BatchAcMode({
@ -21,30 +22,20 @@ class BatchAcMode extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(16),
return DeviceControlsContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildIconContainer(context, TempModes.cold, Assets.freezing,
value == TempModes.cold),
_buildIconContainer(
context, TempModes.hot, Assets.acSun, value == TempModes.hot),
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner,
value == TempModes.wind),
_buildIconContainer(context, TempModes.cold, Assets.freezing, value == TempModes.cold),
_buildIconContainer(context, TempModes.hot, Assets.acSun, value == TempModes.hot),
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner, value == TempModes.wind),
],
),
);
}
Widget _buildIconContainer(
BuildContext context, TempModes mode, String assetPath, bool isSelected) {
Widget _buildIconContainer(BuildContext context, TempModes mode, String assetPath, bool isSelected) {
return Flexible(
child: GestureDetector(
onTap: () {

View File

@ -1,11 +1,13 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/shared/celciuse_symbol.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/pages/device_managment/shared/increament_decreament.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
class BatchCurrentTemp extends StatefulWidget {
const BatchCurrentTemp({
@ -14,12 +16,14 @@ class BatchCurrentTemp extends StatefulWidget {
required this.devicesIds,
required this.currentTemp,
required this.tempSet,
this.isBatch,
});
final String code;
final List<String> devicesIds;
final int currentTemp;
final int tempSet;
final bool? isBatch;
@override
State<BatchCurrentTemp> createState() => _CurrentTempState();
@ -67,49 +71,39 @@ class _CurrentTempState extends State<BatchCurrentTemp> {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(16),
return DeviceControlsContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Current Temperature',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.grey),
),
const SizedBox(
height: 5,
),
Row(
children: [
Text(
(widget.currentTemp > 99
? widget.currentTemp / 10
: widget.currentTemp)
.toString(),
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.grey),
),
const CelsiusSymbol(
color: Colors.grey,
)
],
),
],
),
widget.isBatch == true
? Text(
'Set Temperature',
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
)
: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Current Temperature',
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
),
const SizedBox(
height: 5,
),
Row(
children: [
Text(
(widget.currentTemp > 99 ? widget.currentTemp / 10 : widget.currentTemp).toString(),
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
),
const CelsiusSymbol(
color: Colors.grey,
)
],
),
],
),
const Spacer(),
IncrementDecrementWidget(
value: _adjustedValue.toString(),
@ -118,7 +112,7 @@ class _CurrentTempState extends State<BatchCurrentTemp> {
onIncrement: () {
if (_adjustedValue < 30) {
setState(() {
_adjustedValue++;
_adjustedValue = _adjustedValue + 0.5;
});
_onValueChanged(_adjustedValue);
}
@ -126,7 +120,7 @@ class _CurrentTempState extends State<BatchCurrentTemp> {
onDecrement: () {
if (_adjustedValue > 20) {
setState(() {
_adjustedValue--;
_adjustedValue = _adjustedValue - 0.5;
});
_onValueChanged(_adjustedValue);
}

View File

@ -1,11 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class BatchFanSpeedControl extends StatelessWidget {
const BatchFanSpeedControl({
@ -21,33 +22,25 @@ class BatchFanSpeedControl extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(8),
return DeviceControlsContainer(
padding: 8,
child: Column(
children: [
Wrap(
runSpacing: 8,
spacing: 8,
children: [
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto,
value == FanSpeeds.auto),
_buildIconContainer(context, FanSpeeds.low, Assets.acFanLow,
value == FanSpeeds.low),
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto, value == FanSpeeds.auto),
_buildIconContainer(context, FanSpeeds.low, Assets.acFanLow, value == FanSpeeds.low),
],
),
const SizedBox(height: 8),
Wrap(
runSpacing: 8,
spacing: 8,
children: [
_buildIconContainer(context, FanSpeeds.middle, Assets.acFanMiddle,
value == FanSpeeds.middle),
_buildIconContainer(context, FanSpeeds.high, Assets.acFanHigh,
value == FanSpeeds.high),
_buildIconContainer(context, FanSpeeds.middle, Assets.acFanMiddle, value == FanSpeeds.middle),
_buildIconContainer(context, FanSpeeds.high, Assets.acFanHigh, value == FanSpeeds.high),
],
)
],
@ -55,8 +48,7 @@ class BatchFanSpeedControl extends StatelessWidget {
);
}
Widget _buildIconContainer(BuildContext context, FanSpeeds speed,
String assetPath, bool isSelected) {
Widget _buildIconContainer(BuildContext context, FanSpeeds speed, String assetPath, bool isSelected) {
return GestureDetector(
onTap: () {
context.read<AcBloc>().add(

View File

@ -1,11 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class AcMode extends StatelessWidget {
const AcMode({
@ -21,30 +22,20 @@ class AcMode extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(16),
return DeviceControlsContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildIconContainer(context, TempModes.cold, Assets.freezing,
value == TempModes.cold),
_buildIconContainer(
context, TempModes.hot, Assets.acSun, value == TempModes.hot),
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner,
value == TempModes.wind),
_buildIconContainer(context, TempModes.cold, Assets.freezing, value == TempModes.cold),
_buildIconContainer(context, TempModes.hot, Assets.acSun, value == TempModes.hot),
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner, value == TempModes.wind),
],
),
);
}
Widget _buildIconContainer(
BuildContext context, TempModes mode, String assetPath, bool isSelected) {
Widget _buildIconContainer(BuildContext context, TempModes mode, String assetPath, bool isSelected) {
return Flexible(
child: GestureDetector(
onTap: () {

View File

@ -1,9 +1,9 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
@ -25,13 +25,7 @@ class AcToggle extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(16),
return DeviceControlsContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -39,16 +33,21 @@ class AcToggle extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipOval(
child: Container(
color: ColorsManager.whiteColors,
child: SvgPicture.asset(
icon ?? Assets.acDevice,
width: 60,
height: 60,
fit: BoxFit.cover,
Container(
width: 60,
height: 60,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: ColorsManager.whiteColors,
),
)),
padding: const EdgeInsets.all(8),
child: ClipOval(
child: SvgPicture.asset(
icon ?? Assets.lightPulp,
fit: BoxFit.contain,
),
),
),
SizedBox(
height: 20,
width: 35,

View File

@ -1,11 +1,13 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/shared/celciuse_symbol.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/pages/device_managment/shared/increament_decreament.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
class CurrentTemp extends StatefulWidget {
const CurrentTemp({
@ -67,13 +69,7 @@ class _CurrentTempState extends State<CurrentTemp> {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(16),
return DeviceControlsContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -83,10 +79,7 @@ class _CurrentTempState extends State<CurrentTemp> {
children: [
Text(
'Current Temperature',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.grey),
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
),
const SizedBox(
height: 5,
@ -94,14 +87,8 @@ class _CurrentTempState extends State<CurrentTemp> {
Row(
children: [
Text(
(widget.currentTemp > 99
? widget.currentTemp / 10
: widget.currentTemp)
.toString(),
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.grey),
(widget.currentTemp > 99 ? widget.currentTemp / 10 : widget.currentTemp).toString(),
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
),
const CelsiusSymbol(
color: Colors.grey,
@ -118,7 +105,7 @@ class _CurrentTempState extends State<CurrentTemp> {
onIncrement: () {
if (_adjustedValue < 30) {
setState(() {
_adjustedValue++;
_adjustedValue = _adjustedValue + 0.5;
});
_onValueChanged(_adjustedValue);
}
@ -126,7 +113,7 @@ class _CurrentTempState extends State<CurrentTemp> {
onDecrement: () {
if (_adjustedValue > 20) {
setState(() {
_adjustedValue--;
_adjustedValue = _adjustedValue - 0.5;
});
_onValueChanged(_adjustedValue);
}

View File

@ -1,11 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class FanSpeedControl extends StatelessWidget {
const FanSpeedControl({
@ -21,33 +22,24 @@ class FanSpeedControl extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(8),
return DeviceControlsContainer(
child: Column(
children: [
Wrap(
runSpacing: 8,
spacing: 8,
children: [
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto,
value == FanSpeeds.auto),
_buildIconContainer(context, FanSpeeds.low, Assets.acFanLow,
value == FanSpeeds.low),
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto, value == FanSpeeds.auto),
_buildIconContainer(context, FanSpeeds.low, Assets.acFanLow, value == FanSpeeds.low),
],
),
const SizedBox(height: 8),
Wrap(
runSpacing: 8,
spacing: 8,
children: [
_buildIconContainer(context, FanSpeeds.middle, Assets.acFanMiddle,
value == FanSpeeds.middle),
_buildIconContainer(context, FanSpeeds.high, Assets.acFanHigh,
value == FanSpeeds.high),
_buildIconContainer(context, FanSpeeds.middle, Assets.acFanMiddle, value == FanSpeeds.middle),
_buildIconContainer(context, FanSpeeds.high, Assets.acFanHigh, value == FanSpeeds.high),
],
)
],
@ -55,8 +47,7 @@ class FanSpeedControl extends StatelessWidget {
);
}
Widget _buildIconContainer(BuildContext context, FanSpeeds speed,
String assetPath, bool isSelected) {
Widget _buildIconContainer(BuildContext context, FanSpeeds speed, String assetPath, bool isSelected) {
return GestureDetector(
onTap: () {
context.read<AcBloc>().add(

View File

@ -15,7 +15,9 @@ class DeviceManagementBloc
int _lowBatteryCount = 0;
List<AllDevicesModel> _selectedDevices = [];
List<AllDevicesModel> _filteredDevices = [];
String productName = '';
String currentProductName = '';
String? currentCommunity;
String? currentUnitName;
DeviceManagementBloc() : super(DeviceManagementInitial()) {
on<FetchDevices>(_onFetchDevices);
@ -25,6 +27,7 @@ class DeviceManagementBloc
on<SelectDevice>(_onSelectDevice);
on<ResetFilters>(_onResetFilters);
on<ResetSelectedDevices>(_onResetSelectedDevices);
on<UpdateSelection>(_onUpdateSelection);
}
Future<void> _onFetchDevices(
@ -76,15 +79,15 @@ class DeviceManagementBloc
isControlButtonEnabled: _selectedDevices.isNotEmpty,
));
if (productName.isNotEmpty) {
add(SearchDevices(productName: productName));
if (currentProductName.isNotEmpty) {
add(SearchDevices(productName: currentProductName));
}
}
}
Future<void> _onResetFilters(
ResetFilters event, Emitter<DeviceManagementState> emit) async {
productName = '';
currentProductName = '';
_selectedDevices.clear();
_filteredDevices = List.from(_devices);
_selectedIndex = 0;
@ -172,6 +175,48 @@ class DeviceManagementBloc
}
}
void _onUpdateSelection(
UpdateSelection event, Emitter<DeviceManagementState> emit) {
List<AllDevicesModel> selectedDevices = [];
List<AllDevicesModel> devicesToSelectFrom = [];
if (state is DeviceManagementLoaded) {
devicesToSelectFrom = (state as DeviceManagementLoaded).devices;
} else if (state is DeviceManagementFiltered) {
devicesToSelectFrom = (state as DeviceManagementFiltered).filteredDevices;
}
for (int i = 0; i < event.selectedRows.length; i++) {
if (event.selectedRows[i]) {
selectedDevices.add(devicesToSelectFrom[i]);
}
}
if (state is DeviceManagementLoaded) {
final loadedState = state as DeviceManagementLoaded;
emit(DeviceManagementLoaded(
devices: loadedState.devices,
selectedIndex: loadedState.selectedIndex,
onlineCount: loadedState.onlineCount,
offlineCount: loadedState.offlineCount,
lowBatteryCount: loadedState.lowBatteryCount,
selectedDevice: selectedDevices,
isControlButtonEnabled: _checkIfControlButtonEnabled(selectedDevices),
));
} else if (state is DeviceManagementFiltered) {
final filteredState = state as DeviceManagementFiltered;
emit(DeviceManagementFiltered(
filteredDevices: filteredState.filteredDevices,
selectedIndex: filteredState.selectedIndex,
onlineCount: filteredState.onlineCount,
offlineCount: filteredState.offlineCount,
lowBatteryCount: filteredState.lowBatteryCount,
selectedDevice: selectedDevices,
isControlButtonEnabled: _checkIfControlButtonEnabled(selectedDevices),
));
}
}
bool _checkIfControlButtonEnabled(List<AllDevicesModel> selectedDevices) {
if (selectedDevices.length > 1) {
final productTypes =
@ -210,32 +255,42 @@ class DeviceManagementBloc
if ((event.community == null || event.community!.isEmpty) &&
(event.unitName == null || event.unitName!.isEmpty) &&
(event.productName == null || event.productName!.isEmpty)) {
productName = '';
currentProductName = '';
if (state is DeviceManagementFiltered) {
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
} else {
return;
}
}
productName = event.productName ?? '';
if (event.productName == currentProductName &&
event.community == currentCommunity &&
event.unitName == currentUnitName &&
event.searchField) {
return;
}
currentProductName = event.productName ?? '';
currentCommunity = event.community;
currentUnitName = event.unitName;
List<AllDevicesModel> devicesToSearch = _filteredDevices;
if (devicesToSearch.isNotEmpty) {
_selectedDevices.clear();
_selectedIndex = _selectedIndex;
final filteredDevices = devicesToSearch.where((device) {
final matchesCommunity = event.community == null ||
event.community!.isEmpty ||
(device.room?.name
(device.community?.name
?.toLowerCase()
.contains(event.community!.toLowerCase()) ??
false);
final matchesUnit = event.unitName == null ||
event.unitName!.isEmpty ||
(device.unit?.name
?.toLowerCase()
.contains(event.unitName!.toLowerCase()) ??
false);
(device.spaces != null &&
device.spaces!.isNotEmpty &&
device.spaces![0].spaceName
!.toLowerCase()
.contains(event.unitName!.toLowerCase()));
final matchesProductName = event.productName == null ||
event.productName!.isEmpty ||
(device.name

View File

@ -31,11 +31,13 @@ class SearchDevices extends DeviceManagementEvent {
final String? community;
final String? unitName;
final String? productName;
final bool searchField;
const SearchDevices({
this.community,
this.unitName,
this.productName,
this.searchField = false,
});
@override
@ -54,3 +56,9 @@ class SelectDevice extends DeviceManagementEvent {
class ResetFilters extends DeviceManagementEvent {}
class ResetSelectedDevices extends DeviceManagementEvent {}
class UpdateSelection extends DeviceManagementEvent {
final List<bool> selectedRows;
const UpdateSelection(this.selectedRows);
}

View File

@ -9,18 +9,35 @@ import 'package:syncrow_web/pages/device_managment/curtain/view/curtain_batch_st
import 'package:syncrow_web/pages/device_managment/curtain/view/curtain_status_view.dart';
import 'package:syncrow_web/pages/device_managment/door_lock/view/door_lock_batch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/door_lock/view/door_lock_control_view.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/view/garage_door_batch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/view/garage_door_control_view.dart';
import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_batch_control.dart';
import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_sensor_batch_view.dart';
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_batch_control.dart';
import 'package:syncrow_web/pages/device_managment/one_gang_switch/view/wall_light_device_control.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/view/power_clamp_batch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/view/smart_power_device_control.dart';
import 'package:syncrow_web/pages/device_managment/sos/view/sos_batch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/sos/view/sos_device_control_view.dart';
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_batch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/view/three_gang_glass_switch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart';
import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_device_control.dart';
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_batch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/view/two_gang_glass_switch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_batch_control.dart';
import 'package:syncrow_web/pages/device_managment/two_gang_switch/view/wall_light_device_control.dart';
import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart';
import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_batch_control.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_device_control.dart';
import 'package:syncrow_web/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart';
import 'package:syncrow_web/pages/device_managment/water_leak/view/water_leak_control_view.dart';
import '../../one_g_glass_switch/view/one_gang_glass_switch_control_view.dart';
mixin RouteControlsBasedCode {
Widget routeControlsWidgets({required AllDevicesModel device}) {
@ -37,6 +54,18 @@ mixin RouteControlsBasedCode {
return LivingRoomDeviceControlsView(
deviceId: device.uuid!,
);
case '1GT':
return OneGangGlassSwitchControlView(
deviceId: device.uuid!,
);
case '2GT':
return TwoGangGlassSwitchControlView(
deviceId: device.uuid!,
);
case '3GT':
return ThreeGangGlassSwitchControlView(
deviceId: device.uuid!,
);
case 'GW':
return GateWayControlsView(
gatewayId: device.uuid!,
@ -56,11 +85,25 @@ mixin RouteControlsBasedCode {
case 'AC':
return AcDeviceControlsView(device: device);
case 'WH':
return WaterHeaterDeviceControl(
return WaterHeaterDeviceControlView(
device: device,
);
case 'DS':
return MainDoorSensorControlView(device: device);
case 'GD':
return GarageDoorControlView(
deviceId: device.uuid!,
);
case 'WL':
return WaterLeakView(
deviceId: device.uuid!,
);
case 'PC':
return SmartPowerDeviceControl(
deviceId: device.uuid!,
);
case 'SOS':
return SosDeviceControlsView(device: device);
default:
return const SizedBox();
}
@ -75,71 +118,82 @@ mixin RouteControlsBasedCode {
WPS:
CPS:
AC:
CUR:
CUR:
WH:
DS:
*/
Widget routeBatchControlsWidgets({required List<AllDevicesModel> devices}) {
switch (devices.first.productType) {
case '1G':
return WallLightBatchControlView(
deviceIds: devices
.where((e) => (e.productType == '1G'))
.map((e) => e.uuid!)
.toList(),
deviceIds: devices.where((e) => (e.productType == '1G')).map((e) => e.uuid!).toList(),
);
case '2G':
return TwoGangBatchControlView(
deviceIds: devices
.where((e) => (e.productType == '2G'))
.map((e) => e.uuid!)
.toList(),
deviceIds: devices.where((e) => (e.productType == '2G')).map((e) => e.uuid!).toList(),
);
case '3G':
return LivingRoomBatchControlsView(
deviceIds: devices
.where((e) => (e.productType == '3G'))
.map((e) => e.uuid!)
.toList(),
deviceIds: devices.where((e) => (e.productType == '3G')).map((e) => e.uuid!).toList(),
);
case '1GT':
return OneGangGlassSwitchBatchControlView(
deviceIds: devices.where((e) => (e.productType == '1GT')).map((e) => e.uuid!).toList(),
);
case '2GT':
return TwoGangGlassSwitchBatchControlView(
deviceIds: devices.where((e) => (e.productType == '2GT')).map((e) => e.uuid!).toList(),
);
case '3GT':
return ThreeGangGlassSwitchBatchControlView(
deviceIds: devices.where((e) => (e.productType == '3GT')).map((e) => e.uuid!).toList(),
);
case 'GW':
return GatewayBatchControlView(
gatewayIds: devices
.where((e) => (e.productType == 'GW'))
.map((e) => e.uuid!)
.toList(),
gatewayIds: devices.where((e) => (e.productType == 'GW')).map((e) => e.uuid!).toList(),
);
case 'DL':
return DoorLockBatchControlView(
devicesIds: devices
.where((e) => (e.productType == 'DL'))
.map((e) => e.uuid!)
.toList());
devicesIds: devices.where((e) => (e.productType == 'DL')).map((e) => e.uuid!).toList());
case 'WPS':
return WallSensorBatchControlView(
devicesIds: devices
.where((e) => (e.productType == 'WPS'))
.map((e) => e.uuid!)
.toList());
devicesIds: devices.where((e) => (e.productType == 'WPS')).map((e) => e.uuid!).toList());
case 'CPS':
return CeilingSensorBatchControlView(
devicesIds: devices
.where((e) => (e.productType == 'CPS'))
.map((e) => e.uuid!)
.toList(),
devicesIds: devices.where((e) => (e.productType == 'CPS')).map((e) => e.uuid!).toList(),
);
case 'CUR':
return CurtainBatchStatusView(
devicesIds: devices
.where((e) => (e.productType == 'CUR'))
.map((e) => e.uuid!)
.toList(),
devicesIds: devices.where((e) => (e.productType == 'CUR')).map((e) => e.uuid!).toList(),
);
case 'AC':
return AcDeviceBatchControlView(
devicesIds: devices
.where((e) => (e.productType == 'AC'))
.map((e) => e.uuid!)
.toList());
devicesIds: devices.where((e) => (e.productType == 'AC')).map((e) => e.uuid!).toList());
case 'WH':
return WaterHEaterBatchControlView(
deviceIds: devices.where((e) => (e.productType == 'WH')).map((e) => e.uuid!).toList(),
);
case 'DS':
return MainDoorSensorBatchView(
devicesIds: devices.where((e) => (e.productType == 'DS')).map((e) => e.uuid!).toList(),
);
case 'GD':
return GarageDoorBatchControlView(
deviceIds: devices.where((e) => (e.productType == 'GD')).map((e) => e.uuid!).toList(),
);
case 'WL':
return WaterLeakBatchControlView(
deviceIds: devices.where((e) => (e.productType == 'WL')).map((e) => e.uuid!).toList(),
);
case 'PC':
return PowerClampBatchControlView(
deviceIds: devices.where((e) => (e.productType == 'PC')).map((e) => e.uuid!).toList(),
);
case 'SOS':
return SOSBatchControlView(
deviceIds: devices.where((e) => (e.productType == 'SOS')).map((e) => e.uuid!).toList(),
);
default:
return const SizedBox();
}

View File

@ -0,0 +1,18 @@
class DeviceCommunityModel {
String? uuid;
String? name;
DeviceCommunityModel({this.uuid, this.name});
DeviceCommunityModel.fromJson(Map<String, dynamic> json) {
uuid = json['uuid']?.toString();
name = json['name']?.toString();
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['uuid'] = uuid;
data['name'] = name;
return data;
}
}

View File

@ -0,0 +1,18 @@
class DeviceSpaceModel {
String? uuid;
String? spaceName;
DeviceSpaceModel({this.uuid, this.spaceName});
DeviceSpaceModel.fromJson(Map<String, dynamic> json) {
uuid = json['uuid']?.toString();
spaceName = json['spaceName']?.toString();
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['uuid'] = uuid;
data['spaceName'] = spaceName;
return data;
}
}

View File

@ -1,3 +1,5 @@
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_community.model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_space_model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
@ -40,6 +42,7 @@ class AllDevicesModel {
DevicesModelRoom? room;
DevicesModelUnit? unit;
DeviceCommunityModel? community;
String? productUuid;
String? productType;
String? permissionType;
@ -63,10 +66,13 @@ class AllDevicesModel {
int? updateTime;
String? uuid;
int? batteryLevel;
String? productName;
List<DeviceSpaceModel>? spaces;
AllDevicesModel({
this.room,
this.unit,
this.community,
this.productUuid,
this.productType,
this.permissionType,
@ -90,6 +96,8 @@ class AllDevicesModel {
this.updateTime,
this.uuid,
this.batteryLevel,
this.productName,
this.spaces,
});
AllDevicesModel.fromJson(Map<String, dynamic> json) {
room = (json['room'] != null && (json['room'] is Map))
@ -98,6 +106,9 @@ class AllDevicesModel {
unit = (json['unit'] != null && (json['unit'] is Map))
? DevicesModelUnit.fromJson(json['unit'])
: null;
community = (json['community'] != null && (json['community'] is Map))
? DeviceCommunityModel.fromJson(json['community'])
: null;
productUuid = json['productUuid']?.toString();
productType = json['productType']?.toString();
permissionType = json['permissionType']?.toString();
@ -121,6 +132,12 @@ class AllDevicesModel {
updateTime = int.tryParse(json['updateTime']?.toString() ?? '');
uuid = json['uuid']?.toString();
batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
productName = json['productName']?.toString();
if (json['spaces'] != null && json['spaces'] is List) {
spaces = (json['spaces'] as List)
.map((space) => DeviceSpaceModel.fromJson(space))
.toList();
}
}
String _getDefaultIcon(String? productType) {
@ -159,6 +176,9 @@ class AllDevicesModel {
if (unit != null) {
data['unit'] = unit!.toJson();
}
if (community != null) {
data['community'] = community!.toJson();
}
data['productUuid'] = productUuid;
data['productType'] = productType;
data['permissionType'] = permissionType;
@ -182,6 +202,10 @@ class AllDevicesModel {
data['updateTime'] = updateTime;
data['uuid'] = uuid;
data['battery'] = batteryLevel;
data['productName'] = productName;
if (spaces != null) {
data['spaces'] = spaces!.map((space) => space.toJson()).toList();
}
return data;
}
@ -214,6 +238,7 @@ class AllDevicesModel {
other.timeZone == timeZone &&
other.updateTime == updateTime &&
other.uuid == uuid &&
other.productName == productName &&
other.batteryLevel == batteryLevel;
}
@ -243,6 +268,7 @@ class AllDevicesModel {
timeZone.hashCode ^
updateTime.hashCode ^
uuid.hashCode ^
productName.hashCode ^
batteryLevel.hashCode;
}
}

View File

@ -0,0 +1,55 @@
import 'package:flutter/foundation.dart';
class FactoryResetModel {
final List<String> devicesUuid;
FactoryResetModel({
required this.devicesUuid,
});
factory FactoryResetModel.fromJson(Map<String, dynamic> json) {
return FactoryResetModel(
devicesUuid: List<String>.from(json['devicesUuid']),
);
}
Map<String, dynamic> toJson() {
return {
'devicesUuid': devicesUuid,
};
}
FactoryResetModel copyWith({
List<String>? devicesUuid,
}) {
return FactoryResetModel(
devicesUuid: devicesUuid ?? this.devicesUuid,
);
}
Map<String, dynamic> toMap() {
return {
'devicesUuid': devicesUuid,
};
}
factory FactoryResetModel.fromMap(Map<String, dynamic> map) {
return FactoryResetModel(
devicesUuid: List<String>.from(map['devicesUuid']),
);
}
@override
String toString() => 'FactoryReset(devicesUuid: $devicesUuid)';
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is FactoryResetModel &&
listEquals(other.devicesUuid, devicesUuid);
}
@override
int get hashCode => devicesUuid.hashCode;
}

View File

@ -1,14 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/common/custom_table.dart';
import 'package:syncrow_web/pages/common/filter/filter_widget.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_managment_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_control_dialog.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_search_filters.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_control_dialog.dart';
import 'package:syncrow_web/utils/format_date_time.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
import 'package:syncrow_web/utils/style.dart';
@ -37,8 +36,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
offlineCount = state.offlineCount;
lowBatteryCount = state.lowBatteryCount;
isControlButtonEnabled = state.isControlButtonEnabled;
selectedDevices = state.selectedDevice ??
context.read<DeviceManagementBloc>().selectedDevices;
selectedDevices = state.selectedDevice ?? [];
} else if (state is DeviceManagementFiltered) {
devicesToShow = state.filteredDevices;
selectedIndex = state.selectedIndex;
@ -46,14 +44,12 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
offlineCount = state.offlineCount;
lowBatteryCount = state.lowBatteryCount;
isControlButtonEnabled = state.isControlButtonEnabled;
selectedDevices = state.selectedDevice ??
context.read<DeviceManagementBloc>().selectedDevices;
selectedDevices = state.selectedDevice ?? [];
} else if (state is DeviceManagementInitial) {
devicesToShow = [];
selectedIndex = 0;
isControlButtonEnabled = false;
}
final tabs = [
'All',
'Online ($onlineCount)',
@ -88,7 +84,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
const SizedBox(height: 12),
Container(
height: 45,
width: 100,
width: 125,
decoration: containerDecoration,
child: Center(
child: DefaultButton(
@ -120,6 +116,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
borderRadius: 9,
child: Text(
buttonLabel,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
color: isControlButtonEnabled
@ -148,26 +145,39 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
.add(SelectDevice(selectedDevice));
},
withCheckBox: true,
size: context.screenSize,
size: MediaQuery.of(context).size,
uuidIndex: 2,
headers: const [
'Device Name',
'Product Name',
'Device ID',
'Unit Name',
'Room',
'Space Name',
'location',
'Battery Level',
'Installation Date and Time',
'Status',
'Last Offline Date and Time',
],
data: devicesToShow.map((device) {
final combinedSpaceNames = device.spaces != null
? device.spaces!
.map((space) => space.spaceName)
.join(' > ') +
(device.community != null
? ' > ${device.community!.name}'
: '')
: (device.community != null
? device.community!.name
: '');
return [
device.categoryName ?? '',
device.name ?? '',
device.productName ?? '',
device.uuid ?? '',
device.unit?.name ?? '',
device.room?.name ?? '',
(device.spaces != null && device.spaces!.isNotEmpty)
? device.spaces![0].spaceName
: '',
combinedSpaceNames,
device.batteryLevel != null
? '${device.batteryLevel}%'
: '-',
@ -178,6 +188,11 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
(device.updateTime ?? 0) * 1000)),
];
}).toList(),
onSelectionChanged: (selectedRows) {
context
.read<DeviceManagementBloc>()
.add(UpdateSelection(selectedRows));
},
initialSelectedIds: context
.read<DeviceManagementBloc>()
.selectedDevices

View File

@ -4,6 +4,7 @@ import 'package:syncrow_web/pages/common/text_field/custom_text_field.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_managment_bloc.dart';
import 'package:syncrow_web/pages/common/buttons/search_reset_buttons.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
import 'package:syncrow_web/utils/style.dart';
class DeviceSearchFilters extends StatefulWidget {
const DeviceSearchFilters({super.key});
@ -33,7 +34,7 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
children: [
_buildSearchField("Community", communityController, 200),
const SizedBox(width: 20),
_buildSearchField("Unit Name", unitNameController, 200),
_buildSearchField("Space Name", unitNameController, 200),
const SizedBox(width: 20),
_buildSearchField(
"Device Name / Product Name", productNameController, 300),
@ -45,10 +46,17 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
spacing: 20,
runSpacing: 10,
children: [
_buildSearchField("Community", communityController, 200),
_buildSearchField("Unit Name", unitNameController, 200),
_buildSearchField(
"Device Name / Product Name", productNameController, 300),
"Community",
communityController,
200,
),
_buildSearchField("Space Name", unitNameController, 200),
_buildSearchField(
"Device Name / Product Name",
productNameController,
300,
),
_buildSearchResetButtons(),
],
);
@ -56,11 +64,20 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
Widget _buildSearchField(
String title, TextEditingController controller, double width) {
return StatefulTextField(
title: title,
width: width,
elevation: 2,
controller: controller,
return Container(
child: StatefulTextField(
title: title,
width: width,
elevation: 2,
controller: controller,
onSubmitted: () {
context.read<DeviceManagementBloc>().add(SearchDevices(
productName: productNameController.text,
unitName: unitNameController.text,
community: communityController.text,
searchField: true));
},
),
);
}
@ -68,10 +85,10 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
return SearchResetButtons(
onSearch: () {
context.read<DeviceManagementBloc>().add(SearchDevices(
community: communityController.text,
unitName: unitNameController.text,
productName: productNameController.text,
));
community: communityController.text,
unitName: unitNameController.text,
productName: productNameController.text,
searchField: true));
},
onReset: () {
communityController.clear();

View File

@ -1,8 +1,9 @@
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/event.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/state.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_state.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/help_description.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
@ -20,14 +21,14 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
on<GetCeilingDeviceReportsEvent>(_getDeviceReports);
on<ShowCeilingDescriptionEvent>(_showDescription);
on<BackToCeilingGridViewEvent>(_backToGridView);
on<CeilingFactoryResetEvent>(_onFactoryReset);
}
void _fetchCeilingSensorStatus(
CeilingInitialEvent event, Emitter<CeilingSensorState> emit) async {
emit(CeilingLoadingInitialState());
try {
var response = await DevicesManagementApi()
.getDeviceStatus(event.deviceId);
var response = await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = CeilingSensorModel.fromJson(response.status);
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
// _listenToChanges();
@ -56,8 +57,7 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
// } catch (_) {}
// }
void _changeValue(
CeilingChangeValueEvent event, Emitter<CeilingSensorState> emit) async {
void _changeValue(CeilingChangeValueEvent event, Emitter<CeilingSensorState> emit) async {
emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus));
if (event.code == 'sensitivity') {
deviceStatus.sensitivity = event.value;
@ -122,8 +122,7 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
try {
late bool response;
if (isBatch) {
response = await DevicesManagementApi()
.deviceBatchControl(deviceId, code, value);
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
} else {
response = await DevicesManagementApi()
.deviceControl(deviceId, Status(code: code, value: value));
@ -144,17 +143,19 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
});
}
FutureOr<void> _getDeviceReports(GetCeilingDeviceReportsEvent event,
Emitter<CeilingSensorState> emit) async {
FutureOr<void> _getDeviceReports(
GetCeilingDeviceReportsEvent event, Emitter<CeilingSensorState> emit) async {
if (event.code.isEmpty) {
emit(ShowCeilingDescriptionState(description: reportString));
return;
} else {
emit(CeilingReportsLoadingState());
// final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
// final to = DateTime.now().millisecondsSinceEpoch;
try {
await DevicesManagementApi.getDeviceReports(deviceId, event.code)
.then((value) {
// await DevicesManagementApi.getDeviceReportsByDate(deviceId, event.code, from.toString(), to.toString())
await DevicesManagementApi.getDeviceReports(deviceId, event.code).then((value) {
emit(CeilingReportsState(deviceReport: value));
});
} catch (e) {
@ -164,23 +165,19 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
}
}
void _showDescription(
ShowCeilingDescriptionEvent event, Emitter<CeilingSensorState> emit) {
void _showDescription(ShowCeilingDescriptionEvent event, Emitter<CeilingSensorState> emit) {
emit(ShowCeilingDescriptionState(description: event.description));
}
void _backToGridView(
BackToCeilingGridViewEvent event, Emitter<CeilingSensorState> emit) {
void _backToGridView(BackToCeilingGridViewEvent event, Emitter<CeilingSensorState> emit) {
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
}
FutureOr<void> _fetchCeilingSensorBatchControl(
CeilingFetchDeviceStatusEvent event,
Emitter<CeilingSensorState> emit) async {
CeilingFetchDeviceStatusEvent event, Emitter<CeilingSensorState> emit) async {
emit(CeilingLoadingInitialState());
try {
var response =
await DevicesManagementApi().getBatchStatus(event.devicesIds);
var response = await DevicesManagementApi().getBatchStatus(event.devicesIds);
deviceStatus = CeilingSensorModel.fromJson(response.status);
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
} catch (e) {
@ -188,4 +185,22 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
return;
}
}
FutureOr<void> _onFactoryReset(
CeilingFactoryResetEvent event, Emitter<CeilingSensorState> emit) async {
emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus));
try {
final response = await DevicesManagementApi().factoryReset(
event.factoryResetModel,
event.devicesId,
);
if (!response) {
emit(const CeilingFailedState(error: 'Failed'));
} else {
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
}
} catch (e) {
emit(CeilingFailedState(error: e.toString()));
}
}
}

View File

@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
abstract class CeilingSensorEvent extends Equatable {
const CeilingSensorEvent();
@ -69,3 +70,16 @@ class ShowCeilingDescriptionEvent extends CeilingSensorEvent {
}
class BackToCeilingGridViewEvent extends CeilingSensorEvent {}
class CeilingFactoryResetEvent extends CeilingSensorEvent {
final String devicesId;
final FactoryResetModel factoryResetModel;
const CeilingFactoryResetEvent({
required this.devicesId,
required this.factoryResetModel,
});
@override
List<Object> get props => [devicesId, factoryResetModel];
}

View File

@ -46,22 +46,19 @@ class CeilingSensorModel {
_spaceType = getSpaceType(status.value ?? 'none');
break;
case 'sensitivity':
_sensitivity = status.value is int
? status.value
: int.tryParse(status.value ?? '1') ?? 1;
_sensitivity =
status.value is int ? status.value : int.tryParse(status.value ?? '1') ?? 1;
break;
case 'checking_result':
_checkingResult = status.value ?? '';
break;
case 'presence_range':
_presenceRange = status.value is int
? status.value
: int.tryParse(status.value ?? '0') ?? 0;
_presenceRange =
status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0;
break;
case 'sports_para':
_sportsPara = status.value is int
? status.value
: int.tryParse(status.value ?? '0') ?? 0;
_sportsPara =
status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0;
break;
case 'body_movement':
_bodyMovement = status.value ?? '';
@ -70,9 +67,7 @@ class CeilingSensorModel {
_noBodyTime = status.value ?? 'none';
break;
case 'moving_max_dis':
_maxDis = status.value is int
? status.value
: int.tryParse(status.value ?? '0') ?? 0;
_maxDis = status.value is int ? status.value : int.tryParse(status.value ?? '0') ?? 0;
break;
}
}

View File

@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/bloc.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/event.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/state.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_state.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
@ -11,8 +12,7 @@ import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presen
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class CeilingSensorBatchControlView extends StatelessWidget
with HelperResponsiveLayout {
class CeilingSensorBatchControlView extends StatelessWidget with HelperResponsiveLayout {
const CeilingSensorBatchControlView({super.key, required this.devicesIds});
final List<String> devicesIds;
@ -27,12 +27,11 @@ class CeilingSensorBatchControlView extends StatelessWidget
..add(CeilingFetchDeviceStatusEvent(devicesIds)),
child: BlocBuilder<CeilingSensorBloc, CeilingSensorState>(
builder: (context, state) {
if (state is CeilingLoadingInitialState ||
state is CeilingReportsLoadingState) {
if (state is CeilingLoadingInitialState || state is CeilingReportsLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is CeilingUpdateState) {
return _buildGridView(context, state.ceilingSensorModel,
isExtraLarge, isLarge, isMedium);
return _buildGridView(
context, state.ceilingSensorModel, isExtraLarge, isLarge, isMedium);
}
return const Center(child: Text('Error fetching status'));
},
@ -40,8 +39,8 @@ class CeilingSensorBatchControlView extends StatelessWidget
);
}
Widget _buildGridView(BuildContext context, CeilingSensorModel model,
bool isExtraLarge, bool isLarge, bool isMedium) {
Widget _buildGridView(BuildContext context, CeilingSensorModel model, bool isExtraLarge,
bool isLarge, bool isMedium) {
return GridView(
padding: const EdgeInsets.symmetric(horizontal: 50),
shrinkWrap: true,
@ -72,7 +71,7 @@ class CeilingSensorBatchControlView extends StatelessWidget
value: model.sensitivity.toDouble(),
title: 'Sensitivity:',
minValue: 1,
maxValue: 5,
maxValue: 10,
steps: 1,
action: (int value) {
context.read<CeilingSensorBloc>().add(
@ -112,7 +111,16 @@ class CeilingSensorBatchControlView extends StatelessWidget
),
),
FirmwareUpdateWidget(deviceId: devicesIds.first, version: 4),
FactoryResetWidget(deviceId: devicesIds.first),
FactoryResetWidget(
callFactoryReset: () {
context.read<CeilingSensorBloc>().add(
CeilingFactoryResetEvent(
devicesId: devicesIds.first,
factoryResetModel: FactoryResetModel(devicesUuid: devicesIds),
),
);
},
),
],
);
}

View File

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/bloc.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/event.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/state.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_event.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_state.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_display_data.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_space_type.dart';
@ -16,8 +16,7 @@ import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dar
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class CeilingSensorControlsView extends StatelessWidget
with HelperResponsiveLayout {
class CeilingSensorControlsView extends StatelessWidget with HelperResponsiveLayout {
const CeilingSensorControlsView({super.key, required this.device});
final AllDevicesModel device;
@ -32,35 +31,29 @@ class CeilingSensorControlsView extends StatelessWidget
..add(CeilingInitialEvent(device.uuid ?? '')),
child: BlocBuilder<CeilingSensorBloc, CeilingSensorState>(
builder: (context, state) {
if (state is CeilingLoadingInitialState ||
state is CeilingReportsLoadingState) {
if (state is CeilingLoadingInitialState || state is CeilingReportsLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is CeilingUpdateState) {
return _buildGridView(context, state.ceilingSensorModel,
isExtraLarge, isLarge, isMedium);
return _buildGridView(
context, state.ceilingSensorModel, isExtraLarge, isLarge, isMedium);
} else if (state is CeilingReportsState) {
return ReportsTable(
report: state.deviceReport,
onRowTap: (index) {},
onClose: () {
context
.read<CeilingSensorBloc>()
.add(BackToCeilingGridViewEvent());
context.read<CeilingSensorBloc>().add(BackToCeilingGridViewEvent());
},
);
} else if (state is ShowCeilingDescriptionState) {
return DescriptionView(
description: state.description,
onClose: () {
context
.read<CeilingSensorBloc>()
.add(BackToCeilingGridViewEvent());
context.read<CeilingSensorBloc>().add(BackToCeilingGridViewEvent());
},
);
} else if (state is CeilingReportsFailedState) {
final model = context.read<CeilingSensorBloc>().deviceStatus;
return _buildGridView(
context, model, isExtraLarge, isLarge, isMedium);
return _buildGridView(context, model, isExtraLarge, isLarge, isMedium);
}
return const Center(child: Text('Error fetching status'));
},
@ -68,8 +61,8 @@ class CeilingSensorControlsView extends StatelessWidget
);
}
Widget _buildGridView(BuildContext context, CeilingSensorModel model,
bool isExtraLarge, bool isLarge, bool isMedium) {
Widget _buildGridView(BuildContext context, CeilingSensorModel model, bool isExtraLarge,
bool isLarge, bool isMedium) {
return GridView(
padding: const EdgeInsets.symmetric(horizontal: 50),
shrinkWrap: true,
@ -112,7 +105,7 @@ class CeilingSensorControlsView extends StatelessWidget
value: model.sensitivity.toDouble(),
title: 'Sensitivity:',
minValue: 1,
maxValue: 5,
maxValue: 10,
steps: 1,
action: (int value) {
context.read<CeilingSensorBloc>().add(
@ -150,8 +143,8 @@ class CeilingSensorControlsView extends StatelessWidget
),
GestureDetector(
onTap: () {
context.read<CeilingSensorBloc>().add(GetCeilingDeviceReportsEvent(
code: 'presence_state', deviceUuid: device.uuid!));
context.read<CeilingSensorBloc>().add(
GetCeilingDeviceReportsEvent(code: 'presence_state', deviceUuid: device.uuid!));
},
child: const PresenceStaticWidget(
icon: Assets.illuminanceRecordIcon,
@ -160,8 +153,9 @@ class CeilingSensorControlsView extends StatelessWidget
),
GestureDetector(
onTap: () {
context.read<CeilingSensorBloc>().add(GetCeilingDeviceReportsEvent(
code: '', deviceUuid: device.uuid!));
context
.read<CeilingSensorBloc>()
.add(GetCeilingDeviceReportsEvent(code: '', deviceUuid: device.uuid!));
},
child: const PresenceStaticWidget(
icon: Assets.helpDescriptionIcon,

View File

@ -15,6 +15,7 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
on<CurtainFetchBatchStatus>(_onFetchBatchStatus);
on<CurtainControl>(_onCurtainControl);
on<CurtainBatchControl>(_onCurtainBatchControl);
on<CurtainFactoryReset>(_onFactoryReset);
}
FutureOr<void> _onFetchDeviceStatus(
@ -139,4 +140,22 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
isBatch: true,
);
}
FutureOr<void> _onFactoryReset(
CurtainFactoryReset event, Emitter<CurtainState> emit) async {
emit(CurtainStatusLoading());
try {
final response = await DevicesManagementApi().factoryReset(
event.factoryReset,
event.deviceId,
);
if (!response) {
emit(const CurtainControlError('Failed'));
} else {
add(CurtainFetchDeviceStatus(event.deviceId));
}
} catch (e) {
emit(CurtainControlError(e.toString()));
}
}
}

View File

@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
sealed class CurtainEvent extends Equatable {
const CurtainEvent();
@ -48,3 +49,14 @@ class CurtainBatchControl extends CurtainEvent {
@override
List<Object> get props => [devicesIds, code, value];
}
class CurtainFactoryReset extends CurtainEvent {
final String deviceId;
final FactoryResetModel factoryReset;
const CurtainFactoryReset(
{required this.deviceId, required this.factoryReset});
@override
List<Object> get props => [deviceId, factoryReset];
}

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/curtain_toggle.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_bloc.dart';
import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart';
import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_state.dart';
@ -68,7 +69,16 @@ class CurtainBatchStatusView extends StatelessWidget
},
),
FirmwareUpdateWidget(deviceId: devicesIds.first, version: 5),
FactoryResetWidget(deviceId: devicesIds.first),
FactoryResetWidget(
callFactoryReset: () {
context.read<CurtainBloc>().add(
CurtainFactoryReset(
deviceId: devicesIds.first,
factoryReset: FactoryResetModel(devicesUuid: devicesIds),
),
);
},
),
],
);
}

View File

@ -17,6 +17,7 @@ class DoorLockBloc extends Bloc<DoorLockEvent, DoorLockState> {
on<DoorLockFetchStatus>(_onFetchDeviceStatus);
//on<DoorLockControl>(_onDoorLockControl);
on<UpdateLockEvent>(_updateLock);
on<DoorLockFactoryReset>(_onFactoryReset);
}
FutureOr<void> _onFetchDeviceStatus(
@ -113,4 +114,22 @@ class DoorLockBloc extends Bloc<DoorLockEvent, DoorLockState> {
return null;
}
}
FutureOr<void> _onFactoryReset(
DoorLockFactoryReset event, Emitter<DoorLockState> emit) async {
emit(DoorLockStatusLoading());
try {
final response = await DevicesManagementApi().factoryReset(
event.factoryReset,
event.deviceId,
);
if (!response) {
emit(const DoorLockControlError('Failed'));
} else {
add(DoorLockFetchStatus(event.deviceId));
}
} catch (e) {
emit(DoorLockControlError(e.toString()));
}
}
}

View File

@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
sealed class DoorLockEvent extends Equatable {
const DoorLockEvent();
@ -38,4 +39,15 @@ class UpdateLockEvent extends DoorLockEvent {
List<Object> get props => [value];
}
class DoorLockFactoryReset extends DoorLockEvent {
final String deviceId;
final FactoryResetModel factoryReset;
const DoorLockFactoryReset({
required this.deviceId,
required this.factoryReset,
});
@override
List<Object> get props => [deviceId, factoryReset];
}

View File

@ -1,4 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_bloc.dart';
import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_event.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
@ -11,28 +15,35 @@ class DoorLockBatchControlView extends StatelessWidget
@override
Widget build(BuildContext context) {
final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return SizedBox(
child: GridView(
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge || isExtraLarge || isMedium ? 2 : 1,
mainAxisExtent: 140,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
children: [
FirmwareUpdateWidget(
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 170,
height: 140,
child: FirmwareUpdateWidget(
deviceId: devicesIds.first,
version: 12,
),
FactoryResetWidget(deviceId: devicesIds.first),
],
),
),
const SizedBox(
width: 12,
),
SizedBox(
width: 170,
height: 140,
child: FactoryResetWidget(
callFactoryReset: () {
BlocProvider.of<DoorLockBloc>(context).add(
DoorLockFactoryReset(
deviceId: devicesIds.first,
factoryReset: FactoryResetModel(devicesUuid: devicesIds),
),
);
},
),
),
],
);
}
}

View File

@ -0,0 +1,423 @@
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
import 'package:syncrow_web/utils/format_date_time.dart';
class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorState> {
final String deviceId;
late GarageDoorStatusModel deviceStatus;
Timer? _timer;
GarageDoorBloc({required this.deviceId}) : super(GarageDoorInitialState()) {
on<GarageDoorInitialEvent>(_fetchGarageDoorStatus);
on<GarageDoorControlEvent>(_garageDoorControlEvent);
on<AddGarageDoorScheduleEvent>(_addSchedule);
on<UpdateGarageDoorScheduleEvent>(_updateSchedule);
on<DeleteGarageDoorScheduleEvent>(_deleteSchedule);
on<FetchGarageDoorSchedulesEvent>(_fetchSchedules);
on<IncreaseGarageDoorDelayEvent>(_increaseDelay);
on<DecreaseGarageDoorDelayEvent>(_decreaseDelay);
on<FetchGarageDoorRecordsEvent>(_fetchRecords);
on<GarageDoorUpdatedEvent>(_handleUpdate);
on<UpdateSelectedTimeEvent>(_updateSelectedTime);
on<UpdateSelectedDayEvent>(_updateSelectedDay);
on<UpdateFunctionOnEvent>(_updateFunctionOn);
on<InitializeAddScheduleEvent>(_initializeAddSchedule);
on<BackToGarageDoorGridViewEvent>(_backToGridView);
on<UpdateCountdownAlarmEvent>(_onUpdateCountdownAlarm);
on<UpdateTrTimeConEvent>(_onUpdateTrTimeCon);
on<GarageDoorBatchControlEvent>(_onBatchControl);
on<GarageDoorFetchBatchStatusEvent>(_onFetchBatchStatus);
on<GarageDoorFactoryResetEvent>(_onFactoryReset);
on<EditGarageDoorScheduleEvent>(_onEditSchedule);
}
void _fetchGarageDoorStatus(GarageDoorInitialEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
var response = await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = GarageDoorStatusModel.fromJson(deviceId, response.status);
emit(GarageDoorLoadedState(status: deviceStatus));
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
}
}
Future<void> _onFetchBatchStatus(GarageDoorFetchBatchStatusEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
deviceStatus = GarageDoorStatusModel.fromJson(event.deviceIds.first, status.status);
emit(GarageDoorBatchStatusLoaded(deviceStatus));
} catch (e) {
emit(GarageDoorBatchControlError(e.toString()));
}
}
Future<void> _addSchedule(AddGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try {
ScheduleEntry newSchedule = ScheduleEntry(
category: event.category,
time: formatTimeOfDayToISO(event.time),
function: Status(code: 'switch_1', value: event.functionOn),
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
);
bool success = await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
if (success) {
add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
}
void _onUpdateCountdownAlarm(UpdateCountdownAlarmEvent event, Emitter<GarageDoorState> emit) {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
status: currentState.status.copyWith(countdownAlarm: event.countdownAlarm),
));
}
}
void _onUpdateTrTimeCon(UpdateTrTimeConEvent event, Emitter<GarageDoorState> emit) {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
status: currentState.status.copyWith(trTimeCon: event.trTimeCon),
));
}
}
Future<void> _updateSchedule(UpdateGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try {
final updatedSchedules = deviceStatus.schedules?.map((schedule) {
if (schedule.scheduleId == event.scheduleId) {
return schedule.copyWith(
function: Status(code: 'switch_1', value: event.functionOn),
enable: event.enable,
);
}
return schedule;
}).toList();
bool success = await DevicesManagementApi().updateScheduleRecord(
enable: event.enable,
uuid: deviceStatus.uuid,
scheduleId: event.scheduleId,
);
if (success) {
deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules);
emit(GarageDoorLoadedState(status: deviceStatus));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
}
Future<void> _deleteSchedule(DeleteGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try {
bool success = await DevicesManagementApi().deleteScheduleRecord(deviceStatus.uuid, event.scheduleId);
if (success) {
final updatedSchedules =
deviceStatus.schedules?.where((schedule) => schedule.scheduleId != event.scheduleId).toList();
deviceStatus = deviceStatus.copyWith(schedules: updatedSchedules);
emit(GarageDoorLoadedState(status: deviceStatus));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
}
Future<void> _fetchSchedules(FetchGarageDoorSchedulesEvent event, Emitter<GarageDoorState> emit) async {
emit(ScheduleGarageLoadingState());
try {
List<ScheduleModel> schedules =
await DevicesManagementApi().getDeviceSchedules(deviceStatus.uuid, event.category);
deviceStatus = deviceStatus.copyWith(schedules: schedules);
emit(
GarageDoorLoadedState(
status: deviceStatus,
scheduleMode: ScheduleModes.schedule,
),
);
} catch (e) {
emit(
GarageDoorLoadedState(
status: deviceStatus,
scheduleMode: ScheduleModes.schedule,
),
);
}
}
Future<void> _updateSelectedTime(UpdateSelectedTimeEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(selectedTime: event.selectedTime));
}
}
Future<void> _updateSelectedDay(UpdateSelectedDayEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
List<bool> updatedDays = List.from(currentState.selectedDays);
updatedDays[event.dayIndex] = event.isSelected;
emit(currentState.copyWith(selectedDays: updatedDays, selectedTime: currentState.selectedTime));
}
}
Future<void> _updateFunctionOn(UpdateFunctionOnEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(functionOn: event.functionOn, selectedTime: currentState.selectedTime));
}
}
Future<void> _initializeAddSchedule(InitializeAddScheduleEvent event, Emitter<GarageDoorState> emit) async {
final currentState = state;
if (currentState is GarageDoorLoadedState) {
emit(currentState.copyWith(
selectedTime: event.selectedTime,
selectedDays: event.selectedDays,
functionOn: event.functionOn,
isEditing: event.isEditing,
));
}
}
Future<void> _fetchRecords(FetchGarageDoorRecordsEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorReportsLoadingState());
try {
final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
final to = DateTime.now().millisecondsSinceEpoch;
final DeviceReport records =
await DevicesManagementApi.getDeviceReportsByDate(event.deviceId, 'switch_1', from.toString(), to.toString());
emit(GarageDoorReportsState(deviceReport: records));
} catch (e) {
emit(GarageDoorReportsFailedState(error: e.toString()));
}
}
Future<void> _onBatchControl(GarageDoorBatchControlEvent event, Emitter<GarageDoorState> emit) async {
final oldValue = event.code == 'switch_1' ? deviceStatus.switch1 : false;
_updateLocalValue(event.code, event.value);
emit(GarageDoorBatchStatusLoaded(deviceStatus));
final success = await _runDeBouncer(
deviceId: event.deviceIds,
code: event.code,
value: event.value,
oldValue: oldValue,
emit: emit,
isBatch: true,
);
if (!success) {
_revertValue(event.code, oldValue, emit);
}
}
void _backToGridView(BackToGarageDoorGridViewEvent event, Emitter<GarageDoorState> emit) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
void _handleUpdate(GarageDoorUpdatedEvent event, Emitter<GarageDoorState> emit) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
Future<bool> _runDeBouncer({
required dynamic deviceId,
required String code,
required dynamic value,
required dynamic oldValue,
required Emitter<GarageDoorState> emit,
required bool isBatch,
}) async {
try {
late bool status;
await Future.delayed(const Duration(milliseconds: 500));
if (isBatch) {
status = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
} else {
status = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
}
if (!status) {
_revertValue(code, oldValue, emit);
return false;
} else {
return true;
}
} catch (e) {
_revertValue(code, oldValue, emit);
return false;
}
}
Future<void> _onFactoryReset(GarageDoorFactoryResetEvent event, Emitter<GarageDoorState> emit) async {
emit(GarageDoorLoadingState());
try {
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
if (!response) {
emit(const GarageDoorErrorState(message: 'Failed to reset device'));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
}
}
void _increaseDelay(IncreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
// if (deviceStatus.countdown1 != 0) {
try {
deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay + Duration(minutes: 10));
emit(GarageDoorLoadedState(status: deviceStatus));
add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1'));
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
}
// }
}
void _decreaseDelay(DecreaseGarageDoorDelayEvent event, Emitter<GarageDoorState> emit) async {
// if (deviceStatus.countdown1 != 0) {
try {
if (deviceStatus.delay.inMinutes > 10) {
deviceStatus = deviceStatus.copyWith(delay: deviceStatus.delay - Duration(minutes: 10));
}
emit(GarageDoorLoadedState(status: deviceStatus));
add(GarageDoorControlEvent(deviceId: event.deviceId, value: deviceStatus.delay.inSeconds, code: 'countdown_1'));
} catch (e) {
emit(GarageDoorErrorState(message: e.toString()));
}
//}
}
void _garageDoorControlEvent(GarageDoorControlEvent event, Emitter<GarageDoorState> emit) async {
final oldValue = event.code == 'countdown_1' ? deviceStatus.countdown1 : deviceStatus.switch1;
_updateLocalValue(event.code, event.value);
emit(GarageDoorLoadedState(status: deviceStatus));
final success = await _runDeBouncer(
deviceId: event.deviceId,
code: event.code,
value: event.value,
oldValue: oldValue,
emit: emit,
isBatch: false,
);
if (!success) {
_revertValue(event.code, oldValue, emit);
}
}
void _revertValue(String code, dynamic oldValue, Emitter<GarageDoorState> emit) {
switch (code) {
case 'switch_1':
if (oldValue is bool) {
deviceStatus = deviceStatus.copyWith(switch1: oldValue);
}
break;
case 'countdown_1':
if (oldValue is int) {
deviceStatus = deviceStatus.copyWith(countdown1: oldValue, delay: Duration(seconds: oldValue));
}
break;
// Add other cases if needed
default:
break;
}
if (state is GarageDoorLoadedState) {
final currentState = state as GarageDoorLoadedState;
emit(currentState.copyWith(status: deviceStatus));
}
}
void _updateLocalValue(String code, dynamic value) {
switch (code) {
case 'switch_1':
if (value is bool) {
deviceStatus = deviceStatus.copyWith(switch1: value);
}
break;
case 'countdown_1':
if (value is int) {
deviceStatus = deviceStatus.copyWith(countdown1: value, delay: Duration(seconds: value));
}
break;
case 'countdown_alarm':
if (value is int) {
deviceStatus = deviceStatus.copyWith(countdownAlarm: value);
}
break;
case 'tr_timecon':
if (value is int) {
deviceStatus = deviceStatus.copyWith(trTimeCon: value);
}
break;
case 'door_state_1':
if (value is String) {
deviceStatus = deviceStatus.copyWith(doorState1: value);
}
break;
case 'door_control_1':
if (value is String) {
deviceStatus = deviceStatus.copyWith(doorControl1: value);
}
break;
case 'voice_control_1':
if (value is bool) {
deviceStatus = deviceStatus.copyWith(voiceControl1: value);
}
break;
case 'door_contact_state':
if (value is bool) {
deviceStatus = deviceStatus.copyWith(doorContactState: value);
}
default:
break;
}
}
@override
Future<void> close() {
_timer?.cancel();
return super.close();
}
FutureOr<void> _onEditSchedule(EditGarageDoorScheduleEvent event, Emitter<GarageDoorState> emit) async {
try {
ScheduleEntry newSchedule = ScheduleEntry(
scheduleId: event.scheduleId,
category: event.category,
time: formatTimeOfDayToISO(event.time),
function: Status(code: 'switch_1', value: event.functionOn),
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
);
bool success = await DevicesManagementApi().editScheduleRecord(deviceId, newSchedule);
if (success) {
add(FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
} catch (e) {
emit(GarageDoorLoadedState(status: deviceStatus));
}
}
}

View File

@ -0,0 +1,234 @@
// lib/pages/device_managment/garage_door/bloc/event.dart
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
abstract class GarageDoorEvent extends Equatable {
const GarageDoorEvent();
@override
List<Object?> get props => [];
}
class GarageDoorInitialEvent extends GarageDoorEvent {
final String deviceId;
const GarageDoorInitialEvent(this.deviceId);
@override
List<Object?> get props => [deviceId];
}
class GarageDoorControlEvent extends GarageDoorEvent {
final String deviceId;
final dynamic value;
final String code;
const GarageDoorControlEvent({required this.deviceId, required this.value, required this.code});
@override
List<Object?> get props => [deviceId, value];
}
class AddGarageDoorScheduleEvent extends GarageDoorEvent {
final String category;
final TimeOfDay time;
final bool functionOn;
final List<bool> selectedDays;
const AddGarageDoorScheduleEvent({
required this.category,
required this.time,
required this.functionOn,
required this.selectedDays,
});
}
class EditGarageDoorScheduleEvent extends GarageDoorEvent {
final String scheduleId;
final String category;
final TimeOfDay time;
final bool functionOn;
final List<bool> selectedDays;
const EditGarageDoorScheduleEvent({
required this.scheduleId,
required this.category,
required this.time,
required this.functionOn,
required this.selectedDays,
});
}
class UpdateGarageDoorScheduleEvent extends GarageDoorEvent {
final String deviceId;
final String scheduleId;
final bool enable;
final bool functionOn;
final int index;
const UpdateGarageDoorScheduleEvent({
required this.deviceId,
required this.scheduleId,
required this.enable,
required this.functionOn,
required this.index,
});
}
class DeleteGarageDoorScheduleEvent extends GarageDoorEvent {
final String deviceId;
final String scheduleId;
final int index;
const DeleteGarageDoorScheduleEvent({
required this.deviceId,
required this.scheduleId,
required this.index,
});
}
class FetchGarageDoorSchedulesEvent extends GarageDoorEvent {
final String deviceId;
final String category;
const FetchGarageDoorSchedulesEvent({
required this.deviceId,
required this.category,
});
}
class IncreaseGarageDoorDelayEvent extends GarageDoorEvent {
final String deviceId;
const IncreaseGarageDoorDelayEvent({required this.deviceId});
@override
List<Object?> get props => [deviceId];
}
class DecreaseGarageDoorDelayEvent extends GarageDoorEvent {
final String deviceId;
const DecreaseGarageDoorDelayEvent({required this.deviceId});
@override
List<Object?> get props => [deviceId];
}
class FetchGarageDoorRecordsEvent extends GarageDoorEvent {
final String deviceId;
final String code;
const FetchGarageDoorRecordsEvent({required this.deviceId, required this.code});
@override
List<Object?> get props => [deviceId, code];
}
class BackToGarageDoorGridViewEvent extends GarageDoorEvent {}
class GarageDoorUpdatedEvent extends GarageDoorEvent {}
class UpdateSelectedTimeEvent extends GarageDoorEvent {
final TimeOfDay? selectedTime;
const UpdateSelectedTimeEvent(this.selectedTime);
@override
List<Object?> get props => [selectedTime];
}
class UpdateSelectedDayEvent extends GarageDoorEvent {
final int dayIndex;
final bool isSelected;
const UpdateSelectedDayEvent(this.dayIndex, this.isSelected);
@override
List<Object?> get props => [dayIndex, isSelected];
}
class UpdateFunctionOnEvent extends GarageDoorEvent {
final bool functionOn;
const UpdateFunctionOnEvent({required this.functionOn});
@override
List<Object?> get props => [functionOn];
}
class InitializeAddScheduleEvent extends GarageDoorEvent {
final TimeOfDay? selectedTime;
final List<bool> selectedDays;
final bool functionOn;
final bool isEditing;
final int? index;
const InitializeAddScheduleEvent({
required this.selectedTime,
required this.selectedDays,
required this.functionOn,
required this.isEditing,
this.index,
});
@override
List<Object?> get props => [
selectedTime,
selectedDays,
functionOn,
isEditing,
index,
];
}
class UpdateCountdownAlarmEvent extends GarageDoorEvent {
final int countdownAlarm;
const UpdateCountdownAlarmEvent(this.countdownAlarm);
}
class UpdateTrTimeConEvent extends GarageDoorEvent {
final int trTimeCon;
const UpdateTrTimeConEvent(this.trTimeCon);
}
class GarageDoorBatchControlEvent extends GarageDoorEvent {
final List<String> deviceIds;
final String code;
final bool value;
const GarageDoorBatchControlEvent({
required this.deviceIds,
required this.code,
required this.value,
});
@override
List<Object?> get props => [deviceIds, code, value];
}
class GarageDoorFetchBatchStatusEvent extends GarageDoorEvent {
final List<String> deviceIds;
const GarageDoorFetchBatchStatusEvent(this.deviceIds);
@override
List<Object?> get props => [deviceIds];
}
class GarageDoorFactoryResetEvent extends GarageDoorEvent {
final FactoryResetModel factoryReset;
final String deviceId;
const GarageDoorFactoryResetEvent({
required this.factoryReset,
required this.deviceId,
});
@override
List<Object?> get props => [factoryReset, deviceId];
}

View File

@ -0,0 +1,141 @@
// lib/pages/device_managment/garage_door/bloc/state.dart
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart';
abstract class GarageDoorState extends Equatable {
const GarageDoorState();
@override
List<Object?> get props => [];
}
class GarageDoorInitialState extends GarageDoorState {}
class GarageDoorLoadingState extends GarageDoorState {}
class GarageDoorLoadedState extends GarageDoorState {
final GarageDoorStatusModel status;
final Duration? delay;
final DeviceReport? records;
final List<bool> selectedDays;
final TimeOfDay? selectedTime;
final bool functionOn;
final bool isEditing;
final ScheduleModes? scheduleMode;
const GarageDoorLoadedState({
required this.status,
this.delay,
this.records,
this.selectedDays = const [false, false, false, false, false, false, false],
this.selectedTime,
this.functionOn = false,
this.isEditing = false,
this.scheduleMode = ScheduleModes.schedule,
});
@override
List<Object?> get props => [
status,
delay,
records,
selectedDays,
selectedTime,
functionOn,
isEditing,
scheduleMode,
];
GarageDoorLoadedState copyWith({
GarageDoorStatusModel? status,
Duration? delay,
DeviceReport? records,
List<bool>? selectedDays,
TimeOfDay? selectedTime,
bool? functionOn,
bool? isEditing,
ScheduleModes? scheduleMode,
}) {
return GarageDoorLoadedState(
status: status ?? this.status,
delay: delay ?? this.delay,
records: records ?? this.records,
selectedDays: selectedDays ?? this.selectedDays,
selectedTime: selectedTime,
functionOn: functionOn ?? this.functionOn,
isEditing: isEditing ?? this.isEditing,
scheduleMode: scheduleMode ?? this.scheduleMode,
);
}
}
class GarageDoorErrorState extends GarageDoorState {
final String message;
const GarageDoorErrorState({required this.message});
@override
List<Object?> get props => [message];
}
class GarageDoorLoadingNewState extends GarageDoorState {
final GarageDoorStatusModel garageDoorModel;
const GarageDoorLoadingNewState({required this.garageDoorModel});
@override
List<Object?> get props => [garageDoorModel];
}
class GarageDoorReportsLoadingState extends GarageDoorState {}
class GarageDoorReportsFailedState extends GarageDoorState {
final String error;
const GarageDoorReportsFailedState({required this.error});
@override
List<Object?> get props => [error];
}
class GarageDoorReportsState extends GarageDoorState {
final DeviceReport deviceReport;
const GarageDoorReportsState({required this.deviceReport});
@override
List<Object?> get props => [deviceReport];
}
class ShowGarageDoorDescriptionState extends GarageDoorState {
final String description;
const ShowGarageDoorDescriptionState({required this.description});
@override
List<Object?> get props => [description];
}
class ScheduleGarageLoadingState extends GarageDoorState {}
class GarageDoorBatchStatusLoaded extends GarageDoorState {
final GarageDoorStatusModel status;
const GarageDoorBatchStatusLoaded(this.status);
@override
List<Object?> get props => [status];
}
class GarageDoorBatchControlError extends GarageDoorState {
final String message;
const GarageDoorBatchControlError(this.message);
@override
List<Object?> get props => [message];
}

View File

@ -0,0 +1,385 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/opening_clsoing_time_dialog_body.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/time_out_alarm_dialog_body.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_display_data.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class GarageDoorDialogHelper {
static void showAddGarageDoorScheduleDialog(BuildContext context,
{ScheduleModel? schedule, int? index, bool? isEdit}) {
final bloc = context.read<GarageDoorBloc>();
if (schedule == null) {
bloc.add((const UpdateSelectedTimeEvent(null)));
bloc.add(InitializeAddScheduleEvent(
selectedTime: null,
selectedDays: List.filled(7, false),
functionOn: false,
isEditing: false,
));
} else {
final time = _convertStringToTimeOfDay(schedule.time);
final selectedDays = _convertDaysStringToBooleans(schedule.days);
bloc.add(InitializeAddScheduleEvent(
selectedTime: time,
selectedDays: selectedDays,
functionOn: schedule.function.value,
isEditing: true,
index: index,
));
}
showDialog(
context: context,
builder: (ctx) {
return BlocProvider.value(
value: bloc,
child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
builder: (context, state) {
if (state is GarageDoorLoadedState) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
Text(
'Scheduling',
style: context.textTheme.titleLarge!.copyWith(
color: ColorsManager.dialogBlueTitle,
fontWeight: FontWeight.bold,
),
),
const SizedBox(),
],
),
const SizedBox(height: 24),
SizedBox(
width: 150,
height: 40,
child: DefaultButton(
padding: 8,
backgroundColor: ColorsManager.boxColor,
borderRadius: 15,
onPressed: () async {
TimeOfDay? time = await showTimePicker(
context: context,
initialTime: state.selectedTime ?? TimeOfDay.now(),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: const ColorScheme.light(
primary: ColorsManager.primaryColor,
),
),
child: child!,
);
},
);
if (time != null) {
bloc.add(UpdateSelectedTimeEvent(time));
}
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
state.selectedTime == null ? 'Time' : state.selectedTime!.format(context),
style: context.textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,
),
),
const Icon(
Icons.access_time,
color: ColorsManager.grayColor,
size: 18,
),
],
),
),
),
const SizedBox(height: 16),
_buildDayCheckboxes(context, state.selectedDays, isEdit: isEdit),
const SizedBox(height: 16),
_buildFunctionSwitch(context, state.functionOn, isEdit),
],
),
actions: [
SizedBox(
width: 200,
child: DefaultButton(
height: 40,
onPressed: () {
Navigator.pop(context);
},
backgroundColor: ColorsManager.boxColor,
child: Text(
'Cancel',
style: context.textTheme.bodyMedium,
),
),
),
SizedBox(
width: 200,
child: DefaultButton(
height: 40,
onPressed: () {
if (state.selectedTime != null) {
if (state.isEditing && index != null) {
bloc.add(EditGarageDoorScheduleEvent(
scheduleId: schedule?.scheduleId ?? '',
category: 'switch_1',
time: state.selectedTime!,
selectedDays: state.selectedDays,
functionOn: state.functionOn,
));
} else {
bloc.add(AddGarageDoorScheduleEvent(
category: 'switch_1',
time: state.selectedTime!,
selectedDays: state.selectedDays,
functionOn: state.functionOn,
));
}
Navigator.pop(context);
}
},
backgroundColor: ColorsManager.primaryColor,
child: const Text('Save'),
),
),
],
);
}
return const SizedBox();
},
),
);
},
);
}
static TimeOfDay _convertStringToTimeOfDay(String timeString) {
final regex = RegExp(r'^(\d{2}):(\d{2})$');
final match = regex.firstMatch(timeString);
if (match != null) {
final hour = int.parse(match.group(1)!);
final minute = int.parse(match.group(2)!);
return TimeOfDay(hour: hour, minute: minute);
} else {
throw const FormatException('Invalid time format');
}
}
static List<bool> _convertDaysStringToBooleans(List<String> selectedDays) {
final daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
List<bool> daysBoolean = List.filled(7, false);
for (int i = 0; i < daysOfWeek.length; i++) {
if (selectedDays.contains(daysOfWeek[i])) {
daysBoolean[i] = true;
}
}
return daysBoolean;
}
static Widget _buildDayCheckboxes(BuildContext context, List<bool> selectedDays, {bool? isEdit}) {
final dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
return Row(
children: List.generate(7, (index) {
return Row(
children: [
Checkbox(
value: selectedDays[index],
onChanged: (bool? value) {
context.read<GarageDoorBloc>().add(UpdateSelectedDayEvent(index, value!));
},
),
Text(dayLabels[index]),
],
);
}),
);
}
static Widget _buildFunctionSwitch(BuildContext context, bool isOn, bool? isEdit) {
return Row(
children: [
Text(
'Function:',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.grayColor),
),
const SizedBox(width: 10),
Radio<bool>(
value: true,
groupValue: isOn,
onChanged: (bool? value) {
context.read<GarageDoorBloc>().add(const UpdateFunctionOnEvent(functionOn: true));
},
),
const Text('On'),
const SizedBox(width: 10),
Radio<bool>(
value: false,
groupValue: isOn,
onChanged: (bool? value) {
context.read<GarageDoorBloc>().add(const UpdateFunctionOnEvent(functionOn: false));
},
),
const Text('Off'),
],
);
}
static void showPreferencesDialog(BuildContext context) {
final bloc = context.read<GarageDoorBloc>();
showDialog(
context: context,
builder: (ctx) {
return BlocProvider.value(
value: bloc,
child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
builder: (context, state) {
if (state is GarageDoorLoadedState) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
/// The dialog is closed when the user taps on the close button or when the
/// [GarageDoorBloc] state changes.
Text(
'Preferences',
style: context.textTheme.titleLarge!.copyWith(
color: ColorsManager.dialogBlueTitle,
fontWeight: FontWeight.bold,
),
),
const SizedBox(),
],
),
const SizedBox(height: 24),
Row(
children: [
const SizedBox(width: 24),
SizedBox(
width: 190,
height: 150,
child: GestureDetector(
onTap: () {
context.customAlertDialog(
alertBody: TimeOutAlarmDialogBody(bloc),
title: 'Time Out Alarm',
onConfirm: () {
final updatedState = context.read<GarageDoorBloc>().state;
if (updatedState is GarageDoorLoadedState) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId: updatedState.status.uuid,
code: 'countdown_alarm',
value: updatedState.status.countdownAlarm,
),
);
Navigator.pop(context);
}
});
},
child: ToggleWidget(
icon: "-1",
value: state.status.doorState1 == "close_time_alarm" ? false : true,
code: 'door_state_1',
deviceId: bloc.deviceId,
label: 'Alarm when door is open',
onChange: (value) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId: bloc.deviceId,
code: 'door_state_1',
value: state.status.doorState1 == "close_time_alarm"
? "unclosed_time"
: "close_time_alarm",
),
);
}),
),
),
const SizedBox(
width: 20,
),
SizedBox(
width: 190,
height: 150,
child: GestureDetector(
onTap: () {
context.customAlertDialog(
alertBody: OpeningAndClosingTimeDialogBody(
bloc: bloc,
onDurationChanged: (newDuration) {
context.read<GarageDoorBloc>().add(
UpdateTrTimeConEvent(newDuration),
);
},
),
title: 'Opening and Closing Time',
onConfirm: () {
final updatedState = context.read<GarageDoorBloc>().state;
if (updatedState is GarageDoorLoadedState) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId: updatedState.status.uuid,
code: 'tr_timecon',
value: updatedState.status.trTimeCon,
),
);
Navigator.pop(context);
}
});
},
child: PresenceDisplayValue(
value: state.status.trTimeCon.toString(),
postfix: 'sec',
description: 'Opening & Closing Time',
),
),
),
const SizedBox(width: 24),
],
)
],
),
);
}
return const SizedBox();
},
),
);
},
);
}
}

View File

@ -0,0 +1,123 @@
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
class GarageDoorStatusModel {
final String uuid;
final bool switch1;
final int countdown1;
final bool doorContactState;
final int trTimeCon;
final int countdownAlarm;
final String doorControl1;
final bool voiceControl1;
final String doorState1;
// final bool isOpen;
final Duration delay;
final List<ScheduleModel>? schedules; // Add schedules field
GarageDoorStatusModel({
required this.uuid,
required this.switch1,
required this.countdown1,
required this.doorContactState,
required this.trTimeCon,
required this.countdownAlarm,
required this.doorControl1,
required this.voiceControl1,
required this.doorState1,
// required this.isOpen,
required this.delay,
required this.schedules, // Initialize schedules
});
factory GarageDoorStatusModel.fromJson(String id, List<Status> jsonList) {
late bool switch1;
late int countdown1;
late bool doorContactState;
late int trTimeCon;
late int countdownAlarm;
late String doorControl1;
late bool voiceControl1;
late String doorState1;
List<ScheduleModel> schedules = []; // Initialize schedules
for (var status in jsonList) {
switch (status.code) {
case 'switch_1':
switch1 = status.value ?? false;
break;
case 'countdown_1':
countdown1 = status.value ?? 0;
break;
case 'doorcontact_state':
doorContactState = status.value ?? false;
break;
case 'tr_timecon':
trTimeCon = status.value ?? 0;
break;
case 'countdown_alarm':
countdownAlarm = status.value ?? 0;
break;
case 'door_control_1':
doorControl1 = status.value ?? 'closed';
break;
case 'voice_control_1':
voiceControl1 = status.value ?? false;
break;
case 'door_state_1':
doorState1 = status.value ?? 'close_time_alarm';
break;
}
}
return GarageDoorStatusModel(
uuid: id,
switch1: switch1,
countdown1: countdown1,
doorContactState: doorContactState,
trTimeCon: trTimeCon,
countdownAlarm: countdownAlarm,
doorControl1: doorControl1,
voiceControl1: voiceControl1,
doorState1: doorState1,
// isOpen: doorState1 == 'open' ? true : false,
delay: Duration(seconds: countdown1),
schedules: schedules, // Assign schedules
);
}
GarageDoorStatusModel copyWith({
String? uuid,
bool? switch1,
int? countdown1,
bool? doorContactState,
int? trTimeCon,
int? countdownAlarm,
String? doorControl1,
bool? voiceControl1,
String? doorState1,
// bool? isOpen,
Duration? delay,
List<ScheduleModel>? schedules, // Add schedules to copyWith
}) {
return GarageDoorStatusModel(
uuid: uuid ?? this.uuid,
switch1: switch1 ?? this.switch1,
countdown1: countdown1 ?? this.countdown1,
doorContactState: doorContactState ?? this.doorContactState,
trTimeCon: trTimeCon ?? this.trTimeCon,
countdownAlarm: countdownAlarm ?? this.countdownAlarm,
doorControl1: doorControl1 ?? this.doorControl1,
voiceControl1: voiceControl1 ?? this.voiceControl1,
doorState1: doorState1 ?? this.doorState1,
// isOpen: isOpen ?? this.isOpen,
delay: delay ?? this.delay,
schedules: schedules ?? this.schedules, // Copy schedules
);
}
@override
String toString() {
return 'GarageDoorStatusModel(uuid: $uuid, switch1: $switch1, countdown1: $countdown1, doorContactState: $doorContactState, trTimeCon: $trTimeCon, countdownAlarm: $countdownAlarm, doorControl1: $doorControl1, voiceControl1: $voiceControl1, doorState1: $doorState1, delay: $delay, schedules: $schedules)';
}
}

View File

@ -0,0 +1,95 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class GarageDoorBatchControlView extends StatelessWidget
with HelperResponsiveLayout {
final List<String> deviceIds;
const GarageDoorBatchControlView({Key? key, required this.deviceIds})
: super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => GarageDoorBloc(deviceId: deviceIds.first)
..add(GarageDoorFetchBatchStatusEvent(deviceIds)),
child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
builder: (context, state) {
if (state is GarageDoorLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is GarageDoorBatchStatusLoaded) {
return _buildStatusControls(context, state.status);
} else if (state is GarageDoorBatchControlError) {
return Center(child: Text('Error: ${state.message}'));
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
);
}
Widget _buildStatusControls(
BuildContext context, GarageDoorStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return GridView(
padding: const EdgeInsets.symmetric(horizontal: 50),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge || isExtraLarge
? 3
: isMedium
? 2
: 1,
mainAxisExtent: 140,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
children: [
ToggleWidget(
value: status.switch1,
code: 'switch_1',
deviceId: deviceIds.first,
label: 'Garage Door',
icon: status.switch1 ? Assets.openedDoor : Assets.closedDoor,
onChange: (value) {
context.read<GarageDoorBloc>().add(
GarageDoorBatchControlEvent(
deviceIds: deviceIds,
code: 'switch_1',
value: value,
),
);
},
),
FirmwareUpdateWidget(
deviceId: deviceIds.first,
version: 12,
),
FactoryResetWidget(
callFactoryReset: () {
context.read<GarageDoorBloc>().add(
GarageDoorFactoryResetEvent(
deviceId: deviceIds.first,
factoryReset: FactoryResetModel(devicesUuid: deviceIds),
),
);
},
),
],
);
}
}

View File

@ -0,0 +1,188 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/helper/garage_door_helper.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule_garage_view.dart';
import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart';
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_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';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout {
final String deviceId;
const GarageDoorControlView({required this.deviceId, super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => GarageDoorBloc(deviceId: deviceId)..add(GarageDoorInitialEvent(deviceId)),
child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
builder: (context, state) {
if (state is GarageDoorLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is GarageDoorReportsState) {
return ReportsTable(
report: state.deviceReport,
hideValueShowDescription: true,
garageDoorSensor: true,
onRowTap: (index) {},
onClose: () {
context.read<GarageDoorBloc>().add(BackToGarageDoorGridViewEvent());
},
);
} else if (state is GarageDoorLoadedState) {
return _buildControlView(context, state.status);
} else if (state is GarageDoorErrorState) {
return Center(child: Text('Error: ${state.message}'));
}
return const Center(child: Text('Unknown state'));
},
),
);
}
Widget _buildControlView(BuildContext context, GarageDoorStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return GridView(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 50),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge || isExtraLarge
? 3
: isMedium
? 2
: 1,
childAspectRatio: 1.5,
mainAxisExtent: 140,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
children: [
IconNameStatusContainer(
isFullIcon: false,
name: status.switch1 ? 'Opened' : 'Closed',
icon: status.switch1 ? Assets.openedDoor : Assets.closedDoor,
onTap: () {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(deviceId: status.uuid, value: !status.switch1, code: 'switch_1'),
);
},
status: status.switch1,
textColor: ColorsManager.blackColor,
),
IconNameStatusContainer(
onTap: () {
context.read<GarageDoorBloc>().add(
FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'),
);
showDialog(
context: context,
builder: (ctx) => BlocProvider.value(
value: BlocProvider.of<GarageDoorBloc>(context),
child: BuildGarageDoorScheduleView(status: status),
));
},
name: 'Scheduling',
icon: Assets.acSchedule,
status: false,
textColor: ColorsManager.blackColor,
isFullIcon: false,
),
ToggleWidget(
label: '',
labelWidget: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(
onPressed: () {
context.read<GarageDoorBloc>().add(DecreaseGarageDoorDelayEvent(deviceId: status.uuid));
},
icon: const Icon(
Icons.remove,
size: 28,
color: ColorsManager.greyColor,
),
padding: EdgeInsets.zero,
),
Text(
status.delay.inHours.toString().padLeft(2, '0'),
style: context.textTheme.titleLarge!.copyWith(
color: ColorsManager.dialogBlueTitle,
fontWeight: FontWeight.bold,
),
),
Text(
'h',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
),
Text(
(status.delay.inMinutes % 60).toString().padLeft(2, '0'),
style: context.textTheme.titleLarge!.copyWith(
color: ColorsManager.dialogBlueTitle,
fontWeight: FontWeight.bold,
),
),
Text(
'm',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
),
IconButton(
onPressed: () {
context.read<GarageDoorBloc>().add(IncreaseGarageDoorDelayEvent(deviceId: status.uuid));
},
icon: const Icon(
Icons.add,
size: 28,
color: ColorsManager.greyColor,
),
padding: EdgeInsets.zero,
),
],
),
value: status.countdown1 != 0 ? true : false,
code: 'countdown_1',
deviceId: status.uuid,
icon: Assets.doorDelay,
onChange: (value) {
context.read<GarageDoorBloc>().add(
GarageDoorControlEvent(
deviceId: status.uuid, value: value ? status.delay.inSeconds : 0, code: 'countdown_1'),
);
},
),
IconNameStatusContainer(
isFullIcon: false,
name: 'Records',
icon: Assets.records,
onTap: () {
context.read<GarageDoorBloc>().add(FetchGarageDoorRecordsEvent(code: 'switch_1', deviceId: status.uuid));
},
status: false,
textColor: ColorsManager.blackColor,
),
IconNameStatusContainer(
isFullIcon: false,
name: 'Preferences',
icon: Assets.preferences,
onTap: () {
GarageDoorDialogHelper.showPreferencesDialog(context);
},
status: false,
textColor: ColorsManager.blackColor,
),
],
);
}
}

View File

@ -0,0 +1,53 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/seconds_picker.dart';
class OpeningAndClosingTimeDialogBody extends StatefulWidget {
final ValueChanged<int> onDurationChanged;
final GarageDoorBloc bloc;
OpeningAndClosingTimeDialogBody({
required this.onDurationChanged,
required this.bloc,
});
@override
_OpeningAndClosingTimeDialogBodyState createState() =>
_OpeningAndClosingTimeDialogBodyState();
}
class _OpeningAndClosingTimeDialogBodyState
extends State<OpeningAndClosingTimeDialogBody> {
late int durationInSeconds;
@override
void didChangeDependencies() {
super.didChangeDependencies();
final currentState = widget.bloc.state;
if (currentState is GarageDoorLoadedState) {
setState(() {
durationInSeconds = currentState.status.trTimeCon;
});
}
}
@override
Widget build(BuildContext context) {
return Container(
height: 120,
color: Colors.white,
child: SecondsPicker(
initialSeconds: durationInSeconds,
onSecondsChanged: (newSeconds) {
setState(() {
durationInSeconds = newSeconds;
});
widget.onDurationChanged(newSeconds);
},
),
);
}
}

View File

@ -0,0 +1,212 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/helper/garage_door_helper.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.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';
import 'package:syncrow_web/utils/format_date_time.dart';
class ScheduleGarageTableWidget extends StatelessWidget {
final GarageDoorLoadedState state;
const ScheduleGarageTableWidget({
super.key,
required this.state,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Table(
border: TableBorder.all(
color: ColorsManager.graysColor,
borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)),
),
children: [
TableRow(
decoration: const BoxDecoration(
color: ColorsManager.boxColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
children: [
_buildTableHeader('Active'),
_buildTableHeader('Days'),
_buildTableHeader('Time'),
_buildTableHeader('Function'),
_buildTableHeader('Action'),
],
),
],
),
BlocBuilder<GarageDoorBloc, GarageDoorState>(
builder: (context, state) {
if (state is ScheduleGarageLoadingState) {
return const SizedBox(height: 200, child: Center(child: CircularProgressIndicator()));
}
if (state is GarageDoorLoadedState && state.status.schedules?.isEmpty == true) {
return _buildEmptyState(context);
} else if (state is GarageDoorLoadedState) {
return Container(
height: 200,
decoration: BoxDecoration(
border: Border.all(color: ColorsManager.graysColor),
borderRadius:
const BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
),
child: _buildTableBody(state, context));
}
return const SizedBox(
height: 200,
);
},
),
],
);
}
Widget _buildEmptyState(BuildContext context) {
return Container(
height: 200,
decoration: BoxDecoration(
border: Border.all(color: ColorsManager.graysColor),
borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(Assets.emptyRecords, width: 40, height: 40),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'No schedules added yet',
style: context.textTheme.bodySmall!.copyWith(
fontSize: 13,
color: ColorsManager.grayColor,
),
),
),
],
),
),
);
}
Widget _buildTableBody(GarageDoorLoadedState state, BuildContext context) {
return SizedBox(
height: 200,
child: SingleChildScrollView(
child: Table(
border: TableBorder.all(color: ColorsManager.graysColor),
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
if (state.status.schedules != null)
for (int i = 0; i < state.status.schedules!.length; i++)
_buildScheduleRow(state.status.schedules![i], i, context, state),
],
),
),
);
}
Widget _buildTableHeader(String label) {
return TableCell(
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
label,
style: const TextStyle(
fontSize: 13,
color: ColorsManager.grayColor,
),
),
),
);
}
TableRow _buildScheduleRow(ScheduleModel schedule, int index, BuildContext context, GarageDoorLoadedState state) {
return TableRow(
children: [
Center(
child: GestureDetector(
onTap: () {
context.read<GarageDoorBloc>().add(UpdateGarageDoorScheduleEvent(
index: index,
enable: !schedule.enable,
scheduleId: schedule.scheduleId,
deviceId: state.status.uuid,
functionOn: schedule.function.value,
));
},
child: SizedBox(
width: 24,
height: 24,
child: schedule.enable
? const Icon(Icons.radio_button_checked, color: ColorsManager.blueColor)
: const Icon(
Icons.radio_button_unchecked,
color: ColorsManager.grayColor,
),
),
),
),
Center(child: Text(_getSelectedDays(ScheduleModel.parseSelectedDays(schedule.days)))),
Center(child: Text(formatIsoStringToTime(schedule.time, context))),
Center(child: Text(schedule.function.value ? 'On' : 'Off')),
Center(
child: Wrap(
runAlignment: WrapAlignment.center,
children: [
TextButton(
style: TextButton.styleFrom(padding: EdgeInsets.zero),
onPressed: () {
GarageDoorDialogHelper.showAddGarageDoorScheduleDialog(context,
schedule: schedule, index: index, isEdit: true);
},
child: Text(
'Edit',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blueColor),
),
),
TextButton(
style: TextButton.styleFrom(padding: EdgeInsets.zero),
onPressed: () {
context.read<GarageDoorBloc>().add(DeleteGarageDoorScheduleEvent(
index: index,
scheduleId: schedule.scheduleId,
deviceId: state.status.uuid,
));
},
child: Text(
'Delete',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blueColor),
),
),
],
),
),
],
);
}
String _getSelectedDays(List<bool> selectedDays) {
final days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
List<String> selectedDaysStr = [];
for (int i = 0; i < selectedDays.length; i++) {
if (selectedDays[i]) {
selectedDaysStr.add(days[i]);
}
}
return selectedDaysStr.join(', ');
}
}

View File

@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class ScheduleGarageHeader extends StatelessWidget {
const ScheduleGarageHeader({super.key});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
Text(
'Scheduling',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: ColorsManager.dialogBlueTitle,
),
),
Container(
width: 25,
decoration: BoxDecoration(
color: Colors.transparent,
shape: BoxShape.circle,
border: Border.all(
color: Colors.grey,
width: 1.0,
),
),
child: IconButton(
padding: const EdgeInsets.all(1),
icon: const Icon(
Icons.close,
color: Colors.grey,
size: 18,
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
],
);
}
}

View File

@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule__garage_table.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class ScheduleGarageManagementUI extends StatelessWidget {
final GarageDoorLoadedState state;
final Function onAddSchedule;
const ScheduleGarageManagementUI({
super.key,
required this.state,
required this.onAddSchedule,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 170,
height: 40,
child: DefaultButton(
borderColor: ColorsManager.boxColor,
padding: 2,
backgroundColor: ColorsManager.graysColor,
borderRadius: 15,
onPressed: () => onAddSchedule(),
child: Row(
children: [
const Icon(Icons.add, color: ColorsManager.primaryColor),
Text(
' Add new schedule',
style: context.textTheme.bodySmall!.copyWith(
color: ColorsManager.blackColor,
),
),
],
),
),
),
const SizedBox(height: 20),
ScheduleGarageTableWidget(state: state),
],
);
}
}

View File

@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class ScheduleGarageModeButtons extends StatelessWidget {
final VoidCallback onSave;
const ScheduleGarageModeButtons({
super.key,
required this.onSave,
});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: DefaultButton(
height: 40,
onPressed: () {
Navigator.pop(context);
},
backgroundColor: ColorsManager.boxColor,
child: Text(
'Cancel',
style: context.textTheme.bodyMedium,
),
),
),
const SizedBox(width: 20),
Expanded(
child: DefaultButton(
height: 40,
onPressed: onSave,
backgroundColor: ColorsManager.primaryColor,
child: const Text('Save'),
),
),
],
);
}
}

View File

@ -0,0 +1,68 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class ScheduleGarageDoorModeSelector extends StatelessWidget {
final GarageDoorLoadedState state;
const ScheduleGarageDoorModeSelector({super.key, required this.state});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Type:',
style: context.textTheme.bodySmall!.copyWith(
fontSize: 13,
color: ColorsManager.grayColor,
),
),
const SizedBox(height: 4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildRadioTile(context, 'Schedule', ScheduleModes.schedule, state),
],
),
],
);
}
Widget _buildRadioTile(BuildContext context, String label, ScheduleModes mode, GarageDoorLoadedState state) {
return Flexible(
child: ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
label,
style: context.textTheme.bodySmall!.copyWith(
fontSize: 13,
color: ColorsManager.blackColor,
),
),
leading: Radio<ScheduleModes>(
value: mode,
groupValue: state.scheduleMode,
onChanged: (ScheduleModes? value) {
if (value != null) {
if (value == ScheduleModes.schedule) {
context.read<GarageDoorBloc>().add(
FetchGarageDoorSchedulesEvent(
category: 'switch_1',
deviceId: state.status.uuid,
),
);
}
}
},
),
),
);
}
}

View File

@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/helper/garage_door_helper.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule_garage_header.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule_garage_managment_ui.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/widgets/schedule_garage_mode_buttons.dart';
class BuildGarageDoorScheduleView extends StatefulWidget {
const BuildGarageDoorScheduleView({super.key, required this.status});
final GarageDoorStatusModel status;
@override
State<BuildGarageDoorScheduleView> createState() => _BuildScheduleViewState();
}
class _BuildScheduleViewState extends State<BuildGarageDoorScheduleView> {
@override
Widget build(BuildContext context) {
final bloc = BlocProvider.of<GarageDoorBloc>(context);
return BlocProvider.value(
value: bloc,
child: Dialog(
backgroundColor: Colors.white,
insetPadding: const EdgeInsets.all(20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: SizedBox(
width: 700,
child: SingleChildScrollView(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 40.0, vertical: 20),
child: BlocBuilder<GarageDoorBloc, GarageDoorState>(
builder: (context, state) {
if (state is GarageDoorLoadedState) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ScheduleGarageHeader(),
const SizedBox(height: 20),
ScheduleGarageManagementUI(
state: state,
onAddSchedule: () {
GarageDoorDialogHelper
.showAddGarageDoorScheduleDialog(context,
schedule: null, index: null, isEdit: false);
},
),
const SizedBox(height: 20),
ScheduleGarageModeButtons(
onSave: () {
Navigator.pop(context);
},
),
],
);
}
if (state is ScheduleGarageLoadingState) {
return SizedBox(
height: 200,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const ScheduleGarageHeader(),
const SizedBox(
height: 50,
),
const Center(child: CircularProgressIndicator()),
const SizedBox(
height: 20,
),
ScheduleGarageModeButtons(
onSave: () {},
),
],
));
}
return const SizedBox(
height: 200,
child: ScheduleGarageHeader(),
);
},
),
),
),
),
),
);
}
}

View File

@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
class SecondsPicker extends StatefulWidget {
final int initialSeconds;
final ValueChanged<int> onSecondsChanged;
SecondsPicker({
required this.initialSeconds,
required this.onSecondsChanged,
});
@override
_SecondsPickerState createState() => _SecondsPickerState();
}
class _SecondsPickerState extends State<SecondsPicker> {
late FixedExtentScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = FixedExtentScrollController(
initialItem: widget.initialSeconds,
);
}
@override
Widget build(BuildContext context) {
return Container(
height: 120,
color: Colors.white,
child: ListWheelScrollView.useDelegate(
controller: _scrollController,
itemExtent: 48,
onSelectedItemChanged: (index) {
widget.onSecondsChanged(index);
},
physics: const FixedExtentScrollPhysics(),
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
'$index sec',
style: const TextStyle(fontSize: 24),
),
);
},
),
),
);
}
}

View File

@ -0,0 +1,49 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_bloc.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_event.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
class TimeOutAlarmDialogBody extends StatefulWidget {
TimeOutAlarmDialogBody(this.bloc);
final GarageDoorBloc bloc;
@override
_TimeOutAlarmDialogBodyState createState() => _TimeOutAlarmDialogBodyState();
}
class _TimeOutAlarmDialogBodyState extends State<TimeOutAlarmDialogBody> {
int durationInSeconds = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
final currentState = widget.bloc.state;
if (currentState is GarageDoorLoadedState) {
if (currentState.status.countdownAlarm != 0) {
setState(() {
durationInSeconds = currentState.status.countdownAlarm;
});
}
}
}
@override
Widget build(BuildContext context) {
return Container(
height: 120,
color: Colors.white,
child: CupertinoTimerPicker(
itemExtent: 120,
mode: CupertinoTimerPickerMode.hm,
initialTimerDuration: Duration(seconds: durationInSeconds),
onTimerDurationChanged: (newDuration) {
widget.bloc.add(
UpdateCountdownAlarmEvent(newDuration.inSeconds),
);
},
),
);
}
}

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
@ -12,14 +13,13 @@ class GateWayBloc extends Bloc<GateWayEvent, GateWayState> {
GateWayBloc() : super(GateWayInitial()) {
on<GateWayFetch>((event, emit) {});
on<GatWayById>(_getGatWayById);
on<GateWayFactoryReset>(_onFactoryReset);
}
FutureOr<void> _getGatWayById(
GatWayById event, Emitter<GateWayState> emit) async {
FutureOr<void> _getGatWayById(GatWayById event, Emitter<GateWayState> emit) async {
emit(GatewayLoadingState());
try {
List<DeviceModel> devicesList =
await DevicesManagementApi.getDevicesByGatewayId(event.getWayId);
List<DeviceModel> devicesList = await DevicesManagementApi.getDevicesByGatewayId(event.getWayId);
emit(UpdateGatewayState(list: devicesList));
} catch (e) {
@ -27,4 +27,21 @@ class GateWayBloc extends Bloc<GateWayEvent, GateWayState> {
return;
}
}
FutureOr<void> _onFactoryReset(GateWayFactoryReset event, Emitter<GateWayState> emit) async {
emit(GatewayLoadingState());
try {
final response = await DevicesManagementApi().factoryReset(
event.factoryReset,
event.deviceId,
);
if (!response) {
emit(const ErrorState(message: 'Failed'));
} else {
add(GatWayById(event.deviceId));
}
} catch (e) {
emit(ErrorState(message: e.toString()));
}
}
}

View File

@ -18,3 +18,15 @@ class GatWayById extends GateWayEvent {
final String getWayId;
const GatWayById(this.getWayId);
}
class GateWayFactoryReset extends GateWayEvent {
final String deviceId;
final FactoryResetModel factoryReset;
const GateWayFactoryReset({
required this.deviceId,
required this.factoryReset,
});
@override
List<Object> get props => [deviceId, factoryReset];
}

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/gateway/bloc/gate_way_bloc.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
@ -13,10 +14,6 @@ class GatewayBatchControlView extends StatelessWidget
@override
Widget build(BuildContext context) {
final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return BlocProvider(
create: (context) => GateWayBloc()..add(GatWayById(gatewayIds.first)),
child: BlocBuilder<GateWayBloc, GateWayState>(
@ -24,19 +21,32 @@ class GatewayBatchControlView extends StatelessWidget
if (state is GatewayLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is UpdateGatewayState) {
return GridView(
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge || isExtraLarge || isMedium ? 2 : 1,
mainAxisExtent: 140,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FirmwareUpdateWidget(deviceId: gatewayIds.first, version: 2),
FactoryResetWidget(deviceId: gatewayIds.first),
SizedBox(
width: 170,
height: 140,
child: FirmwareUpdateWidget(
deviceId: gatewayIds.first, version: 2)),
const SizedBox(
width: 12,
),
SizedBox(
width: 170,
height: 140,
child: FactoryResetWidget(
callFactoryReset: () {
context.read<GateWayBloc>().add(
GateWayFactoryReset(
deviceId: gatewayIds.first,
factoryReset:
FactoryResetModel(devicesUuid: gatewayIds),
),
);
},
),
),
],
);
} else {

View File

@ -5,6 +5,7 @@ import 'package:syncrow_web/pages/device_managment/gateway/bloc/gate_way_bloc.da
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class GateWayControlsView extends StatelessWidget with HelperResponsiveLayout {
@ -25,25 +26,61 @@ class GateWayControlsView extends StatelessWidget with HelperResponsiveLayout {
if (state is GatewayLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is UpdateGatewayState) {
return GridView.builder(
padding: const EdgeInsets.symmetric(horizontal: 50),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge || isExtraLarge
? 3
: isMedium
? 2
: 1,
mainAxisExtent: 140,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
itemCount: state.list.length,
itemBuilder: (context, index) {
final device = state.list[index];
return _DeviceItem(device: device);
},
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Bluetooth Devices:",
style: context.textTheme.bodyMedium!.copyWith(
color: ColorsManager.grayColor,
),
),
const SizedBox(height: 12),
Text(
"No devices found",
style: context.textTheme.bodySmall!.copyWith(
color: ColorsManager.blackColor,
),
),
const SizedBox(height: 30),
Text(
"ZigBee Devices:",
style: context.textTheme.bodyMedium!.copyWith(
color: ColorsManager.grayColor,
),
),
],
),
),
const SizedBox(height: 12),
GridView.builder(
padding: const EdgeInsets.symmetric(horizontal: 50),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge || isExtraLarge
? 3
: isMedium
? 2
: 1,
mainAxisExtent: 140,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
itemCount: state.list.length,
itemBuilder: (context, index) {
final device = state.list[index];
return _DeviceItem(device: device);
},
),
],
);
} else {
return const Center(child: Text('Error fetching status'));
@ -67,22 +104,19 @@ class _DeviceItem extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 60,
ClipOval(
child: Container(
height: 60,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: ColorsManager.whiteColors,
width: 60,
padding: const EdgeInsets.all(8),
color: ColorsManager.whiteColors,
child: SvgPicture.asset(
device.icon ?? 'assets/icons/gateway.svg',
width: 35,
height: 35,
fit: BoxFit.contain,
),
margin: const EdgeInsets.symmetric(horizontal: 4),
padding: const EdgeInsets.all(4),
child: ClipOval(
child: SvgPicture.asset(
device.icon,
fit: BoxFit.fill,
),
),
),
)),
const Spacer(),
Text(
device.name ?? 'Unknown Device',

View File

@ -15,6 +15,7 @@ class MainDoorSensorBloc
on<MainDoorSensorControl>(_onControl);
on<MainDoorSensorFetchBatchEvent>(_onFetchBatchStatus);
on<MainDoorSensorReportsEvent>(_fetchReports);
on<MainDoorSensorFactoryReset>(_factoryReset);
}
late MainDoorSensorStatusModel deviceStatus;
@ -137,4 +138,22 @@ class MainDoorSensorBloc
_timer?.cancel();
return super.close();
}
FutureOr<void> _factoryReset(MainDoorSensorFactoryReset event,
Emitter<MainDoorSensorState> emit) async {
emit(MainDoorSensorLoadingState());
try {
final response = await DevicesManagementApi().factoryReset(
event.factoryReset,
event.deviceId,
);
if (!response) {
emit(MainDoorSensorFailedState(error: 'Failed'));
} else {
add(MainDoorSensorFetchDeviceEvent(event.deviceId));
}
} catch (e) {
emit(MainDoorSensorFailedState(error: e.toString()));
}
}
}

View File

@ -1,5 +1,7 @@
import 'package:equatable/equatable.dart';
import '../../all_devices/models/factory_reset_model.dart';
class MainDoorSensorEvent extends Equatable {
@override
List<Object?> get props => [];
@ -61,3 +63,11 @@ class MainDoorSensorReportsEvent extends MainDoorSensorEvent {
required this.from,
required this.to});
}
class MainDoorSensorFactoryReset extends MainDoorSensorEvent {
final String deviceId;
final FactoryResetModel factoryReset;
MainDoorSensorFactoryReset(
{required this.deviceId, required this.factoryReset});
}

View File

@ -1,21 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_state.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/models/main_door_status_model.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/widgets/notification_dialog.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart';
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.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';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class MainDoorSensorControlView extends StatelessWidget
with HelperResponsiveLayout {
class MainDoorSensorControlView extends StatelessWidget with HelperResponsiveLayout {
const MainDoorSensorControlView({super.key, required this.device});
final AllDevicesModel device;
@ -23,12 +20,10 @@ class MainDoorSensorControlView extends StatelessWidget
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => MainDoorSensorBloc()
..add(MainDoorSensorFetchDeviceEvent(device.uuid!)),
create: (context) => MainDoorSensorBloc()..add(MainDoorSensorFetchDeviceEvent(device.uuid!)),
child: BlocBuilder<MainDoorSensorBloc, MainDoorSensorState>(
builder: (context, state) {
if (state is MainDoorSensorLoadingState ||
state is MainDoorSensorReportsLoadingState) {
if (state is MainDoorSensorLoadingState || state is MainDoorSensorReportsLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is MainDoorSensorDeviceStatusLoaded) {
return _buildStatusControls(context, state.status);
@ -37,15 +32,12 @@ class MainDoorSensorControlView extends StatelessWidget
report: state.deviceReport,
onRowTap: (index) {},
onClose: () {
context
.read<MainDoorSensorBloc>()
.add(MainDoorSensorFetchDeviceEvent(device.uuid!));
context.read<MainDoorSensorBloc>().add(MainDoorSensorFetchDeviceEvent(device.uuid!));
},
hideValueShowDescription: true,
mainDoorSensor: true,
);
} else if (state is MainDoorSensorFailedState ||
state is MainDoorSensorBatchFailedState) {
} else if (state is MainDoorSensorFailedState || state is MainDoorSensorBatchFailedState) {
return const Center(child: Text('Error fetching status'));
} else {
return const Center(child: CircularProgressIndicator());
@ -54,8 +46,7 @@ class MainDoorSensorControlView extends StatelessWidget
));
}
Widget _buildStatusControls(
BuildContext context, MainDoorSensorStatusModel status) {
Widget _buildStatusControls(BuildContext context, MainDoorSensorStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
@ -75,20 +66,20 @@ class MainDoorSensorControlView extends StatelessWidget
),
children: [
IconNameStatusContainer(
isFullIcon: true,
name: status.doorContactState ? 'Open' : 'Close',
icon: Assets.mainDoor,
icon: Assets.openCloseDoor,
onTap: () {},
status: status.doorContactState,
textColor: ColorsManager.red,
textColor: status.doorContactState ? ColorsManager.red : ColorsManager.blackColor,
paddingAmount: 8,
),
IconNameStatusContainer(
isFullIcon: true,
name: 'Open/Close\nRecord',
icon: Assets.mainDoorReports,
icon: Assets.openCloseRecords,
onTap: () {
final from = DateTime.now()
.subtract(const Duration(days: 30))
.millisecondsSinceEpoch;
final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch;
final to = DateTime.now().millisecondsSinceEpoch;
context.read<MainDoorSensorBloc>().add(
MainDoorSensorReportsEvent(
@ -103,6 +94,7 @@ class MainDoorSensorControlView extends StatelessWidget
textColor: ColorsManager.blackColor,
),
IconNameStatusContainer(
isFullIcon: false,
name: 'Notifications\nSettings',
icon: Assets.mainDoorNotifi,
onTap: () {
@ -113,69 +105,9 @@ class MainDoorSensorControlView extends StatelessWidget
},
status: false,
textColor: ColorsManager.blackColor,
paddingAmount: 14,
),
],
);
}
}
class IconNameStatusContainer extends StatelessWidget {
const IconNameStatusContainer({
super.key,
required this.name,
required this.icon,
required this.onTap,
required this.status,
required this.textColor,
this.paddingAmount = 12,
});
final String name;
final String icon;
final GestureTapCallback onTap;
final bool status;
final Color textColor;
final double? paddingAmount;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: DeviceControlsContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 60,
height: 60,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: ColorsManager.whiteColors,
),
margin: const EdgeInsets.symmetric(horizontal: 4),
padding: EdgeInsets.all(paddingAmount ?? 12),
child: ClipOval(
child: SvgPicture.asset(
icon,
fit: BoxFit.fill,
),
),
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Text(
name,
textAlign: TextAlign.start,
style: context.textTheme.titleMedium!.copyWith(
fontWeight: FontWeight.w400,
color: textColor,
),
),
),
],
),
),
);
}
}

View File

@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
class MainDoorSensorBatchView extends StatelessWidget {
const MainDoorSensorBatchView({super.key, required this.devicesIds});
final List<String> devicesIds;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 170,
height: 140,
child: FirmwareUpdateWidget(
deviceId: devicesIds.first,
version: 12,
),
),
const SizedBox(
width: 12,
),
SizedBox(
width: 170,
height: 140,
child: FactoryResetWidget(
callFactoryReset: () {
BlocProvider.of<MainDoorSensorBloc>(context).add(
MainDoorSensorFactoryReset(
deviceId: devicesIds.first,
factoryReset: FactoryResetModel(devicesUuid: devicesIds),
),
);
},
),
),
],
);
}
}

View File

@ -2,9 +2,18 @@ import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class NotificationDialog extends StatelessWidget {
class NotificationDialog extends StatefulWidget {
const NotificationDialog({super.key});
@override
State<NotificationDialog> createState() => _NotificationDialogState();
}
class _NotificationDialogState extends State<NotificationDialog> {
bool isLowBatteryNotificationEnabled = true;
bool isClosingRemindersEnabled = true;
bool isDoorAlarmEnabled = true;
@override
Widget build(BuildContext context) {
return Dialog(
@ -14,7 +23,7 @@ class NotificationDialog extends StatelessWidget {
borderRadius: BorderRadius.circular(20),
),
child: SizedBox(
width: 798,
width: 660,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
@ -61,29 +70,53 @@ class NotificationDialog extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ToggleWidget(
value: true,
code: 'notification',
deviceId: '',
label: 'Low Battery',
onChange: (v) {},
icon: '-1',
SizedBox(
width: 170,
height: 135,
child: ToggleWidget(
value: isLowBatteryNotificationEnabled,
code: 'notification',
deviceId: '',
label: 'Low Battery',
onChange: (v) {
setState(() {
isLowBatteryNotificationEnabled = v;
});
},
icon: '-1',
),
),
ToggleWidget(
value: true,
code: 'notification',
deviceId: '',
label: 'Closing\nReminders',
onChange: (v) {},
icon: '-1',
SizedBox(
width: 170,
height: 135,
child: ToggleWidget(
value: isClosingRemindersEnabled,
code: 'notification',
deviceId: '',
label: 'Closing\nReminders',
onChange: (v) {
setState(() {
isClosingRemindersEnabled = v;
});
},
icon: '-1',
),
),
ToggleWidget(
value: true,
code: 'notification',
deviceId: '',
label: 'Door Alarm',
onChange: (v) {},
icon: '-1',
SizedBox(
width: 170,
height: 135,
child: ToggleWidget(
value: isDoorAlarmEnabled,
code: 'notification',
deviceId: '',
label: 'Door Alarm',
onChange: (v) {
setState(() {
isDoorAlarmEnabled = v;
});
},
icon: '-1',
),
),
],
),

View File

@ -0,0 +1,159 @@
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
part 'one_gang_glass_switch_event.dart';
part 'one_gang_glass_switch_state.dart';
class OneGangGlassSwitchBloc extends Bloc<OneGangGlassSwitchEvent, OneGangGlassSwitchState> {
OneGangGlassStatusModel deviceStatus;
Timer? _timer;
OneGangGlassSwitchBloc({required String deviceId})
: deviceStatus = OneGangGlassStatusModel(uuid: deviceId, switch1: false, countDown: 0),
super(OneGangGlassSwitchInitial()) {
on<OneGangGlassSwitchFetchDeviceEvent>(_onFetchDeviceStatus);
on<OneGangGlassSwitchControl>(_onControl);
on<OneGangGlassSwitchBatchControl>(_onBatchControl);
on<OneGangGlassSwitchFetchBatchStatusEvent>(_onFetchBatchStatus);
on<OneGangGlassFactoryResetEvent>(_onFactoryReset);
}
Future<void> _onFetchDeviceStatus(
OneGangGlassSwitchFetchDeviceEvent event, Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading());
try {
final status = await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
} catch (e) {
emit(OneGangGlassSwitchError(e.toString()));
}
}
Future<void> _onControl(OneGangGlassSwitchControl event, Emitter<OneGangGlassSwitchState> emit) async {
final oldValue = _getValueByCode(event.code);
_updateLocalValue(event.code, event.value);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
await _runDebounce(
deviceId: event.deviceId,
code: event.code,
value: event.value,
oldValue: oldValue,
emit: emit,
isBatch: false,
);
}
Future<void> _onFactoryReset(OneGangGlassFactoryResetEvent event, Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading());
try {
final response = await DevicesManagementApi().factoryReset(event.factoryReset, event.deviceId);
if (!response) {
emit(OneGangGlassSwitchError('Failed to reset device'));
} else {
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
}
} catch (e) {
emit(OneGangGlassSwitchError(e.toString()));
}
}
Future<void> _onBatchControl(OneGangGlassSwitchBatchControl event, Emitter<OneGangGlassSwitchState> emit) async {
final oldValue = _getValueByCode(event.code);
_updateLocalValue(event.code, event.value);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
await _runDebounce(
deviceId: event.deviceIds,
code: event.code,
value: event.value,
oldValue: oldValue,
emit: emit,
isBatch: true,
);
}
Future<void> _onFetchBatchStatus(
OneGangGlassSwitchFetchBatchStatusEvent event, Emitter<OneGangGlassSwitchState> emit) async {
emit(OneGangGlassSwitchLoading());
try {
final status = await DevicesManagementApi().getBatchStatus(event.deviceIds);
deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
} catch (e) {
emit(OneGangGlassSwitchError(e.toString()));
}
}
Future<void> _runDebounce({
required dynamic deviceId,
required String code,
required bool value,
required bool oldValue,
required Emitter<OneGangGlassSwitchState> emit,
required bool isBatch,
}) async {
late String id;
if (deviceId is List) {
id = deviceId.first;
} else {
id = deviceId;
}
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(milliseconds: 500), () async {
try {
late bool response;
if (isBatch) {
response = await DevicesManagementApi().deviceBatchControl(deviceId, code, value);
} else {
response = await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
}
if (!response) {
_revertValueAndEmit(id, code, oldValue, emit);
}
} catch (e) {
_revertValueAndEmit(id, code, oldValue, emit);
}
});
}
void _revertValueAndEmit(String deviceId, String code, bool oldValue, Emitter<OneGangGlassSwitchState> emit) {
_updateLocalValue(code, oldValue);
emit(OneGangGlassSwitchStatusLoaded(deviceStatus));
}
void _updateLocalValue(String code, bool value) {
if (code == 'switch_1') {
deviceStatus = deviceStatus.copyWith(switch1: value);
}
}
bool _getValueByCode(String code) {
switch (code) {
case 'switch_1':
return deviceStatus.switch1;
default:
return false;
}
}
@override
Future<void> close() {
_timer?.cancel();
return super.close();
}
}

Some files were not shown because too many files have changed in this diff Show More