store added api

This commit is contained in:
mohamadmahdi jebeli 2025-07-09 10:15:18 +03:30
parent e20c87d0dd
commit 0c53bfdbbb
30 changed files with 2399 additions and 208 deletions

3
assets/icons/addPic.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="52" height="50" viewBox="0 0 52 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M38.2501 22.9997C41.7642 22.9997 45.1344 24.3957 47.6193 26.8806C50.1041 29.3654 51.5001 32.7356 51.5001 36.2497C51.5001 39.7639 50.1041 43.1341 47.6193 45.6189C45.1344 48.1038 41.7642 49.4997 38.2501 49.4997C34.736 49.4997 31.3658 48.1038 28.8809 45.6189C26.3961 43.1341 25.0001 39.7639 25.0001 36.2497C25.0001 32.7356 26.3961 29.3654 28.8809 26.8806C31.3658 24.3957 34.736 22.9997 38.2501 22.9997ZM38.2501 27.8179L38.0333 27.8372C37.7926 27.8812 37.571 27.9974 37.398 28.1704C37.225 28.3434 37.1088 28.565 37.0648 28.8057L37.0455 29.0225V35.0452H31.018L30.8012 35.0669C30.5605 35.1109 30.3389 35.2271 30.1659 35.4001C29.9929 35.5731 29.8767 35.7947 29.8327 36.0353L29.8135 36.2522L29.8327 36.469C29.8767 36.7096 29.9929 36.9312 30.1659 37.1042C30.3389 37.2772 30.5605 37.3935 30.8012 37.4374L31.018 37.4567H37.0455V43.4867L37.0648 43.7035C37.1088 43.9441 37.225 44.1657 37.398 44.3387C37.571 44.5117 37.7926 44.628 38.0333 44.6719L38.2501 44.6912L38.4669 44.6719C38.7076 44.628 38.9292 44.5117 39.1022 44.3387C39.2752 44.1657 39.3914 43.9441 39.4354 43.7035L39.4546 43.4867V37.4543H45.487L45.7038 37.4374C45.9445 37.3935 46.1661 37.2772 46.3391 37.1042C46.5121 36.9312 46.6283 36.7096 46.6723 36.469L46.6915 36.2522L46.6723 36.0353C46.6281 35.7943 46.5116 35.5725 46.3381 35.3995C46.1646 35.2264 45.9425 35.1104 45.7014 35.0669L45.4846 35.0476H39.4546V29.0249L39.4354 28.8081C39.3918 28.5669 39.2758 28.3448 39.1028 28.1714C38.9297 27.9979 38.7079 27.8813 38.4669 27.8372L38.2501 27.8179ZM29.6376 0.123014C30.5821 0.122939 31.5102 0.369645 32.3299 0.838689C33.1497 1.30773 33.8327 1.98284 34.3112 2.79711L36.2722 6.13851H41.2615C43.3376 6.13851 45.3287 6.96308 46.7969 8.43088C48.2652 9.89869 49.0904 11.8895 49.091 13.9657V24.9511C48.0168 23.9189 46.8008 23.0452 45.4798 22.3565L45.4774 13.9657C45.4774 12.8475 45.0332 11.7752 44.2425 10.9846C43.4519 10.1939 42.3796 9.74974 41.2615 9.74974H35.2387C34.9238 9.74991 34.6142 9.66774 34.3408 9.51138C34.0674 9.35503 33.8396 9.12992 33.68 8.85838L31.1939 4.62561C31.0345 4.35442 30.8071 4.12953 30.5341 3.9732C30.2612 3.81686 29.9521 3.7345 29.6376 3.73424H20.4758C20.2122 3.73446 19.9518 3.79236 19.7129 3.9039C19.474 4.01543 19.2624 4.17789 19.093 4.37988L18.9364 4.5967L16.3033 8.88729C16.1418 9.15065 15.9155 9.36822 15.646 9.51922C15.3765 9.67021 15.0728 9.74958 14.7639 9.74974H8.74113C8.18729 9.74943 7.63881 9.85824 7.12704 10.07C6.61526 10.2817 6.15022 10.5922 5.75848 10.9837C5.36674 11.3752 5.05598 11.8401 4.84396 12.3517C4.63194 12.8634 4.52282 13.4118 4.52282 13.9657V36.852C4.52282 39.1792 6.41154 41.0679 8.73872 41.0679H23.345C23.7618 42.352 24.3376 43.5662 25.0531 44.6816H8.73872C6.6622 44.6816 4.67072 43.8567 3.2024 42.3883C1.73408 40.92 0.90918 38.9285 0.90918 36.852V13.9657C0.90918 11.8891 1.73408 9.89765 3.2024 8.42933C4.67072 6.961 6.6622 6.13611 8.73872 6.13611H13.7496L15.8576 2.70556C16.3423 1.91591 17.0213 1.26368 17.8298 0.811134C18.6383 0.358593 19.5493 0.120851 20.4758 0.120605L29.6376 0.123014ZM25.0001 13.3634C27.2922 13.3625 29.5256 14.0881 31.3794 15.436C33.2333 16.7838 34.6123 18.6846 35.3182 20.8653C34.1105 21.0966 32.9597 21.4571 31.866 21.947C31.3321 20.3111 30.2318 18.9195 28.7633 18.0226C27.2947 17.1257 25.5542 16.7824 23.855 17.0546C22.1559 17.3268 20.6096 18.1964 19.4946 19.5071C18.3796 20.8178 17.7691 22.4835 17.7728 24.2043C17.7728 27.6493 20.1819 30.5282 23.4053 31.2557C23.0208 32.401 22.7702 33.5869 22.6585 34.7898C20.0564 34.2066 17.7604 32.6849 16.2095 30.5157C14.6585 28.3465 13.9613 25.6818 14.251 23.0309C14.5407 20.38 15.7971 17.9289 17.7801 16.1459C19.763 14.3629 22.3334 13.3732 25.0001 13.3658" fill="#6AB9F7"/>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 2V5" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 2V5" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.2 21.4C19.9673 21.4 21.4 19.9673 21.4 18.2C21.4 16.4327 19.9673 15 18.2 15C16.4327 15 15 16.4327 15 18.2C15 19.9673 16.4327 21.4 18.2 21.4Z" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M22 22L21 21" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.5 9.08984H20.5" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.37 22H8C4.5 22 3 20 3 17V8.5C3 5.5 4.5 3.5 8 3.5H16C19.5 3.5 21 5.5 21 8.5V13" stroke="#2196F3" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.9955 13.7002H12.0045" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.29431 13.7002H8.30329" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.29431 16.7002H8.30329" stroke="#2196F3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,5 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.0875 17.0625C12.24 17.0625 11.3475 16.86 10.425 16.47C9.525 16.0875 8.6175 15.5625 7.7325 14.925C6.855 14.28 6.0075 13.56 5.205 12.7725C4.41 11.97 3.69 11.1225 3.0525 10.2525C2.4075 9.3525 1.89 8.4525 1.5225 7.5825C1.1325 6.6525 0.9375 5.7525 0.9375 4.905C0.9375 4.32 1.0425 3.765 1.245 3.2475C1.455 2.715 1.7925 2.22 2.25 1.7925C2.8275 1.2225 3.4875 0.9375 4.1925 0.9375C4.485 0.9375 4.785 1.005 5.04 1.125C5.3325 1.26 5.58 1.4625 5.76 1.7325L7.5 4.185C7.6575 4.4025 7.7775 4.6125 7.86 4.8225C7.9575 5.0475 8.01 5.2725 8.01 5.49C8.01 5.775 7.9275 6.0525 7.77 6.315C7.6575 6.5175 7.485 6.735 7.2675 6.9525L6.7575 7.485C6.765 7.5075 6.7725 7.5225 6.78 7.5375C6.87 7.695 7.05 7.965 7.395 8.37C7.7625 8.79 8.1075 9.1725 8.4525 9.525C8.895 9.96 9.2625 10.305 9.6075 10.59C10.035 10.95 10.3125 11.13 10.4775 11.2125L10.4625 11.25L11.01 10.71C11.2425 10.4775 11.4675 10.305 11.685 10.1925C12.0975 9.9375 12.6225 9.8925 13.1475 10.11C13.3425 10.1925 13.5525 10.305 13.7775 10.4625L16.2675 12.2325C16.545 12.42 16.7475 12.66 16.8675 12.945C16.98 13.23 17.0325 13.4925 17.0325 13.755C17.0325 14.115 16.95 14.475 16.7925 14.8125C16.635 15.15 16.44 15.4425 16.1925 15.7125C15.765 16.185 15.3 16.5225 14.76 16.74C14.2425 16.95 13.68 17.0625 13.0875 17.0625ZM4.1925 2.0625C3.78 2.0625 3.3975 2.2425 3.03 2.6025C2.685 2.925 2.445 3.2775 2.295 3.66C2.1375 4.05 2.0625 4.4625 2.0625 4.905C2.0625 5.6025 2.2275 6.36 2.5575 7.14C2.895 7.935 3.3675 8.76 3.9675 9.585C4.5675 10.41 5.25 11.2125 6 11.97C6.75 12.7125 7.56 13.4025 8.3925 14.01C9.2025 14.6025 10.035 15.0825 10.86 15.4275C12.1425 15.975 13.3425 16.1025 14.3325 15.69C14.715 15.5325 15.0525 15.2925 15.36 14.9475C15.5325 14.76 15.6675 14.5575 15.78 14.3175C15.87 14.13 15.915 13.935 15.915 13.74C15.915 13.62 15.8925 13.5 15.8325 13.365C15.81 13.32 15.765 13.2375 15.6225 13.14L13.1325 11.37C12.9825 11.265 12.8475 11.19 12.72 11.1375C12.555 11.07 12.4875 11.0025 12.2325 11.16C12.0825 11.235 11.9475 11.3475 11.7975 11.4975L11.2275 12.06C10.935 12.345 10.485 12.4125 10.14 12.285L9.9375 12.195C9.63 12.03 9.27 11.775 8.8725 11.4375C8.5125 11.13 8.1225 10.77 7.65 10.305C7.2825 9.93 6.915 9.5325 6.5325 9.09C6.18 8.6775 5.925 8.325 5.7675 8.0325L5.6775 7.8075C5.6325 7.635 5.6175 7.5375 5.6175 7.4325C5.6175 7.1625 5.715 6.9225 5.9025 6.735L6.465 6.15C6.615 6 6.7275 5.8575 6.8025 5.73C6.8625 5.6325 6.885 5.55 6.885 5.475C6.885 5.415 6.8625 5.325 6.825 5.235C6.7725 5.115 6.69 4.98 6.585 4.8375L4.845 2.3775C4.77 2.2725 4.68 2.1975 4.5675 2.145C4.4475 2.0925 4.32 2.0625 4.1925 2.0625ZM10.4625 11.2575L10.3425 11.7675L10.545 11.2425C10.5075 11.235 10.4775 11.2425 10.4625 11.2575Z" fill="#A1A0A0"/>
<path d="M13.875 7.3125C13.5675 7.3125 13.3125 7.0575 13.3125 6.75C13.3125 6.48 13.0425 5.9175 12.5925 5.4375C12.15 4.965 11.6625 4.6875 11.25 4.6875C10.9425 4.6875 10.6875 4.4325 10.6875 4.125C10.6875 3.8175 10.9425 3.5625 11.25 3.5625C11.9775 3.5625 12.7425 3.9525 13.41 4.665C14.0325 5.3325 14.4375 6.15 14.4375 6.75C14.4375 7.0575 14.1825 7.3125 13.875 7.3125Z" fill="#A1A0A0"/>
<path d="M16.5 7.3125C16.1925 7.3125 15.9375 7.0575 15.9375 6.75C15.9375 4.1625 13.8375 2.0625 11.25 2.0625C10.9425 2.0625 10.6875 1.8075 10.6875 1.5C10.6875 1.1925 10.9425 0.9375 11.25 0.9375C14.4525 0.9375 17.0625 3.5475 17.0625 6.75C17.0625 7.0575 16.8075 7.3125 16.5 7.3125Z" fill="#A1A0A0"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,6 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 17.0625H6C3.2625 17.0625 1.6875 15.4875 1.6875 12.75V5.25C1.6875 2.5125 3.2625 0.9375 6 0.9375H12C14.7375 0.9375 16.3125 2.5125 16.3125 5.25V12.75C16.3125 15.4875 14.7375 17.0625 12 17.0625ZM6 2.0625C3.855 2.0625 2.8125 3.105 2.8125 5.25V12.75C2.8125 14.895 3.855 15.9375 6 15.9375H12C14.145 15.9375 15.1875 14.895 15.1875 12.75V5.25C15.1875 3.105 14.145 2.0625 12 2.0625H6Z" fill="#A1A0A0"/>
<path d="M13.875 6.9375H12.375C11.235 6.9375 10.3125 6.015 10.3125 4.875V3.375C10.3125 3.0675 10.5675 2.8125 10.875 2.8125C11.1825 2.8125 11.4375 3.0675 11.4375 3.375V4.875C11.4375 5.3925 11.8575 5.8125 12.375 5.8125H13.875C14.1825 5.8125 14.4375 6.0675 14.4375 6.375C14.4375 6.6825 14.1825 6.9375 13.875 6.9375Z" fill="#A1A0A0"/>
<path d="M9 10.3125H6C5.6925 10.3125 5.4375 10.0575 5.4375 9.75C5.4375 9.4425 5.6925 9.1875 6 9.1875H9C9.3075 9.1875 9.5625 9.4425 9.5625 9.75C9.5625 10.0575 9.3075 10.3125 9 10.3125Z" fill="#A1A0A0"/>
<path d="M12 13.3125H6C5.6925 13.3125 5.4375 13.0575 5.4375 12.75C5.4375 12.4425 5.6925 12.1875 6 12.1875H12C12.3075 12.1875 12.5625 12.4425 12.5625 12.75C12.5625 13.0575 12.3075 13.3125 12 13.3125Z" fill="#A1A0A0"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,5 @@
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.5 16.5C13.625 16.5 17 13.125 17 9C17 4.875 13.625 1.5 9.5 1.5C5.375 1.5 2 4.875 2 9C2 13.125 5.375 16.5 9.5 16.5Z" stroke="#A1A0A0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.5 6V9.75" stroke="#A1A0A0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.49585 12H9.50259" stroke="#A1A0A0" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 535 B

4
assets/icons/radar-2.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="53" height="53" viewBox="0 0 53 53" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.4" d="M26.8099 48.4764C38.776 48.4764 48.4765 38.7759 48.4765 26.8097C48.4765 14.8436 38.776 5.14307 26.8099 5.14307C14.8437 5.14307 5.14319 14.8436 5.14319 26.8097C5.14319 38.7759 14.8437 48.4764 26.8099 48.4764Z" fill="#176BAD"/>
<path d="M26.8098 10.0181C23.1481 10.0181 19.6598 11.1881 16.7348 13.3764C16.0198 13.9181 15.8682 14.9364 16.4098 15.6514C16.9515 16.3664 17.9698 16.5181 18.6848 15.9764C21.0465 14.1997 23.8415 13.2681 26.8098 13.2681C34.2848 13.2681 40.3515 19.3347 40.3515 26.8097C40.3515 34.2847 34.2848 40.3514 26.8098 40.3514C19.3348 40.3514 13.2681 34.2847 13.2681 26.8097C13.2681 24.9897 13.6365 23.1914 14.3298 21.5231L16.7998 22.9314C16.3232 24.1664 16.0632 25.4664 16.0632 26.8097C16.0632 32.7247 20.8731 37.5347 26.7881 37.5347C32.7031 37.5347 37.5132 32.7247 37.5132 26.8097C37.5132 20.8947 32.7031 16.0847 26.7881 16.0847C25.1848 16.0847 23.6465 16.4314 22.2165 17.1031C21.4148 17.4931 21.0465 18.4464 21.4365 19.2697C21.8265 20.0714 22.7798 20.4181 23.6031 20.0497C24.5998 19.5731 25.6615 19.3347 26.7881 19.3347C30.9048 19.3347 34.2632 22.6931 34.2632 26.8097C34.2632 30.9264 30.9048 34.2847 26.7881 34.2847C22.6715 34.2847 19.3132 30.9264 19.3132 26.8097C19.3132 26.0514 19.4648 25.3147 19.6815 24.5997L25.9865 28.2181C26.7665 28.6731 27.7632 28.3914 28.1965 27.6114C28.6515 26.8314 28.3698 25.8347 27.5898 25.4014L14.4382 17.8397C13.6582 17.3847 12.6615 17.6664 12.2281 18.4464C10.7765 20.9814 9.99646 23.8631 9.99646 26.8097C9.99646 36.0614 17.5365 43.6014 26.7881 43.6014C36.0398 43.6014 43.5798 36.0614 43.5798 26.8097C43.5798 17.5581 36.0615 10.0181 26.8098 10.0181Z" fill="#176BAD"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

271
assets/images/emptyShop.svg Normal file
View File

@ -0,0 +1,271 @@
<svg width="318" height="326" viewBox="0 0 318 326" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M308.362 323.147H19.7863V325.388H308.362V323.147Z" fill="#C8D3FB"/>
<path d="M196.805 21.7671C243.221 35.0516 321.007 76.3453 317.485 170.937C313.964 265.688 231.377 216.712 169.276 302.341C123.021 366.202 -70.6438 278.973 43.7943 91.5504C89.2494 16.9655 156.632 10.2433 196.805 21.7671Z" fill="url(#paint0_linear_6328_5608)"/>
<path d="M238.259 264.888C197.285 277.372 191.684 295.938 192.004 312.264C192.324 330.83 265.148 321.867 295.558 272.57C326.128 223.434 260.026 258.326 238.259 264.888Z" fill="url(#paint1_linear_6328_5608)"/>
<mask id="mask0_6328_5608" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="8" y="17" width="310" height="307">
<path d="M196.805 21.7671C243.221 35.0516 321.007 76.3453 317.485 170.937C313.964 265.688 231.377 216.712 169.276 302.341C123.021 366.202 -70.6438 278.973 43.7943 91.5504C89.2494 16.9655 156.632 10.2433 196.805 21.7671Z" fill="white"/>
</mask>
<g mask="url(#mask0_6328_5608)">
<path d="M-16.2257 89.4693V77.6254H3.30083V21.2866H8.74265V77.6254H29.7096V89.4693H41.0734V325.708H-40.3937V89.4693H-16.2257Z" fill="#C8D3FB"/>
<path d="M0.322586 325.646H81.6296L81.6296 145.747H0.322586L0.322586 325.646Z" fill="#C8D3FB"/>
<path d="M0.347854 325.646H11.5516L11.5516 145.747H0.347854L0.347854 325.646Z" fill="#D5DDFB"/>
<path d="M58.666 158.178H70.3499V153.377H58.666V158.178Z" fill="#D5DDFB"/>
<path d="M39.0394 158.178H50.7233V153.377H39.0394V158.178Z" fill="#D5DDFB"/>
<path d="M58.666 175.857H70.3499V171.056H58.666V175.857Z" fill="#D5DDFB"/>
<path d="M39.0394 175.857H50.7233V171.056H39.0394V175.857Z" fill="#D5DDFB"/>
<path d="M19.416 175.857H31.0999V171.056H19.416V175.857Z" fill="#D5DDFB"/>
<path d="M58.666 193.537H70.3499V188.736H58.666V193.537Z" fill="#D5DDFB"/>
<path d="M19.416 193.537H31.0999V188.736H19.416V193.537Z" fill="#D5DDFB"/>
<path d="M39.0394 202.216H50.7233V197.414H39.0394V202.216Z" fill="#D5DDFB"/>
<path d="M58.666 211.055H70.3499V206.253H58.666V211.055Z" fill="#D5DDFB"/>
<path d="M39.0394 219.894H50.7233V215.092H39.0394V219.894Z" fill="#D5DDFB"/>
<path d="M58.666 228.734H70.3499V223.932H58.666V228.734Z" fill="#D5DDFB"/>
<path d="M19.416 228.734H31.0999V223.932H19.416V228.734Z" fill="#D5DDFB"/>
<path d="M58.666 245.014H70.3499V240.213H58.666V245.014Z" fill="#D5DDFB"/>
<path d="M39.0394 245.014H50.7233V240.213H39.0394V245.014Z" fill="#D5DDFB"/>
<path d="M58.666 262.693H70.3499V257.891H58.666V262.693Z" fill="#D5DDFB"/>
<path d="M39.0394 262.693H50.7233V257.891H39.0394V262.693Z" fill="#D5DDFB"/>
<path d="M19.416 262.693H31.0999V257.891H19.416V262.693Z" fill="#D5DDFB"/>
<path d="M58.666 280.372H70.3499V275.57H58.666V280.372Z" fill="#D5DDFB"/>
<path d="M19.416 280.372H31.0999V275.57H19.416V280.372Z" fill="#D5DDFB"/>
<path d="M39.0394 289.211H50.7233V284.409H39.0394V289.211Z" fill="#D5DDFB"/>
<path d="M19.416 289.211H31.0999V284.409H19.416V289.211Z" fill="#D5DDFB"/>
<path d="M58.666 298.051H70.3499V293.249H58.666V298.051Z" fill="#D5DDFB"/>
<path d="M39.0394 306.73H50.7233V301.928H39.0394V306.73Z" fill="#D5DDFB"/>
<path d="M58.666 315.57H70.3499V310.769H58.666V315.57Z" fill="#D5DDFB"/>
<path d="M19.416 315.57H31.0999V310.769H19.416V315.57Z" fill="#D5DDFB"/>
<path d="M195.027 325.646H276.334V145.746H195.027L195.027 325.646Z" fill="#C8D3FB"/>
<path d="M195.054 325.646H206.258L206.258 145.746H195.054L195.054 325.646Z" fill="#D5DDFB"/>
<path d="M79.3953 325.675H188.552L188.552 60.1465H79.3953L79.3953 325.675Z" fill="#C8D3FB"/>
<path d="M79.4684 325.675H90.6722L90.6722 60.1465H79.4684L79.4684 325.675Z" fill="#D5DDFB"/>
<path d="M160.033 79.8203H177.159V72.778H160.033V79.8203Z" fill="#D5DDFB"/>
<path d="M131.276 79.8203H148.401V72.778H131.276V79.8203Z" fill="#D5DDFB"/>
<path d="M160.033 105.578H177.159V98.5353H160.033V105.578Z" fill="#D5DDFB"/>
<path d="M131.276 105.578H148.401V98.5353H131.276V105.578Z" fill="#D5DDFB"/>
<path d="M102.519 105.578H119.644V98.5353H102.519V105.578Z" fill="#D5DDFB"/>
<path d="M160.033 131.335H177.159V124.293H160.033V131.335Z" fill="#D5DDFB"/>
<path d="M102.519 131.335H119.644V124.293H102.519V131.335Z" fill="#D5DDFB"/>
<path d="M131.276 144.294H148.401V137.252H131.276V144.294Z" fill="#D5DDFB"/>
<path d="M160.033 157.092H177.159V150.05H160.033V157.092Z" fill="#D5DDFB"/>
<path d="M131.276 170.051H148.401V163.008H131.276V170.051Z" fill="#D5DDFB"/>
<path d="M160.033 182.85H177.159V175.808H160.033V182.85Z" fill="#D5DDFB"/>
<path d="M102.519 182.85H119.644V175.808H102.519V182.85Z" fill="#D5DDFB"/>
<path d="M160.033 206.775H177.159V199.733H160.033V206.775Z" fill="#D5DDFB"/>
<path d="M131.276 206.775H148.401V199.733H131.276V206.775Z" fill="#D5DDFB"/>
<path d="M160.033 232.534H177.159V225.491H160.033V232.534Z" fill="#D5DDFB"/>
<path d="M131.276 232.534H148.401V225.491H131.276V232.534Z" fill="#D5DDFB"/>
<path d="M102.519 232.534H119.644V225.491H102.519V232.534Z" fill="#D5DDFB"/>
<path d="M160.033 258.29H177.159V251.248H160.033V258.29Z" fill="#D5DDFB"/>
<path d="M102.519 258.29H119.644V251.248H102.519V258.29Z" fill="#D5DDFB"/>
<path d="M131.276 271.089H148.401V264.047H131.276V271.089Z" fill="#D5DDFB"/>
<path d="M102.519 271.089H119.644V264.047H102.519V271.089Z" fill="#D5DDFB"/>
<path d="M160.033 284.047H177.159V277.005H160.033V284.047Z" fill="#D5DDFB"/>
<path d="M131.276 296.846H148.401V289.803H131.276V296.846Z" fill="#D5DDFB"/>
<path d="M160.033 309.804H177.159V302.762H160.033V309.804Z" fill="#D5DDFB"/>
<path d="M102.519 309.804H119.644V302.762H102.519V309.804Z" fill="#D5DDFB"/>
<path d="M251.134 325.625H358.049L358.049 79.7827H251.134L251.134 325.625Z" fill="#C8D3FB"/>
<path d="M251.074 325.625H262.117L262.117 79.7827H251.074L251.074 325.625Z" fill="#D5DDFB"/>
<path d="M301.982 98.1021H318.628V91.5399H301.982V98.1021Z" fill="#D5DDFB"/>
<path d="M301.982 122.098H318.628V115.536H301.982V122.098Z" fill="#D5DDFB"/>
<path d="M273.886 122.098H290.532V115.536H273.886V122.098Z" fill="#D5DDFB"/>
<path d="M273.886 145.936H290.532V139.374H273.886V145.936Z" fill="#D5DDFB"/>
<path d="M301.982 157.773H318.628V151.211H301.982V157.773Z" fill="#D5DDFB"/>
<path d="M301.982 181.612H318.628V175.05H301.982V181.612Z" fill="#D5DDFB"/>
<path d="M273.886 193.609H290.532V187.047H273.886V193.609Z" fill="#D5DDFB"/>
<path d="M301.982 215.589H318.628V209.027H301.982V215.589Z" fill="#D5DDFB"/>
<path d="M301.982 239.426H318.628V232.864H301.982V239.426Z" fill="#D5DDFB"/>
<path d="M273.886 239.426H290.532V232.864H273.886V239.426Z" fill="#D5DDFB"/>
<path d="M273.886 263.263H290.532V256.701H273.886V263.263Z" fill="#D5DDFB"/>
<path d="M301.982 275.26H318.628V268.698H301.982V275.26Z" fill="#D5DDFB"/>
<path d="M273.886 275.26H290.532V268.698H273.886V275.26Z" fill="#D5DDFB"/>
<path d="M301.982 299.098H318.628V292.535H301.982V299.098Z" fill="#D5DDFB"/>
<path d="M273.886 310.936H290.532V304.374H273.886V310.936Z" fill="#D5DDFB"/>
<path opacity="0.35" d="M154.231 -8.64307H-137.866V324.268H154.231V-8.64307Z" fill="white"/>
<path opacity="0.5" d="M-77.366 305.542H-88.7298L32.7506 -17.606H44.1144L-77.366 305.542Z" fill="white"/>
<path opacity="0.5" d="M57.879 305.542H46.6753L150.71 17.126V40.3337L57.879 305.542Z" fill="white"/>
<path opacity="0.35" d="M447.609 -17.2856H155.512V315.625H447.609V-17.2856Z" fill="white"/>
<path opacity="0.5" d="M204.008 305.542H181.28L302.76 -17.606H325.488L204.008 305.542Z" fill="white"/>
<path opacity="0.5" d="M163.994 305.542H152.631L274.111 -17.606H285.475L163.994 305.542Z" fill="white"/>
<path d="M459.933 55.538V51.6967H449.369V-8.32324H157.272H150.87H-141.067V-0.640685H-134.665V2.08022H53.7176V51.8568H-141.067V55.6981H53.5575V153.491H-141.067V157.332H53.5575V255.124H-141.067V258.966H53.5575V322.667H-134.665V324.908H-141.067V333.711H151.03H157.432H449.529V333.07V259.126H460.093V255.284H449.529V157.492H460.093V153.651H449.529V55.538H459.933ZM157.432 157.172H248.342V254.964H157.432V157.172ZM157.432 153.331V55.538H248.342V153.331H157.432ZM157.432 51.6967V1.92017H248.342V51.6967H157.432ZM157.432 258.646H248.342V322.347H157.432V324.588V258.646ZM254.744 322.347V258.646H345.655V322.347H254.744ZM254.744 254.964V157.172H345.655V254.964H254.744ZM254.744 153.331V55.538H345.655V153.331H254.744ZM254.744 51.6967V1.92017H345.655V51.6967H254.744ZM352.057 1.92017H442.967V51.6967H352.057V1.92017ZM59.9597 1.92017H150.87V51.6967H59.9597V1.92017ZM59.9597 55.538H150.87V153.331H59.9597V55.538ZM59.9597 157.172H150.87V254.964H59.9597V157.172ZM59.9597 258.646H150.87V324.588V322.347H59.9597V258.646ZM442.967 324.588V322.347H352.057V258.646H442.967V324.588ZM442.967 254.964H352.057V157.172H442.967V254.964ZM442.967 153.331H352.057V55.538H442.967V153.331Z" fill="url(#paint2_linear_6328_5608)"/>
</g>
<path d="M79.9664 185.982C79.9664 185.662 79.6462 185.501 79.3261 185.501C73.0841 185.662 65.0814 185.662 59.7996 189.503C54.838 193.184 54.0377 199.586 54.1978 205.188C54.1978 205.828 54.838 205.988 55.3181 205.668C68.4425 210.79 81.727 199.906 79.9664 185.982Z" fill="#6A6AE8"/>
<path d="M49.3962 211.75C49.3962 207.429 48.4359 202.947 45.0748 199.906C41.2335 196.385 35.6316 194.465 31.1501 192.064C30.6699 191.904 29.8697 192.224 30.1898 192.864C32.2705 198.146 31.9504 204.548 35.6316 209.029C38.6726 212.871 43.9544 214.151 48.5959 212.711C48.756 212.711 48.916 212.551 49.0761 212.23C49.2361 212.391 49.3962 212.07 49.3962 211.75Z" fill="#6A6AE8"/>
<path d="M90.0497 226.155C87.0087 223.754 83.0074 224.074 79.1661 224.234C75.0047 224.395 70.8433 225.035 67.002 226.795C60.4399 229.996 55.7983 236.879 58.1991 244.241C58.1991 244.561 58.1991 244.881 58.6793 245.041C64.9214 246.962 67.9624 242.801 71.8036 238.639C76.6052 233.358 82.8473 229.516 89.7296 227.275C90.2098 227.115 90.5299 226.475 90.0497 226.155Z" fill="#6A6AE8"/>
<path d="M105.095 241.68C105.095 241.68 104.935 241.68 104.775 241.52C102.054 240.4 99.6529 238.159 97.2521 236.078C94.5312 233.838 91.8103 231.597 88.7693 230.957C87.3288 230.636 85.7283 230.797 84.1277 231.277C77.4055 233.517 73.2441 240.56 72.6039 247.282C72.6039 247.442 72.6039 247.602 72.764 247.602C72.764 247.602 72.764 247.602 72.764 247.762C72.6039 248.082 72.924 248.562 73.4042 248.722C79.1661 249.363 84.768 248.722 90.5299 247.602C95.4915 246.482 101.253 245.681 105.575 242.801C105.895 242.64 105.735 242 105.095 241.68Z" fill="#6A6AE8"/>
<path d="M95.1714 254.644C87.809 253.204 72.6039 249.362 71.6436 261.206C71.6436 261.526 71.8036 261.847 72.1237 261.847C78.846 269.689 91.8103 263.447 95.6516 255.765C95.8116 255.284 95.6516 254.804 95.1714 254.644Z" fill="#6A6AE8"/>
<path d="M48.5959 231.117C46.6753 226.796 42.0337 222.314 37.7123 220.714C37.2321 220.553 36.912 220.874 36.912 221.354C36.912 229.837 34.8313 243.281 44.1144 247.923H44.2745C44.5946 248.243 45.0747 248.403 45.3948 247.923C48.1158 242.801 51.1568 236.879 48.5959 231.117Z" fill="#6A6AE8"/>
<path d="M24.4279 236.398C19.9464 232.717 12.744 231.917 7.46223 234.638C0.0997844 238.319 1.54026 247.122 0.419888 253.844C0.259835 254.484 1.0601 254.965 1.54026 254.484C8.74265 248.082 18.826 245.682 24.2678 237.359C24.5879 237.199 24.748 236.719 24.4279 236.398Z" fill="#6A6AE8"/>
<path d="M24.4279 243.121C24.2678 242.801 23.9477 242.801 23.6276 242.801C23.4676 242.641 23.1475 242.48 22.8273 242.641C19.1461 244.561 14.9847 247.442 14.3445 251.764C13.5443 257.045 16.4252 262.007 16.7453 267.129C16.7453 267.769 17.8657 268.089 18.0257 267.289C18.9861 262.327 24.1078 260.086 25.8684 255.605C27.4689 252.244 26.6686 246.482 24.4279 243.121Z" fill="#6A6AE8"/>
<path d="M46.8353 273.37C42.5139 267.448 38.1925 262.327 30.83 260.406C30.3498 260.246 29.7096 260.886 30.0297 261.366C31.6303 263.927 31.6303 266.648 33.0708 269.209C33.871 270.649 35.3115 271.77 36.5919 272.73C39.793 274.651 43.7943 276.571 47.3155 274.491C48.1158 274.171 47.4755 273.21 46.8353 273.37Z" fill="#6A6AE8"/>
<path d="M56.2785 266.328V266.168C53.3975 261.527 53.2375 255.605 49.2361 251.603C48.916 251.283 48.4359 251.443 48.1158 251.763C46.1951 254.964 45.2348 258.806 46.6753 262.327C48.4359 266.168 51.957 267.288 55.7983 267.609C56.5986 267.609 56.7586 266.808 56.2785 266.328Z" fill="#6A6AE8"/>
<path d="M64.4412 214.311C63.6409 213.67 62.5205 214.311 61.7203 214.631C60.1197 215.271 58.6793 216.071 57.2388 217.031C54.6779 218.952 52.9174 221.513 52.7573 224.714C52.7573 224.714 52.7573 224.874 52.7573 225.034C52.7573 225.194 52.7573 225.194 52.7573 225.354C52.7573 226.155 53.8777 226.155 54.0377 225.674C57.2388 225.034 59.7997 222.953 61.8803 220.393C63.0007 219.112 66.5219 215.911 64.4412 214.311Z" fill="#6A6AE8"/>
<path d="M66.0417 266.969C65.8817 266.808 65.8817 266.808 65.7216 266.648C66.5219 260.886 66.842 254.324 61.2401 250.963C60.92 250.803 60.4399 250.963 60.2798 251.283C58.6793 257.365 60.4399 263.447 65.0814 267.769C65.7216 268.409 66.6819 267.449 66.0417 266.969Z" fill="#6A6AE8"/>
<path d="M104.615 241.04C102.214 239.92 99.813 237.999 97.4122 236.238C94.6913 234.158 91.9704 231.917 88.9293 231.117C87.4889 230.797 85.8883 230.957 84.2878 231.437C77.5656 233.678 73.4042 240.72 72.764 247.442C72.764 247.602 72.764 247.762 72.924 247.762C72.924 247.762 72.924 247.762 72.924 247.922C73.0841 247.922 73.4042 247.762 73.5642 247.602C73.7243 247.602 73.8843 247.602 73.8843 247.442C76.1251 245.041 78.3658 242.961 80.7666 240.72C81.887 239.6 83.0074 238.319 84.1277 237.359C86.8486 235.438 89.0894 235.758 91.9704 236.559C95.3315 237.519 98.3725 239.279 101.413 240.88C102.534 241.52 103.654 242.641 104.935 242C105.095 241.84 105.255 241.68 105.255 241.36C104.935 241.36 104.775 241.2 104.615 241.04Z" fill="#6A6AE8"/>
<path d="M45.5549 263.448C44.9147 260.887 44.2745 258.166 43.3142 255.605C44.4345 251.444 44.9147 247.282 44.7546 243.121C44.9147 243.121 45.2348 242.961 45.2348 242.641C46.0351 240.24 46.3552 237.679 46.1951 235.118C46.1951 234.318 44.7546 234.318 44.9147 235.118C45.0747 236.879 44.9147 238.64 44.4345 240.4C44.1144 238.48 43.7943 236.399 43.1541 234.478C42.834 233.678 41.5536 233.998 41.8737 234.798C43.7943 240.88 43.9544 247.122 42.5139 253.364C41.2335 250.163 39.6329 247.122 37.5522 244.401C32.5906 237.999 23.6276 234.158 16.5853 237.199C16.5853 236.879 16.4252 236.719 16.1051 236.719C13.3842 236.079 10.5032 236.399 8.10244 237.999C7.30217 238.48 8.10244 239.6 8.74265 239.12C10.6633 237.999 12.904 237.519 15.1448 237.999C13.5443 238.96 11.9437 240.24 10.6633 242.001C10.1831 242.641 11.3035 243.441 11.7837 242.641C15.1448 237.839 21.3869 236.399 26.8287 238.159C28.4292 238.64 29.8697 239.44 31.1501 240.4C25.3882 240.24 21.2268 244.081 17.2255 247.923C16.5853 248.563 17.5456 249.523 18.1858 248.883C18.9861 248.083 19.7863 247.443 20.5866 246.642C20.4265 247.923 20.2665 249.363 20.4265 250.644C20.5866 251.444 21.867 251.444 21.707 250.644C21.5469 248.883 21.707 247.122 22.0271 245.522C22.0271 245.362 22.0271 245.362 22.0271 245.202C24.748 242.961 27.789 241.521 31.6303 241.681C31.9504 241.681 32.1104 241.521 32.2705 241.2C35.3115 243.601 37.7123 246.802 39.4729 250.323C42.834 257.206 44.9147 264.888 46.0351 272.731C43.3142 272.091 40.9134 270.65 38.9927 268.409C38.3525 267.769 37.3922 268.73 38.0324 269.37C38.9927 270.49 40.1131 271.29 41.2335 272.091C40.4332 272.091 39.6329 272.091 38.9927 271.931C38.1925 271.771 37.7123 273.051 38.6726 273.211C39.9531 273.371 41.2335 273.531 42.5139 273.371C42.834 273.371 42.9941 273.211 42.9941 273.051C43.9544 273.531 45.0748 273.851 46.0351 274.171H46.1951C46.6753 278.013 46.9954 281.694 47.1554 285.375C47.1554 286.175 48.5959 286.175 48.4359 285.375C48.2758 278.173 47.3155 270.81 45.5549 263.448Z" fill="#312890"/>
<path d="M67.6422 236.078C66.3618 236.878 65.2415 237.839 64.2811 238.799C64.9213 236.398 65.8817 234.157 67.3221 232.237C67.8023 231.597 66.6819 230.796 66.2018 231.597C64.4412 233.997 63.3208 236.878 62.6806 239.759C62.6806 239.919 62.6806 240.079 62.8407 240.239C59.7996 243.12 57.3988 246.482 55.3181 250.163C54.998 245.521 54.6779 240.88 54.3578 236.398C54.1978 233.197 53.8777 229.516 53.8777 225.675C55.4782 223.594 57.0787 221.513 59.4795 220.393C60.2798 220.073 59.6396 218.952 58.8393 219.272C56.7586 220.233 55.3182 221.833 53.8777 223.594C53.8777 221.833 53.8777 220.073 54.0377 218.312C54.1978 218.152 54.1978 217.992 54.0377 217.672C54.6779 208.229 57.5589 199.426 66.5219 195.264C67.3221 194.944 66.6819 193.824 65.8817 194.144C63.6409 195.264 61.7203 196.545 60.1197 198.145C60.1197 196.865 60.2798 195.585 60.76 194.304C61.0801 193.504 59.7996 193.184 59.4795 193.984C58.8393 195.745 58.6793 197.505 58.9994 199.426C55.1581 204.067 53.5576 210.149 53.0774 216.392C51.1568 214.151 49.2361 211.91 47.3155 209.669C47.4755 209.509 47.6356 209.349 47.6356 209.189C47.4755 207.268 46.9954 205.508 45.875 204.067C45.3949 203.427 44.2745 204.067 44.7546 204.708C45.5549 205.828 46.0351 207.108 46.1951 208.389C45.5549 207.589 44.7546 206.788 44.1144 205.828C43.4742 205.188 42.6739 206.148 43.1541 206.788C46.5152 210.63 49.7163 214.471 53.0774 218.312C52.9174 220.713 52.9173 222.954 52.9173 225.355C52.9173 225.355 52.9173 225.354 52.7573 225.515C52.5972 225.835 52.5972 226.155 52.9173 226.315C52.9173 228.556 53.0774 230.796 53.0774 232.877C53.5576 243.441 54.3578 254.164 55.4782 264.728C53.0774 263.447 51.797 260.886 50.5165 258.486C50.1964 257.685 48.916 258.325 49.3962 259.126C50.8367 261.847 52.2771 264.728 55.3181 266.008C55.4782 266.008 55.6383 266.008 55.6383 266.008C56.4385 272.73 57.2388 279.613 58.3592 286.335C58.5192 287.135 59.7996 286.815 59.6396 286.015C57.879 274.971 56.5986 263.767 55.6383 252.564C55.7983 252.564 55.7983 252.404 55.9584 252.243C58.9994 246.321 63.3208 241.36 68.6026 237.519C69.0827 236.718 68.2824 235.598 67.6422 236.078Z" fill="#312890"/>
<path d="M89.7296 237.198C86.8486 237.198 84.2878 237.838 82.047 238.959C83.0074 237.838 84.1277 236.878 85.2481 236.078C85.8883 235.598 85.2481 234.477 84.6079 234.957C82.3672 236.718 80.4465 238.639 78.846 240.879C78.846 241.039 78.6859 241.039 78.6859 241.2C74.2045 244.721 70.8433 250.163 68.7626 255.284C67.4822 258.485 66.5219 261.686 65.8817 264.887C65.0814 263.607 64.7613 262.167 64.2812 260.886C63.961 259.766 63.6409 258.805 62.5206 258.165C61.7203 257.685 61.0801 258.805 61.8804 259.286C63.0007 259.926 63.1608 261.846 63.6409 262.967C63.961 264.087 64.4412 265.047 65.0814 266.008C65.2415 266.168 65.4015 266.328 65.5616 266.328C63.9611 274.331 63.4809 282.813 62.6806 290.816C62.5206 291.616 63.9611 291.616 63.9611 290.816C64.7613 283.294 65.0814 275.611 66.5219 268.088C66.6819 268.088 66.6819 267.928 66.842 267.928C69.4028 265.208 71.9637 262.327 75.1648 260.406C76.1251 261.366 77.2455 262.006 78.5259 262.327C79.3261 262.647 79.6462 261.366 78.846 261.046C77.8857 260.726 77.0854 260.246 76.4452 259.606C77.4055 259.125 78.2058 258.805 79.1661 258.485C79.9664 258.165 79.6462 256.885 78.846 257.205C77.5656 257.525 76.2852 258.165 75.1648 258.805C75.0047 258.805 74.8447 258.965 74.6846 259.125C71.8037 260.886 69.4029 263.287 67.0021 265.688C67.4822 263.607 67.9624 261.526 68.6026 259.446C69.883 255.284 71.9637 250.643 74.8447 246.801C76.2851 246.321 77.8857 246.001 79.4862 245.681C80.2865 245.521 79.9664 244.241 79.1661 244.401C78.2058 244.561 77.2455 244.721 76.2851 245.041C79.8063 241.039 84.2878 238.159 89.8897 238.319C90.5299 238.479 90.5299 237.198 89.7296 237.198Z" fill="#312890"/>
<path d="M78.5259 278.653L77.5656 285.375L75.6449 297.219L71.4835 322.988H41.0734L36.912 297.219L35.1514 285.375L34.0311 278.653H78.5259Z" fill="#C8D3FB"/>
<path opacity="0.08" d="M46.6753 285.375L45.715 278.653H34.0311L35.1514 285.375L36.912 297.219L41.0734 322.988H52.7573L48.5959 297.219L46.6753 285.375Z" fill="black"/>
<path opacity="0.64" d="M67.9624 320.907C67.0021 320.907 66.5219 320.427 66.5219 319.946L71.8036 280.733C71.8036 280.253 72.6039 279.933 73.4042 279.933C74.2044 279.933 74.8447 280.413 74.6846 280.893L69.4028 320.106C69.2428 320.587 68.6026 320.907 67.9624 320.907Z" fill="white"/>
<path d="M289.796 285.695C289.796 292.577 284.514 298.179 277.952 298.179H165.115C158.553 298.179 153.271 292.577 153.271 285.695V52.4973C153.271 45.615 158.553 40.0132 165.115 40.0132H277.952C284.514 40.0132 289.796 45.615 289.796 52.4973V285.695Z" fill="url(#paint3_linear_6328_5608)"/>
<path d="M289.956 28.0093L206.408 28.4894V39.8532L248.663 40.0133L278.752 40.1733C288.836 40.1733 297.159 48.8162 297.159 59.5398L296.839 279.133C296.839 289.696 288.516 298.339 278.432 298.339L205.928 298.499V322.347L289.476 323.147C299.559 323.147 307.882 314.505 307.882 303.941L308.362 47.3757C308.362 36.6522 300.2 28.0093 289.956 28.0093Z" fill="#1C0A76"/>
<path d="M283.714 27.8491C283.234 27.8491 282.914 27.8491 282.434 27.8491H154.071C147.509 27.8491 142.227 33.451 142.067 40.3333V310.503C142.067 317.385 147.349 322.987 153.911 322.987H282.274C282.754 322.987 283.074 322.987 283.554 322.987C293.157 322.347 300.68 314.024 300.68 303.781V47.2156C300.84 36.9722 293.317 28.6494 283.714 27.8491ZM289.796 285.695C289.796 292.577 284.514 298.179 277.792 298.179H164.955C158.392 298.179 153.111 292.577 153.111 285.695V52.4973C153.111 45.615 158.392 40.0132 164.955 40.0132H277.792C284.354 40.0132 289.636 45.615 289.636 52.4973L289.796 285.695Z" fill="url(#paint4_linear_6328_5608)"/>
<path d="M236.498 316.425H205.928C202.887 316.425 200.326 313.864 200.326 310.663C200.326 307.462 202.887 304.901 205.928 304.901H236.498C239.539 304.901 242.1 307.462 242.1 310.663C242.1 313.864 239.539 316.425 236.498 316.425Z" fill="#1C0A76"/>
<mask id="mask1_6328_5608" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="109" y="40" width="181" height="259">
<path d="M289.796 285.695C289.796 292.577 284.514 298.179 277.952 298.179H165.115C158.553 298.179 109.096 149.009 109.096 142.127L153.271 52.4973C153.271 45.615 158.553 40.0132 165.115 40.0132H277.952C284.514 40.0132 289.796 45.615 289.796 52.4973V285.695Z" fill="white"/>
</mask>
<g mask="url(#mask1_6328_5608)">
<path d="M223.694 122.92C220.653 129.162 201.127 146.288 197.445 149.969C192.804 154.451 185.762 150.929 186.722 145.168C187.522 140.206 208.969 115.558 212.17 113.157C217.772 109.156 227.535 115.078 223.694 122.92Z" fill="#FFD2A7"/>
<path d="M209.129 142.447C215.531 136.045 224.334 122.92 225.935 119.719C229.776 111.877 220.013 105.955 214.251 110.116C212.49 111.397 202.567 121.64 195.685 130.923C195.685 134.284 202.407 142.287 209.129 142.447Z" fill="#D35600"/>
<path d="M138.386 150.609C143.187 148.369 143.187 143.247 147.989 142.927C152.631 142.607 154.551 141.647 155.832 144.688C157.112 147.729 154.391 148.849 148.949 151.41C143.668 154.131 131.343 154.131 138.386 150.609Z" fill="#FFD2A7"/>
<path d="M194.725 154.611C184.641 155.411 154.231 147.409 148.629 149.649C147.029 150.29 149.429 141.967 155.031 142.927C162.074 144.048 181.44 139.886 191.523 140.526C201.447 141.167 201.447 153.971 194.725 154.611Z" fill="#FFD2A7"/>
<path d="M207.369 191.584C209.449 182.14 215.051 175.738 216.972 174.138C220.013 171.417 228.816 171.737 232.337 178.939C235.858 186.142 237.139 190.463 236.178 203.588C235.218 216.552 224.494 261.047 224.334 270.81C224.334 280.573 204.008 279.453 205.128 265.528C206.248 251.443 204.968 202.627 207.369 191.584Z" fill="#3B31A1"/>
<path d="M236.338 194.304C236.178 187.742 234.738 184.061 232.177 178.939C230.256 174.938 226.575 173.017 223.374 172.697C223.214 172.697 222.894 172.697 222.734 172.697C222.574 172.697 222.414 172.697 222.254 172.697C221.774 172.697 221.133 172.697 220.653 172.857C220.013 173.017 219.373 173.017 218.733 173.337C218.412 173.498 218.252 173.498 217.932 173.658C217.772 173.658 217.612 173.818 217.612 173.818C217.452 173.978 217.132 174.138 216.972 174.298C216.812 174.458 216.652 174.458 216.492 174.618C216.492 174.618 216.332 174.778 216.172 174.938C216.172 174.938 216.172 174.938 216.012 175.098L215.852 175.258C215.852 175.258 215.852 175.258 215.692 175.418L215.531 175.578C215.531 175.578 215.531 175.578 215.371 175.738C215.211 175.898 214.891 176.218 214.731 176.539C214.731 176.539 214.731 176.699 214.571 176.699C214.411 176.859 214.411 176.859 214.251 177.019L214.091 177.179C213.931 177.339 213.931 177.339 213.771 177.499C213.771 177.499 213.771 177.659 213.611 177.659C213.291 177.979 213.131 178.299 212.811 178.779C212.811 178.779 212.811 178.939 212.651 178.939C212.49 179.099 212.49 179.259 212.33 179.419L212.17 179.58C212.01 179.74 212.01 179.9 211.85 180.06C211.85 180.06 211.85 180.22 211.69 180.22C211.37 180.7 211.21 181.02 210.89 181.5C210.89 181.5 210.89 181.66 210.73 181.66C210.57 181.82 210.57 181.98 210.41 182.14C210.41 182.3 210.25 182.3 210.25 182.461C210.09 182.621 210.09 182.781 209.93 182.941C209.93 182.941 209.93 183.101 209.77 183.101C209.609 183.421 209.449 183.581 209.449 183.901C209.289 184.221 209.129 184.381 209.129 184.701C209.129 184.861 209.129 184.861 208.969 185.021C208.809 185.181 208.809 185.341 208.649 185.662C208.649 185.822 208.489 185.822 208.489 185.982C208.329 186.142 208.329 186.462 208.169 186.622C208.169 186.782 208.169 186.782 208.009 186.942C207.849 187.262 207.849 187.582 207.689 187.902C207.529 188.222 207.529 188.543 207.369 188.863C207.369 189.023 207.369 189.023 207.209 189.183C207.209 189.343 207.049 189.663 207.049 189.823C207.049 189.983 207.049 189.983 206.889 190.143C206.889 190.303 206.729 190.623 206.729 190.783C206.729 190.943 206.729 190.943 206.568 191.103C206.408 191.423 206.408 191.744 206.408 192.064C206.408 192.224 206.408 192.384 206.248 192.704V192.864C206.248 193.024 206.248 193.184 206.248 193.344C206.248 193.504 206.248 193.504 206.248 193.664C206.248 193.824 206.248 193.984 206.248 194.144C206.248 194.304 206.248 194.304 206.248 194.465C206.248 194.625 206.248 194.785 206.248 194.945C206.248 195.105 206.248 195.105 206.248 195.265C206.248 195.425 206.248 195.745 206.248 195.905V196.065C206.248 196.705 206.088 197.345 206.088 197.986V198.146C206.088 198.466 206.088 198.626 206.088 198.946C206.088 199.106 206.088 199.106 206.088 199.266C206.088 199.586 206.088 199.746 206.088 200.066C206.088 200.226 206.088 200.226 206.088 200.386C206.088 200.707 206.088 201.027 206.088 201.347V201.507C206.088 201.827 206.088 202.307 206.088 202.627C206.088 203.908 205.928 205.188 205.928 206.629C205.928 206.629 205.928 206.629 205.928 206.789C205.928 207.269 205.928 207.589 205.928 208.069C205.928 208.069 205.928 208.069 205.928 208.229C205.928 208.709 205.928 209.189 205.928 209.67C214.571 215.752 229.456 215.752 228.976 220.073C228.816 221.994 222.414 264.248 221.774 265.848C221.613 266.008 222.894 272.09 224.334 272.09C224.334 271.77 224.334 271.61 224.334 271.29C224.334 261.687 234.738 218.472 236.018 204.708C236.018 204.548 236.018 204.228 236.018 204.068C236.178 201.987 236.338 200.226 236.338 198.626C236.498 196.705 236.498 195.425 236.338 194.304Z" fill="#1C0A76"/>
<path d="M256.185 191.743C252.504 182.14 245.782 175.738 243.541 173.977C240.02 171.256 231.377 171.416 229.136 178.619C226.895 185.821 226.415 190.143 229.616 203.267C232.817 216.391 245.141 260.886 246.902 270.81C248.662 280.573 266.909 272.89 264.828 258.485C262.427 242.64 260.506 202.787 256.185 191.743Z" fill="#3B31A1"/>
<path d="M236.178 211.11C240.66 210.31 247.862 209.189 249.463 209.67C252.824 210.63 255.545 213.671 255.545 217.352C255.545 221.674 262.267 262.647 262.267 262.807C262.907 262.167 264.028 261.367 264.988 260.246C264.988 259.606 264.988 258.966 264.828 258.326C262.427 242.481 260.506 202.787 256.345 191.584C252.984 182.941 247.062 176.699 244.341 174.458C244.021 174.298 243.861 173.978 243.541 173.818C240.02 171.097 231.377 171.257 229.136 178.459C226.895 185.662 226.415 189.983 229.616 203.107C229.776 203.748 229.616 209.029 230.416 210.95C231.057 213.191 233.938 211.43 236.178 211.11Z" fill="#1C0A76"/>
<path d="M269.629 318.506C269.629 318.506 268.669 318.826 267.069 319.146C264.508 319.626 260.346 320.266 257.625 318.986C257.625 318.986 246.582 279.453 246.582 269.529C246.582 254.164 254.424 251.604 260.827 254.965C260.987 255.125 261.307 255.125 261.467 255.285C261.467 255.285 261.467 255.285 261.627 255.285C261.947 255.445 262.267 255.605 262.427 255.765C262.747 255.925 263.067 256.245 263.227 256.405C263.547 256.725 263.708 256.885 264.028 257.365C265.308 259.286 266.108 262.647 266.588 267.129V267.289C268.029 280.093 267.069 301.06 269.149 317.866C269.629 318.346 269.629 318.346 269.629 318.506Z" fill="#3B31A1"/>
<path d="M215.852 318.346C215.051 318.666 214.251 318.826 213.291 318.986C209.129 319.306 204.008 317.385 204.008 317.385C205.128 295.458 202.567 268.569 206.568 264.248C211.05 259.286 218.252 258.646 222.414 265.688C222.734 266.168 222.894 266.488 223.054 266.969C223.214 267.289 223.374 267.609 223.374 267.769C223.694 268.569 224.014 269.369 224.174 270.17C224.334 270.81 224.494 271.61 224.494 272.57C225.135 284.414 215.852 318.346 215.852 318.346Z" fill="#3B31A1"/>
<path d="M221.774 293.058C219.533 303.461 216.972 313.704 215.852 318.346C215.051 318.666 214.251 318.826 213.291 318.986C214.251 300.9 222.094 266.649 222.254 265.528C222.574 266.008 222.734 266.329 222.894 266.809C223.054 267.129 223.214 267.449 223.214 267.609C223.534 268.409 223.854 269.21 224.014 270.01C224.174 270.65 224.334 271.45 224.334 272.411C224.655 277.052 223.374 285.055 221.774 293.058Z" fill="#1C0A76"/>
<path d="M269.629 318.505C269.629 318.505 268.669 318.826 267.069 319.146C266.108 310.823 264.668 291.136 264.828 282.013C264.988 272.09 261.787 258.325 260.987 254.964C261.147 255.124 261.467 255.124 261.627 255.284C261.627 255.284 261.627 255.284 261.787 255.284C262.107 255.445 262.427 255.605 262.587 255.765C262.907 255.925 263.227 256.245 263.387 256.405C263.707 256.725 263.868 256.885 264.188 257.365C265.468 259.286 266.268 262.647 266.748 267.128V267.288C268.189 280.093 267.709 301.22 269.309 317.865C269.629 318.345 269.629 318.345 269.629 318.505Z" fill="#1C0A76"/>
<path d="M257.145 190.943C257.145 190.943 219.853 206.308 205.128 188.062C205.128 188.062 205.928 119.079 211.53 112.037C216.172 106.115 226.095 107.395 226.095 107.395C226.095 107.395 229.136 105.314 228.656 99.8727C227.375 86.7483 239.7 96.1915 239.7 96.1915C239.7 96.1915 236.819 107.075 241.78 107.555C243.541 107.715 245.942 108.195 248.182 108.516C251.063 108.996 255.705 111.397 255.705 111.397C257.145 112.357 258.906 115.718 259.066 116.038C259.066 116.198 259.066 116.358 259.226 116.518C259.226 116.678 259.386 116.998 259.386 117.158C261.147 127.882 260.987 165.975 257.145 190.943Z" fill="url(#paint5_linear_6328_5608)"/>
<path d="M259.066 117.319C259.066 116.999 258.906 116.839 258.906 116.679C258.906 116.519 258.906 116.359 258.746 116.199C258.746 116.039 252.984 110.917 250.583 121.641C248.342 132.204 244.341 169.016 205.128 188.383C220.013 206.309 257.145 191.104 257.145 191.104C260.987 165.975 261.147 127.883 259.066 117.319Z" fill="#D35600"/>
<path d="M239.379 97.6319C239.539 96.6715 239.7 96.1914 239.7 96.1914C239.7 96.1914 229.776 88.6689 228.656 96.5115L239.379 97.6319Z" fill="url(#paint6_linear_6328_5608)"/>
<path d="M245.621 108.195C241.14 114.758 234.098 117.959 228.176 115.558C224.815 114.117 222.414 111.076 221.453 107.395C224.174 107.075 226.255 107.395 226.255 107.395C226.255 107.395 229.296 105.314 228.816 99.8727C227.535 86.7483 239.86 96.1915 239.86 96.1915C239.86 96.1915 236.979 107.075 241.94 107.555C242.741 107.715 244.181 107.875 245.621 108.195Z" fill="#FFD2A7"/>
<path d="M220.823 85.7936L220.772 86.271L224.75 86.6995L224.801 86.2222L220.823 85.7936Z" fill="#002DAA"/>
<path d="M223.854 78.4258L222.254 93.7909C221.774 98.2724 225.295 102.434 230.096 102.914C234.898 103.394 239.219 100.193 239.7 95.5515V95.2314C239.7 95.2314 244.661 95.3914 245.301 90.4298C245.782 85.3081 242.26 87.0687 242.26 87.0687L242.901 80.3464L223.854 78.4258Z" fill="#FFD2A7"/>
<path d="M242.1 87.2286L242.741 80.5063L236.018 79.7061V79.8661L234.098 97.3119C233.778 100.353 230.576 102.594 227.696 102.114C226.735 101.953 225.935 101.633 225.295 101.153C226.575 102.114 228.176 102.754 229.936 103.074C234.738 103.554 239.059 100.353 239.539 95.7114V95.3913C239.539 95.3913 244.501 95.5513 245.141 90.5897C245.782 85.468 242.1 87.2286 242.1 87.2286Z" fill="#FFBC8E"/>
<path d="M242.1 87.3886C242.1 87.3886 240.18 91.71 239.86 86.1081C239.539 80.5063 237.779 80.5063 231.537 80.3462C225.295 80.0261 216.972 76.8251 221.133 69.6227C225.135 62.5803 237.779 69.4626 237.779 69.4626C237.779 69.4626 247.702 67.542 248.502 75.3846C249.143 83.0671 242.1 87.3886 242.1 87.3886Z" fill="#1C0A76"/>
<path d="M233.297 92.1903C231.857 92.0303 230.897 91.0699 230.576 90.2697C230.096 89.3094 229.776 88.189 229.936 87.0686C230.096 85.308 231.697 84.5078 234.098 84.8279C236.658 85.148 237.939 86.2683 237.779 88.0289C237.619 89.7895 236.018 92.3504 233.297 92.1903C233.457 92.1903 233.457 92.1903 233.297 92.1903ZM230.416 87.0686C230.256 88.0289 230.576 89.1493 231.057 90.1096C231.377 90.7498 232.177 91.7102 233.457 91.8702C235.858 92.0303 237.139 89.6295 237.299 87.8689C237.459 85.9482 235.698 85.308 234.098 85.148H233.938C232.337 84.9879 230.576 85.148 230.416 87.0686Z" fill="#002DAA"/>
<path d="M224.014 91.0702C221.293 90.7501 220.333 87.8691 220.653 85.9485C220.813 84.1879 222.414 83.3876 224.815 83.7077C227.375 84.0278 228.656 85.1482 228.496 86.9088C228.176 88.6694 226.735 91.3903 224.014 91.0702ZM220.973 86.1085C220.813 87.8691 221.614 90.59 224.014 90.7501C226.415 91.0702 227.856 88.5093 228.016 86.7487C228.176 84.8281 226.415 84.1879 224.815 84.0278H224.655C222.894 84.0278 221.133 84.1879 220.973 86.1085Z" fill="#002DAA"/>
<path d="M228.183 86.2082L228.132 86.6855L230.041 86.8916L230.093 86.4143L228.183 86.2082Z" fill="#002DAA"/>
<path d="M237.511 87.6657L237.459 88.1431L241.437 88.5724L241.489 88.0951L237.511 87.6657Z" fill="#002DAA"/>
<path d="M156.152 122.28C156.152 122.28 153.431 117.159 147.189 114.438C147.189 114.438 147.189 111.237 147.829 110.276C147.829 110.436 157.112 114.598 156.152 122.28Z" fill="#1C0A76"/>
<path d="M156.152 122.281C156.152 122.281 149.429 122.441 145.748 118.599C145.108 117.959 144.148 116.679 143.507 115.558C143.507 115.558 143.507 115.398 143.347 115.398C143.187 115.078 143.347 114.598 143.507 114.278C144.148 113.318 146.228 111.077 147.829 110.597C147.829 110.597 148.149 111.237 148.629 112.197C148.789 112.677 149.109 113.158 149.429 113.638C149.91 114.598 150.71 115.718 151.51 116.999C151.99 117.639 152.47 118.439 152.951 119.08C153.911 120.04 155.031 121.16 156.152 122.281Z" fill="#3B31A1"/>
<path d="M155.992 122.441C155.992 122.441 159.833 117.959 166.395 116.359C166.395 116.359 167.035 113.318 166.555 112.197C166.555 112.197 156.792 114.598 155.992 122.441Z" fill="#1C0A76"/>
<path d="M169.756 117.639C169.756 117.639 169.756 117.799 169.596 117.799C168.956 118.599 168.316 119.24 167.676 119.72C167.355 119.88 167.195 120.2 166.875 120.36C166.875 120.36 165.595 121.16 164.955 121.48C160.633 123.561 155.992 122.281 155.992 122.281C157.432 121.48 158.713 120.52 159.993 119.4C160.633 118.759 161.273 118.279 161.914 117.639C162.874 116.679 163.674 115.878 164.314 115.078C164.635 114.758 164.955 114.438 165.115 114.118C166.075 112.998 166.555 112.197 166.555 112.197C167.836 112.998 169.436 115.558 169.916 116.519C170.076 116.839 170.076 117.319 169.756 117.639Z" fill="#3B31A1"/>
<path d="M155.992 122.121C155.992 122.121 159.193 115.239 157.112 107.236C157.112 107.236 160.473 104.675 162.074 104.515C161.914 104.355 164.955 116.519 155.992 122.121Z" fill="#1C0A76"/>
<path d="M161.914 104.355C161.914 104.355 160.153 107.076 158.553 111.077C158.072 112.197 157.592 113.478 157.272 114.918C156.632 117.159 156.152 119.56 155.832 121.961C155.832 121.961 150.23 115.559 151.99 107.876C152.31 106.916 152.631 105.795 153.111 104.835C153.271 104.675 153.271 104.355 153.431 104.195C153.591 103.875 153.911 103.555 154.391 103.555C155.832 103.395 159.993 103.234 161.914 104.355Z" fill="#3B31A1"/>
<path d="M156.792 120.2C155.832 119.88 154.711 120.2 154.071 121C154.071 121.16 153.911 121.16 153.911 121.32C153.431 122.441 153.911 123.561 155.191 124.041C156.312 124.521 157.592 124.041 158.072 122.921C158.232 122.761 158.232 122.441 158.232 122.281C158.232 121.48 157.752 120.68 156.792 120.2Z" fill="#1C0A76"/>
<path d="M192.004 128.363H146.549V163.254H192.004V128.363Z" fill="#D35600"/>
<path d="M182.56 128.363H126.382V163.254H182.56V128.363Z" fill="url(#paint7_linear_6328_5608)"/>
<path opacity="0.08" d="M192.164 124.201H126.382V136.845H192.164V124.201Z" fill="black"/>
<path d="M193.444 122.44H146.549V135.085H193.444V122.44Z" fill="#D35600"/>
<path d="M183.201 122.44H124.941V135.085H183.201V122.44Z" fill="url(#paint8_linear_6328_5608)"/>
<path d="M155.992 122.44H152.951V163.254H155.992V122.44Z" fill="#3B31A1"/>
<path d="M189.123 122.44H187.682V163.254H189.123V122.44Z" fill="#3B31A1"/>
<path d="M157.592 122.441C157.592 122.441 163.514 127.082 163.834 134.925C163.834 134.925 161.914 137.486 158.873 135.885C158.873 135.885 159.353 128.683 156.792 122.441C156.952 122.441 157.272 122.121 157.592 122.441Z" fill="#3B31A1"/>
<path d="M155.992 126.122C155.351 128.043 154.231 129.643 152.951 131.084V138.446C154.071 138.606 155.031 138.606 155.031 138.606C155.351 137.806 155.672 137.166 155.992 136.365V126.122Z" fill="#1C0A76"/>
<path d="M156.472 122.6C156.472 122.6 157.752 130.443 154.391 137.325C154.391 137.325 148.789 137.325 147.989 133.964C147.989 133.964 155.191 128.842 155.992 122.28C155.992 122.28 156.472 122.28 156.472 122.6Z" fill="#3B31A1"/>
<path d="M255.545 125.002C252.504 131.244 232.977 148.369 229.296 152.211C224.815 156.692 217.612 153.171 218.572 147.409C219.373 142.447 240.82 117.799 243.861 115.398C249.623 111.237 259.386 117.159 255.545 125.002Z" fill="#FFD2A7"/>
<path d="M240.98 144.528C247.382 138.126 256.185 125.002 257.786 121.8C261.627 113.958 251.864 108.036 246.102 112.197C244.341 113.478 234.418 123.721 227.535 133.004C227.375 136.365 234.258 144.368 240.98 144.528Z" fill="url(#paint9_linear_6328_5608)"/>
<path d="M159.193 157.172C164.154 155.412 164.795 150.45 169.596 150.61C174.398 150.77 176.158 150.13 177.119 153.331C178.079 156.532 175.198 157.332 169.596 159.253C163.994 161.334 151.83 159.893 159.193 157.172Z" fill="#FFD2A7"/>
<path d="M225.295 155.091C215.531 157.492 175.838 155.891 170.556 159.092C169.116 160.053 170.076 151.41 175.838 151.41C182.881 151.41 209.77 142.607 219.853 141.647C229.776 140.686 231.857 153.491 225.295 155.091Z" fill="#FFD2A7"/>
<path d="M230.737 149.97C230.737 149.97 226.895 154.131 225.775 154.291C224.654 154.611 220.173 146.609 220.173 146.609L221.934 142.127L223.054 141.007C223.054 141.007 225.935 139.086 228.176 141.487C230.096 143.888 230.737 149.97 230.737 149.97Z" fill="#FFD2A7"/>
<path d="M176.318 151.891C176.318 151.891 174.878 151.411 174.238 151.411C173.598 151.411 168.796 154.292 169.596 158.933C169.596 158.933 170.396 158.453 171.197 158.133C171.997 157.813 175.838 154.932 176.158 153.971C176.639 153.011 176.318 151.891 176.318 151.891Z" fill="#FFD2A7"/>
</g>
<path d="M289.796 56.8186H153.111V44.6545C153.111 41.9336 155.191 39.6929 157.912 39.6929H284.995C287.555 39.6929 289.796 41.9336 289.796 44.6545V56.8186Z" fill="#1C0A76"/>
<path d="M179.199 48.3353C179.199 46.8948 180.32 45.7744 181.76 45.7744C183.201 45.7744 184.321 46.8948 184.321 48.3353C184.321 49.7757 183.201 50.8961 181.76 50.8961C180.32 50.8961 179.199 49.7757 179.199 48.3353Z" fill="white"/>
<path d="M169.596 48.3353C169.596 46.8948 170.717 45.7744 172.157 45.7744C173.597 45.7744 174.718 46.8948 174.718 48.3353C174.718 49.7757 173.597 50.8961 172.157 50.8961C170.717 50.8961 169.596 49.7757 169.596 48.3353Z" fill="#C8D3FB"/>
<path d="M159.993 48.3353C159.993 46.8948 161.113 45.7744 162.554 45.7744C163.994 45.7744 165.115 46.8948 165.115 48.3353C165.115 49.7757 163.994 50.8961 162.554 50.8961C161.113 50.8961 159.993 49.7757 159.993 48.3353Z" fill="url(#paint10_linear_6328_5608)"/>
<path d="M277.792 46.4147L279.073 45.1343L280.833 46.8949L282.594 45.1343L283.874 46.4147L282.114 48.1753L283.874 50.0959L282.594 51.3764L280.833 49.4557L279.073 51.3764L277.792 50.0959L279.553 48.1753L277.792 46.4147Z" fill="white"/>
<path d="M131.664 57.939H155.351L165.915 39.853H148.629C146.869 39.853 145.268 40.4932 144.148 41.6136L131.664 57.939Z" fill="url(#paint11_linear_6328_5608)"/>
<path d="M179.199 57.9389L185.922 39.6929H166.075L155.351 57.9389H179.199Z" fill="url(#paint12_linear_6328_5608)"/>
<path d="M179.199 57.9389H202.887L208.329 39.6929H185.922L179.199 57.9389Z" fill="url(#paint13_linear_6328_5608)"/>
<path d="M130.863 65.941C130.383 71.2228 135.665 75.3842 142.547 75.0641C148.949 74.904 154.231 70.5826 154.711 65.6209L155.351 57.7783H131.664L130.863 65.941Z" fill="#D35600"/>
<path d="M154.711 66.2612C154.231 71.0628 158.873 74.9041 165.115 74.9041H166.555C172.637 74.9041 178.079 71.0628 178.559 66.2612L179.359 57.9385H155.672L154.711 66.2612Z" fill="#C8D3FB"/>
<path d="M178.399 66.5813C177.919 71.3829 182.56 75.2242 188.803 75.2242H190.243C196.325 75.2242 201.767 71.3829 202.247 66.5813L203.047 57.9385H179.359L178.399 66.5813Z" fill="#D35600"/>
<path d="M297.959 57.939H274.271L275.391 39.853H294.118C295.878 39.853 297.319 40.4932 298.279 41.6136L297.959 57.939Z" fill="url(#paint14_linear_6328_5608)"/>
<path d="M274.111 57.9389L275.391 39.6929H252.504L250.423 57.9389H274.111Z" fill="url(#paint15_linear_6328_5608)"/>
<path d="M250.423 57.9389H226.575L230.096 39.6929H252.504L250.423 57.9389Z" fill="url(#paint16_linear_6328_5608)"/>
<path d="M226.575 57.9389L230.096 39.6929H207.689L202.887 57.9389H226.575Z" fill="url(#paint17_linear_6328_5608)"/>
<path d="M297.159 65.941C296.678 71.2228 290.596 75.3842 283.874 75.0641C277.472 74.904 272.991 70.5826 273.471 65.6209L274.111 57.7783H297.799L297.159 65.941Z" fill="#D35600"/>
<path d="M273.471 66.2612C272.991 71.0628 267.709 74.9041 261.467 74.9041H260.026C253.944 74.9041 249.303 71.0628 249.623 66.2612L250.423 57.9385H274.111L273.471 66.2612Z" fill="#C8D3FB"/>
<path d="M249.623 66.5813C249.143 71.3829 243.861 75.2242 237.619 75.2242H236.178C230.096 75.2242 225.455 71.3829 225.775 66.5813L226.575 57.9385H250.263L249.623 66.5813Z" fill="#D35600"/>
<path d="M225.935 66.2612C225.455 71.0628 220.173 74.9041 213.931 74.9041H212.49C206.408 74.9041 201.767 71.0628 202.087 66.2612L202.887 57.9385H226.575L225.935 66.2612Z" fill="#C8D3FB"/>
<path d="M273.951 34.5715H170.877C169.116 34.5715 167.836 33.131 167.836 31.5305V3.04101C167.836 1.28043 169.276 0 170.877 0H273.951C275.711 0 276.992 1.44048 276.992 3.04101V31.5305C276.992 33.131 275.551 34.5715 273.951 34.5715Z" fill="#B84B00"/>
<path d="M271.71 32.6511H172.637C171.037 32.6511 169.756 31.3707 169.756 29.7702V4.80186C169.756 3.20132 171.037 1.9209 172.637 1.9209H271.55C273.151 1.9209 274.431 3.20132 274.431 4.80186V29.7702C274.591 31.3707 273.311 32.6511 271.71 32.6511Z" fill="#1C0A76"/>
<path d="M272.19 34.5715H169.116C167.355 34.5715 166.075 33.131 166.075 31.5305V3.04101C166.075 1.28043 167.515 0 169.116 0H272.19C273.951 0 275.231 1.44048 275.231 3.04101V31.5305C275.231 33.131 273.951 34.5715 272.19 34.5715Z" fill="#D35600"/>
<path d="M269.95 32.6511H171.037C169.436 32.6511 168.156 31.3707 168.156 29.7702V4.80186C168.156 3.20132 169.436 1.9209 171.037 1.9209H269.95C271.55 1.9209 272.831 3.20132 272.831 4.80186V29.7702C272.831 31.3707 271.55 32.6511 269.95 32.6511Z" fill="url(#paint18_linear_6328_5608)"/>
<path d="M184.161 20.6466L188.002 20.3265C188.162 21.6069 188.643 22.5673 189.443 23.2075C190.083 23.8477 191.203 24.1678 192.324 24.1678C193.604 24.1678 194.565 23.8477 195.205 23.3675C195.845 22.8874 196.165 22.2472 196.165 21.4469C196.165 20.9667 196.005 20.6466 195.685 20.3265C195.365 20.0064 194.885 19.6863 194.244 19.5262C193.764 19.3662 192.644 19.0461 191.043 18.726C188.963 18.2458 187.362 17.6056 186.562 16.8053C185.281 15.685 184.801 14.4045 184.801 12.804C184.801 11.8437 185.121 10.8834 185.602 9.92305C186.242 8.96274 187.042 8.32252 188.162 7.84236C189.283 7.3622 190.563 7.20215 192.004 7.20215C194.565 7.20215 196.325 7.68231 197.606 8.80268C198.886 9.92305 199.526 11.3635 199.526 13.1241L195.525 13.2842C195.365 12.3239 195.045 11.5236 194.404 11.0434C193.764 10.5633 192.964 10.4032 191.844 10.4032C190.723 10.4032 189.763 10.7233 189.123 11.0434C188.643 11.3635 188.482 11.6836 188.482 12.3239C188.482 12.804 188.643 13.1241 189.123 13.6043C189.603 14.0844 190.883 14.4045 192.804 14.8847C194.725 15.3649 196.165 15.845 197.125 16.3252C198.086 16.8053 198.726 17.4456 199.366 18.4059C199.846 19.2061 200.166 20.3265 200.166 21.6069C200.166 22.7273 199.846 23.8477 199.206 24.808C198.566 25.7683 197.605 26.5686 196.485 27.0488C195.365 27.5289 193.924 27.849 192.164 27.849C189.603 27.849 187.682 27.2088 186.402 26.0884C185.121 24.648 184.321 22.8874 184.161 20.6466Z" fill="white"/>
<path d="M203.688 27.2084V7.36182H207.689V15.2044H215.531V7.36182H219.533V27.2084H215.531V18.5655H207.689V27.2084H203.688Z" fill="white"/>
<path d="M222.894 17.2853C222.894 15.2046 223.214 13.6041 223.854 12.1636C224.334 11.2033 224.975 10.243 225.775 9.44269C226.575 8.64242 227.375 8.00221 228.336 7.6821C229.616 7.20194 231.057 6.88184 232.657 6.88184C235.538 6.88184 237.939 7.84216 239.699 9.60274C241.46 11.3633 242.26 13.9242 242.26 17.1252C242.26 20.3263 241.46 22.8872 239.699 24.6477C237.939 26.4083 235.698 27.3687 232.657 27.3687C229.776 27.3687 227.375 26.4083 225.615 24.6477C223.694 23.0472 222.894 20.4864 222.894 17.2853ZM227.055 17.2853C227.055 19.526 227.535 21.2866 228.656 22.407C229.616 23.5274 231.057 24.1676 232.657 24.1676C234.258 24.1676 235.538 23.5274 236.658 22.407C237.619 21.2866 238.259 19.526 238.259 17.2853C238.259 15.0446 237.779 13.284 236.819 12.1636C235.858 11.0432 234.418 10.403 232.817 10.403C231.217 10.403 229.776 11.0432 228.816 12.1636C227.535 13.284 227.055 14.8845 227.055 17.2853Z" fill="white"/>
<path d="M245.301 27.2084V7.36182H251.703C254.104 7.36182 255.705 7.52187 256.505 7.68192C257.625 8.00203 258.586 8.64224 259.386 9.60256C260.186 10.5629 260.506 11.8433 260.506 13.4438C260.506 14.7243 260.346 15.6846 259.866 16.4848C259.386 17.2851 258.906 17.9253 258.106 18.4055C257.465 18.8856 256.665 19.2058 256.025 19.3658C255.065 19.5259 253.624 19.6859 251.864 19.6859H249.303V27.2084H245.301ZM249.303 10.7229V16.3248H251.543C253.144 16.3248 254.104 16.1647 254.745 16.0047C255.225 15.8446 255.705 15.5245 256.025 15.0444C256.345 14.5642 256.505 14.0841 256.505 13.4438C256.505 12.6436 256.345 12.1634 255.865 11.6833C255.385 11.2031 254.905 10.883 254.264 10.883C253.784 10.7229 252.824 10.7229 251.383 10.7229H249.303Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_6328_5608" x1="-27.7332" y1="225.788" x2="330.786" y2="106.282" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#D3DBEB"/>
</linearGradient>
<linearGradient id="paint1_linear_6328_5608" x1="29.5" y1="361.264" x2="413.628" y2="230.02" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#D3DBEB"/>
</linearGradient>
<linearGradient id="paint2_linear_6328_5608" x1="-141.067" y1="162.557" x2="459.878" y2="162.557" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#D3DBEB"/>
</linearGradient>
<linearGradient id="paint3_linear_6328_5608" x1="208.103" y1="180.706" x2="397.741" y2="15.6782" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#D3DBEB"/>
</linearGradient>
<linearGradient id="paint4_linear_6328_5608" x1="204.238" y1="188.606" x2="421.504" y2="-0.46478" gradientUnits="userSpaceOnUse">
<stop stop-color="#6A6AE8"/>
<stop offset="1" stop-color="#312890"/>
</linearGradient>
<linearGradient id="paint5_linear_6328_5608" x1="226.33" y1="186.258" x2="246.709" y2="93.3774" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint6_linear_6328_5608" x1="207.673" y1="92.2687" x2="267.874" y2="98.7539" gradientUnits="userSpaceOnUse">
<stop offset="1.09e-06" stop-color="#FFD000"/>
<stop offset="1" stop-color="#FF7400"/>
</linearGradient>
<linearGradient id="paint7_linear_6328_5608" x1="126.348" y1="145.853" x2="182.506" y2="145.853" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint8_linear_6328_5608" x1="124.89" y1="128.771" x2="183.12" y2="128.771" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint9_linear_6328_5608" x1="215.737" y1="180.386" x2="258.767" y2="95.5905" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint10_linear_6328_5608" x1="159.966" y1="48.2786" x2="164.98" y2="48.2786" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint11_linear_6328_5608" x1="131.357" y1="48.8147" x2="166.247" y2="47.5971" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint12_linear_6328_5608" x1="155.113" y1="48.8146" x2="186.147" y2="47.7315" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#D3DBEB"/>
</linearGradient>
<linearGradient id="paint13_linear_6328_5608" x1="178.871" y1="48.8146" x2="208.561" y2="47.7785" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint14_linear_6328_5608" x1="273.85" y1="48.8147" x2="298.27" y2="47.9625" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint15_linear_6328_5608" x1="250.043" y1="48.81" x2="275.612" y2="47.9176" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#D3DBEB"/>
</linearGradient>
<linearGradient id="paint16_linear_6328_5608" x1="226.335" y1="48.8146" x2="252.722" y2="47.8937" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
<linearGradient id="paint17_linear_6328_5608" x1="202.628" y1="48.8159" x2="230.375" y2="47.8475" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#D3DBEB"/>
</linearGradient>
<linearGradient id="paint18_linear_6328_5608" x1="168.151" y1="17.2353" x2="272.844" y2="17.2353" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFAE00"/>
<stop offset="1" stop-color="#FF7800"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -0,0 +1,29 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class TokenStorageService {
final _storage = const FlutterSecureStorage();
static const _accessTokenKey = 'access_token';
static const _refreshTokenKey = 'refresh_token';
Future<void> saveTokens({
required String accessToken,
required String refreshToken,
}) async {
await _storage.write(key: _accessTokenKey, value: accessToken);
await _storage.write(key: _refreshTokenKey, value: refreshToken);
}
Future<String?> getAccessToken() async {
return await _storage.read(key: _accessTokenKey);
}
Future<String?> getRefreshToken() async {
return await _storage.read(key: _refreshTokenKey);
}
Future<void> deleteAllTokens() async {
await _storage.delete(key: _accessTokenKey);
await _storage.delete(key: _refreshTokenKey);
}
}

View File

@ -0,0 +1,42 @@
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
class LoggingInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if (kDebugMode) {
print('--- API REQUEST ---');
print('METHOD: ${options.method}');
print('URL: ${options.uri}');
print('HEADERS: ${options.headers}');
print('BODY: ${options.data}');
print('-------------------');
}
super.onRequest(options, handler);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
if (kDebugMode) {
print('--- API RESPONSE ---');
print('STATUS_CODE: ${response.statusCode}');
print('URL: ${response.requestOptions.uri}');
print('DATA: ${response.data}');
print('--------------------');
}
super.onResponse(response, handler);
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
if (kDebugMode) {
print('--- API ERROR ---');
print('STATUS_CODE: ${err.response?.statusCode}');
print('URL: ${err.requestOptions.uri}');
print('ERROR: ${err.error}');
print('RESPONSE_DATA: ${err.response?.data}');
print('-----------------');
}
super.onError(err, handler);
}
}

View File

@ -0,0 +1,7 @@
class CategoryEntity {
final String id;
final String name;
final String emoji;
CategoryEntity({required this.id, required this.name, this.emoji = ''});
}

View File

@ -66,6 +66,9 @@ class $AssetsIconsGen {
/// File path: assets/icons/addImg.svg
String get addImg => 'assets/icons/addImg.svg';
/// File path: assets/icons/addPic.svg
String get addPic => 'assets/icons/addPic.svg';
/// File path: assets/icons/appbar2.svg
String get appbar2 => 'assets/icons/appbar2.svg';
@ -87,6 +90,12 @@ class $AssetsIconsGen {
/// File path: assets/icons/backArrow.svg
String get backArrow => 'assets/icons/backArrow.svg';
/// File path: assets/icons/calendar-search.svg
String get calendarSearch => 'assets/icons/calendar-search.svg';
/// File path: assets/icons/call-calling.svg
String get callCalling => 'assets/icons/call-calling.svg';
/// File path: assets/icons/camera.svg
String get camera => 'assets/icons/camera.svg';
@ -111,6 +120,9 @@ class $AssetsIconsGen {
/// File path: assets/icons/discount-shape.svg
String get discountShape => 'assets/icons/discount-shape.svg';
/// File path: assets/icons/document-text.svg
String get documentText => 'assets/icons/document-text.svg';
/// File path: assets/icons/edit-02.svg
String get edit02 => 'assets/icons/edit-02.svg';
@ -129,6 +141,9 @@ class $AssetsIconsGen {
/// File path: assets/icons/global-search.svg
String get globalSearch => 'assets/icons/global-search.svg';
/// File path: assets/icons/info-circle.svg
String get infoCircle => 'assets/icons/info-circle.svg';
/// File path: assets/icons/kafsh.svg
String get kafsh => 'assets/icons/kafsh.svg';
@ -147,6 +162,9 @@ class $AssetsIconsGen {
/// File path: assets/icons/pooshak.svg
String get pooshak => 'assets/icons/pooshak.svg';
/// File path: assets/icons/radar-2.svg
String get radar2 => 'assets/icons/radar-2.svg';
/// File path: assets/icons/receipt-disscount.svg
String get receiptDisscount => 'assets/icons/receipt-disscount.svg';
@ -227,6 +245,7 @@ class $AssetsIconsGen {
tshirt,
vector,
addImg,
addPic,
appbar2,
arayesh,
arrowDown,
@ -234,6 +253,8 @@ class $AssetsIconsGen {
arrowUp,
back,
backArrow,
calendarSearch,
callCalling,
camera,
cardPos,
cinama,
@ -242,18 +263,21 @@ class $AssetsIconsGen {
coffeeshop,
digital,
discountShape,
documentText,
edit02,
edit,
error,
fastfood,
galleryAdd,
globalSearch,
infoCircle,
kafsh,
location,
logo,
map,
notification,
pooshak,
radar2,
receiptDisscount,
resturan,
routing,
@ -307,6 +331,13 @@ class $AssetsImagesGen {
/// File path: assets/images/empty home.svg
String get emptyHome => 'assets/images/empty home.svg';
/// File path: assets/images/emptyShop.svg
String get emptyShop => 'assets/images/emptyShop.svg';
/// File path: assets/images/shoppAdded.png
AssetGenImage get shoppAdded =>
const AssetGenImage('assets/images/shoppAdded.png');
/// File path: assets/images/userinfo.png
AssetGenImage get userinfo =>
const AssetGenImage('assets/images/userinfo.png');
@ -320,6 +351,8 @@ class $AssetsImagesGen {
rectangle3,
rectangle4,
emptyHome,
emptyShop,
shoppAdded,
userinfo,
];
}

View File

@ -1,31 +1,72 @@
import 'package:bloc/bloc.dart';
import 'package:business_panel/core/services/token_storage_service.dart';
import 'package:dio/dio.dart';
import 'package:business_panel/core/utils/logging_interceptor.dart';
part 'auth_event.dart';
part 'auth_state.dart';
class AuthBloc extends Bloc<AuthEvent, AuthState> {
late final Dio _dio;
final TokenStorageService _tokenStorage = TokenStorageService();
AuthBloc() : super(AuthInitial()) {
_dio = Dio();
_dio.interceptors.add(LoggingInterceptor());
on<SendOTPEvent>((event, emit) async {
emit(AuthLoading());
await Future.delayed(const Duration(seconds: 1));
if (event.phoneNumber.isNotEmpty) {
emit(AuthCodeSentSuccess());
} else {
emit(AuthFailure('شماره موبایل معتبر نیست.'));
emit(AuthLoading());
try {
final response = await _dio.post(
'https://fartak.liara.run/login/sendcode',
data: {
'Phone': event.phoneNumber,
'Code': event.countryCode,
},
);
if (response.statusCode == 200) {
emit(AuthCodeSentSuccess());
} else {
emit(AuthFailure(response.data['message'] ?? 'خطایی رخ داد'));
}
} on DioException catch (e) {
emit(AuthFailure(e.response?.data['message'] ?? 'خطای شبکه'));
}
});
on<VerifyOTPEvent>((event, emit) async {
emit(AuthLoading());
await Future.delayed(const Duration(seconds: 1));
if (event.otp == '12345') {
emit(AuthVerified());
} else {
emit(AuthFailure('کد تایید صحیح نمی‌باشد.'));
try {
final response = await _dio.post(
'https://fartak.liara.run/login/getcode',
data: {
'Phone': event.phoneNumber,
'Code': event.countryCode,
'OTP': event.otp,
},
);
if (response.statusCode == 200 && response.data['data']['accessToken'] != null) {
final accessToken = response.data['data']['accessToken'];
final refreshToken = response.data['data']['refreshToken'];
await _tokenStorage.saveTokens(
accessToken: accessToken,
refreshToken: refreshToken,
);
emit(AuthVerified());
} else {
emit(AuthFailure(response.data['message'] ?? 'کد تایید صحیح نمی‌باشد.'));
}
} on DioException catch (e) {
emit(AuthFailure(e.response?.data['message'] ?? 'خطای شبکه'));
}
});
on<SaveUserInfoEvent>((event, emit) async {
emit(AuthLoading());
await Future.delayed(const Duration(milliseconds: 500));
@ -37,4 +78,4 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
}
});
}
}
}

View File

@ -1,18 +1,20 @@
part of 'auth_bloc.dart';
abstract class AuthEvent {}
class SendOTPEvent extends AuthEvent {
final String phoneNumber;
final String countryCode;
SendOTPEvent({required this.phoneNumber});
SendOTPEvent({required this.phoneNumber, required this.countryCode});
}
class VerifyOTPEvent extends AuthEvent {
final String otp;
final String phoneNumber;
final String countryCode;
VerifyOTPEvent({required this.otp});
VerifyOTPEvent({required this.otp, required this.phoneNumber, required this.countryCode});
}
class SaveUserInfoEvent extends AuthEvent {
@ -20,4 +22,4 @@ class SaveUserInfoEvent extends AuthEvent {
final String gender;
SaveUserInfoEvent({required this.name, required this.gender});
}
}

View File

@ -0,0 +1,49 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'discount_event.dart';
import 'discount_state.dart';
class DiscountBloc extends Bloc<DiscountEvent, DiscountState> {
DiscountBloc() : super(const DiscountState()) {
on<ProductImageAdded>((event, emit) {
List<String> updatedImages = List.from(state.productImages);
if (updatedImages.length > event.index) {
updatedImages[event.index] = event.imagePath;
} else {
updatedImages.add(event.imagePath);
}
emit(state.copyWith(productImages: updatedImages));
});
on<ProductNameChanged>((event, emit) {
emit(state.copyWith(productName: event.name));
});
on<DiscountTypeChanged>((event, emit) {
emit(state.copyWith(discountType: event.type));
});
on<DescriptionChanged>((event, emit) {
emit(state.copyWith(description: event.description));
});
on<ValidityDateChanged>((event, emit) {
emit(state.copyWith(startDate: event.startDate, endDate: event.endDate));
});
on<TimeRangeChanged>((event, emit) {
emit(state.copyWith(startTime: event.startTime, endTime: event.endTime));
});
on<PriceChanged>((event, emit) {
emit(state.copyWith(price: event.price));
});
on<DiscountedPriceChanged>((event, emit) {
emit(state.copyWith(discountedPrice: event.price));
});
on<NotificationRadiusChanged>((event, emit) {
emit(state.copyWith(notificationRadius: event.radius));
});
}
}

View File

@ -0,0 +1,52 @@
abstract class DiscountEvent {}
class ProductImageAdded extends DiscountEvent {
final String imagePath;
final int index;
ProductImageAdded(this.imagePath, this.index);
}
class ProductNameChanged extends DiscountEvent {
final String name;
ProductNameChanged(this.name);
}
class DiscountTypeChanged extends DiscountEvent {
final String type;
DiscountTypeChanged(this.type);
}
class DescriptionChanged extends DiscountEvent {
final String description;
DescriptionChanged(this.description);
}
class ValidityDateChanged extends DiscountEvent {
final DateTime startDate;
final DateTime endDate;
ValidityDateChanged({required this.startDate, required this.endDate});
}
class TimeRangeChanged extends DiscountEvent {
final String startTime;
final String endTime;
TimeRangeChanged({required this.startTime, required this.endTime});
}
class PriceChanged extends DiscountEvent {
final String price;
PriceChanged(this.price);
}
class DiscountedPriceChanged extends DiscountEvent {
final String price;
DiscountedPriceChanged(this.price);
}
class NotificationRadiusChanged extends DiscountEvent {
final double radius;
NotificationRadiusChanged(this.radius);
}
class SubmitDiscount extends DiscountEvent {}

View File

@ -0,0 +1,87 @@
import 'package:equatable/equatable.dart';
class DiscountState extends Equatable {
final List<String> productImages;
final String productName;
final String? discountType;
final String description;
final DateTime? startDate;
final DateTime? endDate;
final String? startTime;
final String? endTime;
final String price;
final String discountedPrice;
final double notificationRadius;
final bool isSubmitting;
final bool isSuccess;
final String? errorMessage;
const DiscountState({
this.productImages = const [],
this.productName = '',
this.discountType,
this.description = '',
this.startDate,
this.endDate,
this.startTime,
this.endTime,
this.price = '',
this.discountedPrice = '',
this.notificationRadius = 0.0,
this.isSubmitting = false,
this.isSuccess = false,
this.errorMessage,
});
DiscountState copyWith({
List<String>? productImages,
String? productName,
String? discountType,
String? description,
DateTime? startDate,
DateTime? endDate,
String? startTime,
String? endTime,
String? price,
String? discountedPrice,
double? notificationRadius,
bool? isSubmitting,
bool? isSuccess,
String? errorMessage,
}) {
return DiscountState(
productImages: productImages ?? this.productImages,
productName: productName ?? this.productName,
discountType: discountType ?? this.discountType,
description: description ?? this.description,
startDate: startDate ?? this.startDate,
endDate: endDate ?? this.endDate,
startTime: startTime ?? this.startTime,
endTime: endTime ?? this.endTime,
price: price ?? this.price,
discountedPrice: discountedPrice ?? this.discountedPrice,
notificationRadius: notificationRadius ?? this.notificationRadius,
isSubmitting: isSubmitting ?? this.isSubmitting,
isSuccess: isSuccess ?? this.isSuccess,
errorMessage: errorMessage ?? this.errorMessage,
);
}
@override
List<Object?> get props => [
productImages,
productName,
discountType,
description,
startDate,
endDate,
startTime,
endTime,
price,
discountedPrice,
notificationRadius,
isSubmitting,
isSuccess,
errorMessage,
];
}

View File

@ -0,0 +1,606 @@
import 'dart:io';
import 'package:business_panel/core/config/app_colors.dart';
import 'package:business_panel/gen/assets.gen.dart';
import 'package:business_panel/presentation/discount/bloc/discount_bloc.dart';
import 'package:business_panel/presentation/discount/bloc/discount_event.dart';
import 'package:business_panel/presentation/discount/bloc/discount_state.dart';
import 'package:business_panel/presentation/widgets/info_popup.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:persian_datetime_picker/persian_datetime_picker.dart';
class AddDiscountPage extends StatelessWidget {
const AddDiscountPage({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => DiscountBloc(),
child: const _AddDiscountView(),
);
}
}
class _AddDiscountView extends StatefulWidget {
const _AddDiscountView();
@override
State<_AddDiscountView> createState() => _AddDiscountViewState();
}
class _AddDiscountViewState extends State<_AddDiscountView> {
final _nameController = TextEditingController();
final _descController = TextEditingController();
final _priceController = TextEditingController();
final _discountPriceController = TextEditingController();
@override
void dispose() {
_nameController.dispose();
_descController.dispose();
_priceController.dispose();
_discountPriceController.dispose();
super.dispose();
}
Future<void> _pickValidityDates(BuildContext context) async {
Jalali? startDate = await showPersianDatePicker(
context: context,
initialDate: Jalali.now(),
firstDate: Jalali.now(),
lastDate: Jalali(1500),
);
if (startDate == null || !context.mounted) return;
TimeOfDay? startTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (startTime == null || !context.mounted) return;
Jalali? endDate = await showPersianDatePicker(
context: context,
initialDate: startDate,
firstDate: startDate,
lastDate: Jalali(1500),
);
if (endDate == null || !context.mounted) return;
TimeOfDay? endTime = await showTimePicker(
context: context,
initialTime: startTime,
);
if (endTime == null || !context.mounted) return;
final DateTime startDateTime = startDate.toDateTime().add(
Duration(hours: startTime.hour, minutes: startTime.minute),
);
final DateTime endDateTime = endDate.toDateTime().add(
Duration(hours: endTime.hour, minutes: endTime.minute),
);
context.read<DiscountBloc>().add(
ValidityDateChanged(startDate: startDateTime, endDate: endDateTime),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildCustomAppBar(context),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"تعریف تخفیف جدید",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
const SizedBox(height: 24),
_buildSectionTitle(
title: "بارگذاری عکس از محصول",
popupTitle: "یه عکس خوب، یه فروش خوب‌تر!",
isMandatory: true,
infoText:
"عکس واضح، باکیفیت و واقعی از محصولت بذار. ترجیحا از عکس‌های اینترنتی یا تبلیغاتی استفاده نکن.",
iconPath: Assets.icons.camera,
),
const SizedBox(height: 16),
_buildImagePickers(),
const SizedBox(height: 30),
_buildTextField(
controller: _nameController,
label: "نام محصول",
isRequired: true,
hint: "وافل شکلات فندقی",
onChanged:
(value) => context.read<DiscountBloc>().add(
ProductNameChanged(value),
),
),
const SizedBox(height: 30),
_buildDiscountTypeDropdown(),
const SizedBox(height: 30),
_buildTextField(
controller: _descController,
label: "توضیح برای تخفیف",
hint: "مثلاً عصرونه، با ۵٪ تخفیف مهمون ما باش! ",
isRequired: true,
maxLines: 4,
maxLength: 200,
onChanged:
(value) => context.read<DiscountBloc>().add(
DescriptionChanged(value),
),
),
const SizedBox(height: 30),
_buildDateTimePicker(),
const SizedBox(height: 30),
_buildTimeRangePicker(context),
const SizedBox(height: 30),
_buildTextField(
controller: _priceController,
label: "قیمت بدون تخفیف",
isRequired: true,
hint: "مثلاً 240000 تومان",
keyboardType: TextInputType.number,
onChanged:
(value) =>
context.read<DiscountBloc>().add(PriceChanged(value)),
),
const SizedBox(height: 30),
_buildTextField(
controller: _discountPriceController,
label: "قیمت با تخفیف",
hint: "مثلاً 200000 تومان",
isRequired: true,
keyboardType: TextInputType.number,
onChanged:
(value) => context.read<DiscountBloc>().add(
DiscountedPriceChanged(value),
),
),
const SizedBox(height: 30),
_buildNotificationRadiusSlider(),
const SizedBox(height: 30),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
// TODO: Implement submit logic
},
child: const Text("ثبت تخفیف"),
),
),
const SizedBox(height: 30),
],
),
),
);
}
Widget _buildSectionTitle({
required String title,
String? popupTitle,
bool isMandatory = false,
String? infoText,
String? iconPath,
}) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (infoText != null && iconPath != null)
IconButton(
onPressed:
() => showInfoDialog(
context,
title: popupTitle ?? title,
content: infoText,
iconPath: iconPath,
),
icon: SvgPicture.asset(Assets.icons.infoCircle, width: 17),
),
Text(
title,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
),
if (isMandatory)
const Text(' *', style: TextStyle(color: Colors.red, fontSize: 17)),
],
);
}
Widget _buildImagePickers() {
return BlocBuilder<DiscountBloc, DiscountState>(
builder: (context, state) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(2, (index) {
final imagePath =
state.productImages.length > index
? state.productImages[index]
: null;
return GestureDetector(
onTap: () async {
final ImagePicker picker = ImagePicker();
final XFile? image = await picker.pickImage(
source: ImageSource.gallery,
);
if (image != null && context.mounted) {
context.read<DiscountBloc>().add(
ProductImageAdded(image.path, index),
);
}
},
child: Container(
width: 125,
height: 125,
decoration: BoxDecoration(
color: AppColors.uploadElevated,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.uploadElevated),
image:
imagePath != null
? DecorationImage(
image: FileImage(File(imagePath)),
fit: BoxFit.cover,
)
: null,
),
child:
imagePath == null
? Center(
child: SvgPicture.asset(
Assets.icons.addPic,
width: 60,
),
)
: null,
),
);
}),
);
},
);
}
Widget _buildDiscountTypeDropdown() {
final List<String> discountTypes = [
"ساعت خوش",
"رفیق بازی",
"محصول جانبی رایگان",
"کالای مکمل",
"پلکانی",
"دعوتنامه طلایی",
"بازگشت وجه",
"سایر",
];
return DropdownButtonFormField<String>(
icon: SvgPicture.asset(
Assets.icons.arrowDown,
width: 24,
color: Colors.black,
),
menuMaxHeight: 400,
hint: Text("ساعت خوش"),
decoration: _inputDecoration("نوع تخفیف", isRequired: true).copyWith(
contentPadding: const EdgeInsets.symmetric(
vertical: 14,
horizontal: 20,
),
),
borderRadius: BorderRadius.circular(12.0),
items:
discountTypes
.map((type) => DropdownMenuItem(value: type, child: Text(type)))
.toList(),
onChanged: (value) {
if (value != null) {
context.read<DiscountBloc>().add(DiscountTypeChanged(value));
}
},
);
}
Widget _buildDateTimePicker() {
return BlocBuilder<DiscountBloc, DiscountState>(
buildWhen: (previous, current) =>
previous.startDate != current.startDate ||
previous.endDate != current.endDate,
builder: (context, state) {
String displayText = "انتخاب تاریخ";
if (state.startDate != null && state.endDate != null) {
final jalaliStart = DateTimeExtensions(state.startDate!).toJalali();
final jalaliEnd = DateTimeExtensions(state.endDate!).toJalali();
final startFormatted =
'${jalaliStart.year}/${jalaliStart.month.toString().padLeft(2, '0')}/${jalaliStart.day.toString().padLeft(2, '0')} - ${state.startDate!.hour.toString().padLeft(2, '0')}:${state.startDate!.minute.toString().padLeft(2, '0')}';
final endFormatted =
'${jalaliEnd.year}/${jalaliEnd.month.toString().padLeft(2, '0')}/${jalaliEnd.day.toString().padLeft(2, '0')} - ${state.endDate!.hour.toString().padLeft(2, '0')}:${state.endDate!.minute.toString().padLeft(2, '0')}';
displayText = 'از $startFormatted\nتا $endFormatted';
}
return InkWell(
onTap: () => _pickValidityDates(context),
child: InputDecorator(
decoration: _inputDecoration(
"تاریخ اعتبار تخفیف",
isRequired: true,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
displayText,
textDirection: TextDirection.rtl,
style: const TextStyle(fontSize: 15), // Optional: for better fit
),
),
SvgPicture.asset(Assets.icons.calendarSearch),
],
),
),
);
},
);
}
Widget _buildTimeRangePicker(BuildContext context) {
return BlocBuilder<DiscountBloc, DiscountState>(
buildWhen:
(previous, current) =>
previous.startTime != current.startTime ||
previous.endTime != current.endTime,
builder: (context, state) {
String displayText = "انتخاب بازه زمانی";
if (state.startTime != null && state.endTime != null) {
displayText = 'از ساعت ${state.startTime} تا ${state.endTime}';
}
return InkWell(
onTap: () async {
final TimeOfDay? startTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (startTime == null) return;
final TimeOfDay? endTime = await showTimePicker(
context: context,
initialTime: startTime,
);
if (endTime == null) return;
final formattedStartTime =
'${startTime.hour.toString().padLeft(2, '0')}:${startTime.minute.toString().padLeft(2, '0')}';
final formattedEndTime =
'${endTime.hour.toString().padLeft(2, '0')}:${endTime.minute.toString().padLeft(2, '0')}';
context.read<DiscountBloc>().add(
TimeRangeChanged(
startTime: formattedStartTime,
endTime: formattedEndTime,
),
);
},
child: InputDecorator(
decoration: _inputDecoration("بازه زمانی معتبر", isRequired: true),
child: Text(displayText),
),
);
},
);
}
Widget _buildNotificationRadiusSlider() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
IconButton(
onPressed:
() => showInfoDialog(
context,
title: "انتخاب محدوده نمایش تخفیف",
content:
"محدوده‌ای رو مشخص کن که تخفیف‌هات فقط به کاربرانی که تو اون شعاع هستن نشون داده بشه.",
iconPath: Assets.icons.radar2,
),
icon: SvgPicture.asset(Assets.icons.infoCircle, width: 17),
),
Text(
"شعاع ارسال اعلان تخفیف به مشتری‌ها",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
],
),
],
),
BlocBuilder<DiscountBloc, DiscountState>(
builder: (context, state) {
return Column(
children: [
SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: AppColors.active,
inactiveTrackColor: Colors.grey.shade300,
trackShape: const RoundedRectSliderTrackShape(),
trackHeight: 4.0,
thumbColor: AppColors.active,
thumbShape: const RoundSliderThumbShape(
enabledThumbRadius: 12.0,
),
overlayColor: AppColors.active.withAlpha(32),
overlayShape: const RoundSliderOverlayShape(
overlayRadius: 28.0,
),
),
child: Slider(
value: state.notificationRadius,
min: 0,
max: 1000,
divisions: 100,
label: '${state.notificationRadius.toInt()} متر',
onChanged: (value) {
context.read<DiscountBloc>().add(
NotificationRadiusChanged(value),
);
},
),
),
SizedBox(height: 7,),
BlocBuilder<DiscountBloc, DiscountState>(
builder: (context, state) {
return Text(
'${state.notificationRadius.toInt()} متر',
style: const TextStyle(
fontWeight: FontWeight.normal,
fontSize: 14,
color: Colors.black,
),
);
},
),
],
);
},
),
],
);
}
Widget _buildTextField({
required String label,
String? hint,
bool isRequired = false,
int? maxLines,
int? maxLength,
TextInputType? keyboardType,
required TextEditingController controller,
ValueChanged<String>? onChanged,
}) {
return ValueListenableBuilder<TextEditingValue>(
valueListenable: controller,
builder: (context, value, child) {
return TextFormField(
controller: controller,
onChanged: onChanged,
maxLines: maxLines,
maxLength: maxLength,
keyboardType: keyboardType,
decoration: _inputDecoration(
label,
hint: hint,
isRequired: isRequired,
).copyWith(
counterText: '',
counter:
maxLength != null
? Text(
'${value.text.length}/$maxLength',
style: Theme.of(context).textTheme.bodySmall,
)
: null,
),
);
},
);
}
InputDecoration _inputDecoration(
String label, {
String? hint,
bool isRequired = false,
}) {
return InputDecoration(
hintText: hint,
hintStyle: TextStyle(
color: Color.fromARGB(255, 95, 95, 95),
fontSize: 14,
),
label: RichText(
text: TextSpan(
text: label,
style: const TextStyle(
color: Colors.black,
fontFamily: 'Dana',
fontSize: 18,
fontWeight: FontWeight.bold,
),
children: [
if (isRequired)
const TextSpan(text: ' *', style: TextStyle(color: Colors.red)),
],
),
),
);
}
PreferredSizeWidget _buildCustomAppBar(BuildContext context) {
return PreferredSize(
preferredSize: const Size.fromHeight(70.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(15),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: [
const SizedBox(height: 15),
Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 8),
child: SvgPicture.asset(Assets.icons.logoWithName),
),
const Spacer(),
Row(
children: [
IconButton(
onPressed: () {},
icon: SvgPicture.asset(
Assets.icons.discountShape,
color: Colors.black,
),
),
IconButton(
onPressed: () {},
icon: SvgPicture.asset(Assets.icons.scanBarcode),
),
],
),
],
),
],
),
),
),
),
);
}
}

View File

@ -42,10 +42,18 @@ class _LoginPageState extends State<LoginPage> {
Column(
children: [
Center(
child: SvgPicture.asset(Assets.icons.logo,height: 160,),
child: SvgPicture.asset(
Assets.icons.logo,
height: 160,
),
),
SizedBox(height: 15,),
Text("پنل فروشگاهی شما",style: TextStyle(color: AppColors.active),)
SizedBox(
height: 15,
),
Text(
"پنل فروشگاهی شما",
style: TextStyle(color: AppColors.active),
)
],
),
SizedBox(height: 48),
@ -103,9 +111,8 @@ class _LoginPageState extends State<LoginPage> {
children: [
Checkbox(
value: _keepSignedIn,
onChanged:
(value) =>
setState(() => _keepSignedIn = value ?? false),
onChanged: (value) =>
setState(() => _keepSignedIn = value ?? false),
activeColor: AppColors.primary,
),
Text("مرا به خاطر بسپار", style: textTheme.bodyMedium),
@ -120,14 +127,20 @@ class _LoginPageState extends State<LoginPage> {
content: Text(state.message),
backgroundColor: Colors.red,
),
);
);
}
if (state is AuthCodeSentSuccess) {
final fullPhoneNumber = "0${_phoneController.text}";
final fullPhoneNumber = _phoneController.text;
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => OtpPage(phoneNumber: fullPhoneNumber),
builder: (_) => BlocProvider.value(
value: context.read<AuthBloc>(),
child: OtpPage(
phoneNumber: fullPhoneNumber,
countryCode: _selectedCountry.phoneCode,
),
),
),
);
}
@ -165,7 +178,10 @@ class _LoginPageState extends State<LoginPage> {
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
icon: SvgPicture.asset(Assets.icons.googleSvg,width: 24,),
icon: SvgPicture.asset(
Assets.icons.googleSvg,
width: 24,
),
label: const Text(
"ورود با حساب گوگل",
style: TextStyle(color: Colors.black),
@ -204,7 +220,10 @@ class _LoginPageState extends State<LoginPage> {
void _sendOtp() {
context.read<AuthBloc>().add(
SendOTPEvent(phoneNumber: _phoneController.text),
);
SendOTPEvent(
phoneNumber: _phoneController.text,
countryCode: _selectedCountry.phoneCode,
),
);
}
}
}

View File

@ -10,7 +10,9 @@ import 'package:flutter_svg/svg.dart';
class OtpPage extends StatefulWidget {
final String phoneNumber;
const OtpPage({super.key, required this.phoneNumber});
final String countryCode;
const OtpPage(
{super.key, required this.phoneNumber, required this.countryCode});
@override
State<OtpPage> createState() => _OtpPageState();
@ -90,7 +92,7 @@ class _OtpPageState extends State<OtpPage> {
style: TextStyle(fontSize: 15),
),
TextSpan(
text: widget.phoneNumber,
text: "0${widget.phoneNumber}",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
@ -137,7 +139,6 @@ class _OtpPageState extends State<OtpPage> {
)
else
const SizedBox(height: 32),
BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {
if (state is AuthFailure) {
@ -149,11 +150,10 @@ class _OtpPageState extends State<OtpPage> {
if (state is AuthVerified) {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder:
(_) => BlocProvider(
create: (context) => StoreInfoBloc(),
child: const StoreInfoPage(),
),
builder: (_) => BlocProvider(
create: (context) => StoreInfoBloc(),
child: const StoreInfoPage(),
),
),
(route) => false,
);
@ -189,20 +189,19 @@ class _OtpPageState extends State<OtpPage> {
builder: (context, canResend, child) {
return canResend
? TextButton(
onPressed: _resendOtp,
child: const Text(
"ارسال مجدد کد",
style: TextStyle(color: AppColors.active),
),
)
onPressed: _resendOtp,
child: const Text(
"ارسال مجدد کد",
style: TextStyle(color: AppColors.active),
),
)
: ValueListenableBuilder<int>(
valueListenable: _otpTimer.remainingSeconds,
builder:
(context, seconds, child) => Text(
"${_otpTimer.formatTime()} تا دریافت مجدد",
style: const TextStyle(color: Colors.grey),
),
);
valueListenable: _otpTimer.remainingSeconds,
builder: (context, seconds, child) => Text(
"${_otpTimer.formatTime()} تا دریافت مجدد",
style: const TextStyle(color: Colors.grey),
),
);
},
),
],
@ -240,15 +239,14 @@ class _OtpPageState extends State<OtpPage> {
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color:
_hasError
? Colors.red
: (Theme.of(context)
.inputDecorationTheme
.enabledBorder
?.borderSide
.color ??
Colors.grey),
color: _hasError
? Colors.red
: (Theme.of(context)
.inputDecorationTheme
.enabledBorder
?.borderSide
.color ??
Colors.grey),
),
),
focusedBorder: OutlineInputBorder(
@ -287,7 +285,13 @@ class _OtpPageState extends State<OtpPage> {
void _verifyOtp() {
final otpCode = _controllers.map((c) => c.text).join();
if (otpCode.length == 5) {
context.read<AuthBloc>().add(VerifyOTPEvent(otp: otpCode));
context.read<AuthBloc>().add(
VerifyOTPEvent(
otp: otpCode,
phoneNumber: widget.phoneNumber,
countryCode: widget.countryCode,
),
);
}
}
@ -300,7 +304,8 @@ class _OtpPageState extends State<OtpPage> {
}
_isOtpComplete = false;
});
context.read<AuthBloc>().add(SendOTPEvent(phoneNumber: widget.phoneNumber));
context.read<AuthBloc>().add(SendOTPEvent(
phoneNumber: widget.phoneNumber, countryCode: widget.countryCode));
_otpTimer.resetTimer();
}
}
}

View File

@ -0,0 +1,114 @@
import 'package:business_panel/core/config/app_colors.dart';
import 'package:business_panel/gen/assets.gen.dart';
import 'package:business_panel/presentation/pages/add_discount_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class ProductCreationLandingPage extends StatelessWidget {
const ProductCreationLandingPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildCustomAppBar(context),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SvgPicture.asset(Assets.images.emptyShop, height: 350),
const SizedBox(height: 60),
const Text(
"فروشگاه با موفقیت ثبت شد!",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
"حالا وقتشه اولین تخفیف رو اضافه کنی.",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 25),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const AddDiscountPage()),
);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.confirm,
padding: const EdgeInsets.symmetric(vertical: 14),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.add),
SizedBox(width: 5,),
const Text(
"تعریف تخفیف جدید",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.normal),
),
],
),
),
],
),
),
);
}
}
PreferredSizeWidget _buildCustomAppBar(BuildContext context) {
return PreferredSize(
preferredSize: const Size.fromHeight(70.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.vertical(bottom: Radius.circular(15)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: [
const SizedBox(height: 15),
Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 8),
child: SvgPicture.asset(Assets.icons.logoWithName),
),
const Spacer(),
Row(
children: [
IconButton(
onPressed: () {},
icon: SvgPicture.asset(
Assets.icons.discountShape,
color: Colors.black,
),
),
IconButton(
onPressed: () {},
icon: SvgPicture.asset(Assets.icons.scanBarcode),
),
],
),
],
),
],
),
),
),
),
);
}

View File

@ -1,6 +1,8 @@
import 'dart:io';
import 'package:business_panel/core/config/app_colors.dart';
import 'package:business_panel/domain/entities/category_entity.dart';
import 'package:business_panel/gen/assets.gen.dart';
import 'package:business_panel/presentation/pages/store_info_display_page.dart';
import 'package:business_panel/presentation/pages/working_hours_dialog.dart';
import 'package:business_panel/presentation/store_info/bloc/store_info_bloc.dart';
import 'package:business_panel/presentation/store_info/bloc/store_info_state.dart';
@ -9,13 +11,53 @@ import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart';
import 'package:business_panel/presentation/pages/osm_map_picker_page.dart'; // ایمپورت صفحه جدید
import 'package:business_panel/presentation/pages/osm_map_picker_page.dart';
import 'package:latlong2/latlong.dart';
import 'package:persian_datetime_picker/persian_datetime_picker.dart';
class StoreInfoPage extends StatelessWidget {
class StoreInfoPage extends StatefulWidget {
const StoreInfoPage({super.key});
@override
State<StoreInfoPage> createState() => _StoreInfoPageState();
}
class _StoreInfoPageState extends State<StoreInfoPage> {
final _nameController = TextEditingController();
final _provinceController = TextEditingController();
final _cityController = TextEditingController();
final _addressController = TextEditingController();
final _plaqueController = TextEditingController();
final _postalCodeController = TextEditingController();
final _phoneController = TextEditingController();
final _licenseController = TextEditingController();
@override
void initState() {
super.initState();
final bloc = context.read<StoreInfoBloc>();
_nameController.text = bloc.state.storeName;
_provinceController.text = bloc.state.province;
_cityController.text = bloc.state.city;
_addressController.text = bloc.state.address;
_plaqueController.text = bloc.state.plaque;
_postalCodeController.text = bloc.state.postalCode;
_phoneController.text = bloc.state.contactPhone ?? '';
_licenseController.text = bloc.state.licenseNumber ?? '';
}
@override
void dispose() {
_nameController.dispose();
_provinceController.dispose();
_cityController.dispose();
_addressController.dispose();
_plaqueController.dispose();
_postalCodeController.dispose();
_phoneController.dispose();
_licenseController.dispose();
super.dispose();
}
Future<void> _pickImage(BuildContext context) async {
try {
final ImagePicker picker = ImagePicker();
@ -34,7 +76,7 @@ class StoreInfoPage extends StatelessWidget {
}
}
Future<void> _showWorkingHoursDialog(BuildContext context) async {
Future<void> _showWorkingHoursDialog(BuildContext context) async {
final result = await showDialog<Map<String, dynamic>>(
context: context,
builder: (context) => const WorkingHoursDialog(),
@ -51,64 +93,46 @@ class StoreInfoPage extends StatelessWidget {
}
}
// Future<void> _pickWorkingHours(BuildContext context) async {
// // ۱. انتخاب تاریخ شروع
// Jalali? startDate = await showPersianDatePicker(
// context: context,
// initialDate: Jalali.now(),
// firstDate: Jalali(1400),
// lastDate: Jalali(1405),
// );
// if (startDate == null || !context.mounted) return;
// // ۲. انتخاب ساعت شروع
// TimeOfDay? startTime = await showTimePicker(
// context: context,
// initialTime: TimeOfDay.now(),
// );
// if (startTime == null || !context.mounted) return;
// // ۳. انتخاب تاریخ پایان
// Jalali? endDate = await showPersianDatePicker(
// context: context,
// initialDate: startDate, // شروع از تاریخ انتخابی قبلی
// firstDate: startDate, // تاریخ پایان نمیتواند قبل از شروع باشد
// lastDate: Jalali(1405),
// );
// if (endDate == null || !context.mounted) return;
// // ۴. انتخاب ساعت پایان
// TimeOfDay? endTime = await showTimePicker(
// context: context,
// initialTime: startTime,
// );
// if (endTime == null || !context.mounted) return;
// // ۵. تبدیل به آبجکت DateTime و ارسال به BLoC
// final DateTime startDateTime = startDate.toDateTime().add(
// Duration(hours: startTime.hour, minutes: startTime.minute),
// );
// final DateTime endDateTime = endDate.toDateTime().add(
// Duration(hours: endTime.hour, minutes: endTime.minute),
// );
// context.read<StoreInfoBloc>().add(
// WorkingHoursChanged(
// startDateTime: startDateTime,
// endDateTime: endDateTime,
// ),
// );
// }
final List<CategoryEntity> activityTypes = [
CategoryEntity(id: "6803b940-3e19-48cd-9190-28d9f25421ff", name: "فست فود", emoji: "🍔🍕"),
CategoryEntity(id: "71e371f8-a47a-4a58-aee6-4ed0f26bf29b", name: "پوشاک", emoji: "👚👔"),
CategoryEntity(id: "42acff41-1165-4e62-89b9-58db7329ec3a", name: "تریا", emoji: "🍨🍹"),
CategoryEntity(id: "e33dd7f9-5b20-4273-8eea-59da6ca5f206", name: "لوازم دیجیتال", emoji: "📱📷"),
CategoryEntity(id: "b5881239-bfd5-4c27-967a-187316a7e0b7", name: "رستوران", emoji: "🍣🍢"),
CategoryEntity(id: "b73a868a-a2d2-4d96-8fd4-615327ed9629", name: "کافی شاپ", emoji: "☕🍰"),
CategoryEntity(id: "2f38918c-5566-4aec-a0a9-2c7c48b1e878", name: "کیف و کفش", emoji: "👜👞"),
CategoryEntity(id: "52c51010-3a63-4264-a350-e011c889f3dd", name: "سینما", emoji: "🎭🎟️"),
CategoryEntity(id: "34185954-f79f-4b9e-8eb2-1702679c40a0", name: "لوازم آرایشی", emoji: "💄💅️"),
CategoryEntity(id: "e4517b0c-aacf-4758-94bd-85f45062980f", name: "طلا و زیورآلات", emoji: "💍💎"),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildCustomAppBar(context),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
body: BlocListener<StoreInfoBloc, StoreInfoState>(
listener: (context, state) {
if (state.isSuccess) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => BlocProvider.value(
value: BlocProvider.of<StoreInfoBloc>(context),
child: const StoreInfoDisplayPage(),
),
),
);
}
if (state.errorMessage != null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.errorMessage!), backgroundColor: Colors.red),
);
}
},
child: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 16),
const Row(
children: [
@ -134,7 +158,12 @@ class StoreInfoPage extends StatelessWidget {
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: const Color.fromARGB(255, 224, 224, 224).withOpacity(0.5),
color: const Color.fromARGB(
255,
224,
224,
224,
).withOpacity(0.5),
spreadRadius: 1,
blurRadius: 40,
offset: const Offset(0, 10),
@ -159,9 +188,7 @@ class StoreInfoPage extends StatelessWidget {
child: CircleAvatar(
radius: 20,
backgroundColor: Colors.white,
child: SvgPicture.asset(
Assets.icons.edit02
),
child: SvgPicture.asset(Assets.icons.edit02),
),
),
),
@ -180,6 +207,11 @@ class StoreInfoPage extends StatelessWidget {
label: "نام فروشگاه",
isRequired: true,
hint: "مثلاً کافه ایرونی",
controller: _nameController,
onChanged:
(value) => context.read<StoreInfoBloc>().add(
StoreNameChanged(value),
),
),
const SizedBox(height: 30),
_buildActivityTypeDropdown(context),
@ -187,24 +219,65 @@ class StoreInfoPage extends StatelessWidget {
Row(
children: [
Expanded(
child: _buildTextField(label: "استان", hint: "اصفهان"),
child: _buildTextField(
label: "استان",
hint: "اصفهان",
controller: _provinceController,
onChanged:
(value) => context.read<StoreInfoBloc>().add(
ProvinceChanged(value),
),
),
),
const SizedBox(width: 16),
Expanded(child: _buildTextField(label: "شهر", hint: "اصفهان")),
Expanded(
child: _buildTextField(
controller: _cityController,
label: "شهر",
hint: "اصفهان",
onChanged:
(value) => context.read<StoreInfoBloc>().add(
CityChanged(value),
),
),
),
],
),
const SizedBox(height: 30),
_buildTextField(
controller: _addressController,
label: "جزئیات آدرس",
maxLines: 3,
hint: "خیابان، محله، ساختمان و ....",
onChanged:
(value) =>
context.read<StoreInfoBloc>().add(AddressChanged(value)),
),
const SizedBox(height: 30),
_buildFeaturesSection(),
const SizedBox(height: 50),
Row(
children: [
Expanded(child: _buildTextField(label: "پلاک")),
Expanded(
child: _buildTextField(
controller: _plaqueController,
label: "پلاک",
onChanged:
(value) => context.read<StoreInfoBloc>().add(
PlaqueChanged(value),
),
),
),
const SizedBox(width: 16),
Expanded(child: _buildTextField(label: "کد پستی")),
Expanded(
child: _buildTextField(
controller: _postalCodeController,
label: "کد پستی",
onChanged: (value) => context
.read<StoreInfoBloc>()
.add(PostalCodeChanged(value)),
),
),
],
),
const SizedBox(height: 30),
@ -257,9 +330,12 @@ class StoreInfoPage extends StatelessWidget {
),
const SizedBox(height: 30),
_buildTextField(
controller: _phoneController,
label: "تلفن تماس",
keyboardType: TextInputType.phone,
hint: "شماره تماس ثابت یا موبایل فروشگاه",
onChanged: (value) =>
context.read<StoreInfoBloc>().add(ContactPhoneChanged(value)),
),
const SizedBox(height: 30),
@ -267,23 +343,36 @@ class StoreInfoPage extends StatelessWidget {
const SizedBox(height: 30),
_buildTextField(
controller: _licenseController,
label: "شماره جواز کسب",
hint: "شناسه صنفی 12 رقمی یکتا",
onChanged: (value) =>
context.read<StoreInfoBloc>().add(LicenseNumberChanged(value)),
),
const SizedBox(height: 44),
SizedBox(
width: double.infinity,
width: double.infinity,
child: ElevatedButton(
onPressed: () {},
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => BlocProvider.value(
value: BlocProvider.of<StoreInfoBloc>(context),
child: const StoreInfoDisplayPage(),
),
),
);
},
child: const Text("تایید و ادامه"),
),
),
const SizedBox(height: 34),
],
const SizedBox(height: 34),
],
),
),
);
));
}
Widget _buildSectionTitle() {
return const Text(
@ -297,12 +386,19 @@ class StoreInfoPage extends StatelessWidget {
bool isRequired = false,
String? hint,
int maxLines = 1,
int? maxLength,
TextInputType? keyboardType,
TextEditingController? controller,
ValueChanged<String>? onChanged,
}) {
return TextFormField(
controller: controller,
onChanged: onChanged,
maxLines: maxLines,
keyboardType: keyboardType,
maxLength: maxLength,
keyboardType: keyboardType,
decoration: InputDecoration(
counterText: "",
hintText: hint,
hintStyle: const TextStyle(fontSize: 15, color: Colors.grey),
label: RichText(
@ -327,6 +423,80 @@ class StoreInfoPage extends StatelessWidget {
);
}
Widget _buildFeaturesSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"ویژگی‌های فروشگاه",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
const Text(
"حداکثر ۳ ویژگی برای معرفی بهتر فروشگاه خود اضافه کنید.",
style: TextStyle(color: Colors.grey, fontSize: 14),
),
const SizedBox(height: 16),
BlocBuilder<StoreInfoBloc, StoreInfoState>(
buildWhen: (previous, current) => previous.features != current.features,
builder: (context, state) {
return Column(
children: [
...state.features.asMap().entries.map((entry) {
final index = entry.key;
final controller = TextEditingController(text: entry.value)
..selection = TextSelection.fromPosition(
TextPosition(offset: entry.value.length),
);
return Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Row(
children: [
Expanded(
child: _buildTextField(
controller: controller,
label: "ویژگی ${index + 1}",
hint: "مثلا: دارای ویوی شهر",
maxLength: 60,
onChanged: (value) {
context
.read<StoreInfoBloc>()
.add(StoreFeatureUpdated(index, value));
},
),
),
IconButton(
icon: const Icon(Icons.remove_circle_outline, color: Colors.red),
onPressed: () {
context
.read<StoreInfoBloc>()
.add(StoreFeatureRemoved(index));
},
),
],
),
);
}).toList(),
if (state.features.length < 3)
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
icon: const Icon(Icons.add),
label: const Text("افزودن ویژگی جدید"),
onPressed: () {
context.read<StoreInfoBloc>().add(StoreFeatureAdded());
},
),
),
],
);
},
),
],
);
}
Widget _buildWorkingHoursPicker(BuildContext context) {
return InkWell(
onTap: () => _showWorkingHoursDialog(context),
@ -342,26 +512,41 @@ class StoreInfoPage extends StatelessWidget {
fontWeight: FontWeight.bold,
),
children: [
TextSpan(text: ' *', style: TextStyle(color: Colors.red, fontSize: 16)),
TextSpan(
text: ' *',
style: TextStyle(color: Colors.red, fontSize: 16),
),
],
),
),
contentPadding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12),
contentPadding: const EdgeInsets.symmetric(
vertical: 18,
horizontal: 12,
),
),
child: BlocBuilder<StoreInfoBloc, StoreInfoState>(
buildWhen: (p, c) => p.workingDays != c.workingDays,
builder: (context, state) {
final hasData = state.workingDays.isNotEmpty && state.startTime != null;
final hasData =
state.workingDays.isNotEmpty && state.startTime != null;
const Map<String, String> dayTranslations = {
'Saturday': 'شنبه', 'Sunday': 'یکشنبه', 'Monday': 'دوشنبه',
'Tuesday': 'سه‌شنبه', 'Wednesday': 'چهارشنبه', 'Thursday': 'پنج‌شنبه', 'Friday': 'جمعه'
'Saturday': 'شنبه',
'Sunday': 'یکشنبه',
'Monday': 'دوشنبه',
'Tuesday': 'سه‌شنبه',
'Wednesday': 'چهارشنبه',
'Thursday': 'پنج‌شنبه',
'Friday': 'جمعه',
};
final displayDays = state.workingDays.map((day) => dayTranslations[day] ?? '').join('، ');
final displayDays = state.workingDays
.map((day) => dayTranslations[day] ?? '')
.join('، ');
String displayText = hasData
? "$displayDays\nاز ساعت ${state.startTime} تا ${state.endTime}"
: "انتخاب روز و ساعت کاری";
String displayText =
hasData
? "$displayDays\nاز ساعت ${state.startTime} تا ${state.endTime}"
: "انتخاب روز و ساعت کاری";
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -385,25 +570,16 @@ class StoreInfoPage extends StatelessWidget {
);
}
Widget _buildActivityTypeDropdown(BuildContext context) {
final List<String> activityTypes = [
"🍔🍕 فست فود",
"👚👔 پوشاک",
"🍨🍹 تریا",
"📱📷 لوازم دیجیتال",
"🍣🍢 رستوران",
"☕🍰 کافی شاپ",
"👜👞 کیف و کفش",
"🎭🎟️ سینما",
"💄💅️ لوازم آرایشی",
"💍💎 طلا و زیورآلات",
];
return Theme(
data: Theme.of(context).copyWith(canvasColor: const Color(0xFFF6F6F6)),
child: DropdownButtonFormField<String>(
icon: SvgPicture.asset(Assets.icons.arrowDown, width: 24,color: Colors.black,),
value: context.watch<StoreInfoBloc>().state.activityTypeId,
icon: SvgPicture.asset(
Assets.icons.arrowDown,
width: 24,
color: Colors.black,
),
decoration: InputDecoration(
label: RichText(
text: const TextSpan(
@ -425,10 +601,12 @@ class StoreInfoPage extends StatelessWidget {
),
borderRadius: BorderRadius.circular(12.0),
isExpanded: true,
items:
activityTypes.map((String value) {
return DropdownMenuItem<String>(value: value, child: Text(value));
}).toList(),
items: activityTypes.map((CategoryEntity category) {
return DropdownMenuItem<String>(
value: category.id,
child: Text("${category.emoji} ${category.name}"),
);
}).toList(),
onChanged: (value) {
if (value != null) {
context.read<StoreInfoBloc>().add(ActivityTypeChanged(value));
@ -493,3 +671,54 @@ PreferredSizeWidget _buildCustomAppBar(BuildContext context) {
),
);
}
// Future<void> _pickWorkingHours(BuildContext context) async {
// // ۱. انتخاب تاریخ شروع
// Jalali? startDate = await showPersianDatePicker(
// context: context,
// initialDate: Jalali.now(),
// firstDate: Jalali(1400),
// lastDate: Jalali(1405),
// );
// if (startDate == null || !context.mounted) return;
// // ۲. انتخاب ساعت شروع
// TimeOfDay? startTime = await showTimePicker(
// context: context,
// initialTime: TimeOfDay.now(),
// );
// if (startTime == null || !context.mounted) return;
// // ۳. انتخاب تاریخ پایان
// Jalali? endDate = await showPersianDatePicker(
// context: context,
// initialDate: startDate, // شروع از تاریخ انتخابی قبلی
// firstDate: startDate, // تاریخ پایان نمیتواند قبل از شروع باشد
// lastDate: Jalali(1405),
// );
// if (endDate == null || !context.mounted) return;
// // ۴. انتخاب ساعت پایان
// TimeOfDay? endTime = await showTimePicker(
// context: context,
// initialTime: startTime,
// );
// if (endTime == null || !context.mounted) return;
// // ۵. تبدیل به آبجکت DateTime و ارسال به BLoC
// final DateTime startDateTime = startDate.toDateTime().add(
// Duration(hours: startTime.hour, minutes: startTime.minute),
// );
// final DateTime endDateTime = endDate.toDateTime().add(
// Duration(hours: endTime.hour, minutes: endTime.minute),
// );
// context.read<StoreInfoBloc>().add(
// WorkingHoursChanged(
// startDateTime: startDateTime,
// endDateTime: endDateTime,
// ),
// );
// }

View File

@ -0,0 +1,270 @@
import 'dart:io';
import 'package:business_panel/core/config/app_colors.dart';
import 'package:business_panel/gen/assets.gen.dart';
import 'package:business_panel/presentation/pages/product_creation_landing_page.dart';
import 'package:business_panel/presentation/store_info/bloc/store_info_bloc.dart';
import 'package:business_panel/presentation/store_info/bloc/store_info_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:latlong2/latlong.dart';
class StoreInfoDisplayPage extends StatelessWidget {
const StoreInfoDisplayPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildCustomAppBar(context),
body: BlocListener<StoreInfoBloc, StoreInfoState>(
listener: (context, state) {
if (state.isSuccess) {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (_) => const ProductCreationLandingPage(),
),
(route) => false,
);
}
if (state.errorMessage != null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(state.errorMessage!),
backgroundColor: Colors.red,
),
);
}
},
child: BlocBuilder<StoreInfoBloc, StoreInfoState>(
builder: (context, state) {
return SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 10),
_buildStoreLogo(state),
const SizedBox(height: 24),
Text(
state.storeName,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
),
),
const SizedBox(height: 12),
if (state.activityType.isNotEmpty)
Container(
padding: const EdgeInsets.symmetric(
vertical: 8,
horizontal: 16,
),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300),
borderRadius: BorderRadius.circular(15),
),
child: Text(
state.activityType.split(' ').sublist(1).join(' '),
style: const TextStyle(fontSize: 16),
),
),
const SizedBox(height: 8),
TextButton.icon(
onPressed: () {
Navigator.of(context).pop();
},
icon: SvgPicture.asset(
Assets.icons.edit,
width: 20,
color: AppColors.button,
),
label: const Text(
"ویرایش",
style: TextStyle(color: AppColors.button, fontSize: 16),
),
),
if (state.workingDays.isNotEmpty)
_buildInfoRow(
icon: Assets.icons.clock,
text:
"${state.workingDays.map((day) => _translateDay(day)).join('، ')}\nاز ساعت ${state.startTime} تا ${state.endTime}",
),
if (state.contactPhone != null &&
state.contactPhone!.isNotEmpty)
_buildInfoRow(
icon: Assets.icons.callCalling,
text: state.contactPhone!,
),
if (state.licenseNumber != null &&
state.licenseNumber!.isNotEmpty)
_buildInfoRow(
icon: Assets.icons.documentText,
text: "شماره جواز کسب ${state.licenseNumber!}",
),
if (state.address.isNotEmpty)
_buildInfoRow(
icon: Assets.icons.location,
text: state.address,
),
const SizedBox(height: 24),
if (state.latitude != null && state.longitude != null)
_buildMapView(state.latitude!, state.longitude!),
const SizedBox(height: 40),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: state.isSubmitting ? null : () {
context.read<StoreInfoBloc>().add(SubmitStoreInfo());
},
child: state.isSubmitting
? const CircularProgressIndicator(color: Colors.white)
: const Text("ثبت"),
),
),
const SizedBox(height: 24),
],
),
);
},
),
));
}
Widget _buildStoreLogo(StoreInfoState state) {
return CircleAvatar(
radius: 65,
backgroundColor: AppColors.uploadElevated,
backgroundImage:
state.logoPath != null ? FileImage(File(state.logoPath!)) : null,
child: null,
);
}
Widget _buildInfoRow({required String icon, required String text}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Row(
children: [
SvgPicture.asset(
icon,
width: 24,
color: Color.fromARGB(255, 161, 160, 160),
),
const SizedBox(width: 16),
Expanded(
child: Text(
text,
style: const TextStyle(fontSize: 14, height: 1.5),
textAlign: TextAlign.right,
),
),
],
),
);
}
Widget _buildMapView(double latitude, double longitude) {
return SizedBox(
height: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: FlutterMap(
options: MapOptions(
initialCenter: LatLng(latitude, longitude),
initialZoom: 15.0,
),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
),
MarkerLayer(
markers: [
Marker(
width: 80.0,
height: 80.0,
point: LatLng(latitude, longitude),
child: const Icon(
Icons.location_on,
color: Colors.red,
size: 40.0,
),
),
],
),
],
),
),
);
}
PreferredSizeWidget _buildCustomAppBar(BuildContext context) {
return PreferredSize(
preferredSize: const Size.fromHeight(70.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(15),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: [
const SizedBox(height: 15),
Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 8),
child: SvgPicture.asset(Assets.icons.logoWithName),
),
const Spacer(),
Row(
children: [
IconButton(
onPressed: () {},
icon: SvgPicture.asset(
Assets.icons.discountShape,
color: Colors.black,
),
),
IconButton(
onPressed: () {},
icon: SvgPicture.asset(Assets.icons.scanBarcode),
),
],
),
],
),
],
),
),
),
),
);
}
String _translateDay(String day) {
const Map<String, String> dayTranslations = {
'Saturday': 'شنبه',
'Sunday': 'یکشنبه',
'Monday': 'دوشنبه',
'Tuesday': 'سه‌شنبه',
'Wednesday': 'چهارشنبه',
'Thursday': 'پنج‌شنبه',
'Friday': 'جمعه',
};
return dayTranslations[day] ?? day;
}
}

View File

@ -32,7 +32,6 @@ class _WorkingHoursDialogState extends State<WorkingHoursDialog> {
children: [
const Text("روزهای فعالیت را انتخاب کنید:"),
const SizedBox(height: 8),
// ویجت برای نمایش و انتخاب روزها
Wrap(
spacing: 4.0,
runSpacing: 8.0,
@ -51,7 +50,6 @@ class _WorkingHoursDialogState extends State<WorkingHoursDialog> {
const Divider(height: 32),
const Text("بازه ساعت کاری را مشخص کنید:"),
const SizedBox(height: 16),
// انتخابگرهای ساعت شروع و پایان
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
@ -73,7 +71,6 @@ class _WorkingHoursDialogState extends State<WorkingHoursDialog> {
),
ElevatedButton(
onPressed: () {
// فقط در صورتی که تمام مقادیر انتخاب شده باشند، بازگشت انجام شود
if (_startTime != null && _endTime != null) {
final selectedDays = _days.entries
.where((entry) => entry.value['isSelected'])
@ -81,12 +78,10 @@ class _WorkingHoursDialogState extends State<WorkingHoursDialog> {
.toList();
if (selectedDays.isNotEmpty) {
// فرمت کردن ساعت به رشته "HH:mm"
final format = NumberFormat("00");
final startTimeString = "${format.format(_startTime!.hour)}:${format.format(_startTime!.minute)}";
final endTimeString = "${format.format(_endTime!.hour)}:${format.format(_endTime!.minute)}";
// بازگرداندن نتیجه به صفحه قبل
Navigator.of(context).pop({
'days': selectedDays,
'startTime': startTimeString,

View File

@ -1,8 +1,16 @@
import 'dart:convert';
import 'package:bloc/bloc.dart';
import 'package:business_panel/core/services/token_storage_service.dart';
import 'package:business_panel/presentation/store_info/bloc/store_info_state.dart';
import 'package:dio/dio.dart';
part 'store_info_event.dart';
class StoreInfoBloc extends Bloc<StoreInfoEvent, StoreInfoState> {
final Dio _dio = Dio();
final TokenStorageService _tokenStorage = TokenStorageService();
StoreInfoBloc() : super(StoreInfoState()) {
on<StoreLogoChanged>((event, emit) {
emit(state.copyWith(logoPath: event.imagePath));
@ -13,26 +21,42 @@ class StoreInfoBloc extends Bloc<StoreInfoEvent, StoreInfoState> {
});
on<ActivityTypeChanged>((event, emit) {
emit(state.copyWith(activityType: event.activityType));
emit(state.copyWith(activityTypeId: event.activityTypeId));
});
on<SubmitStoreInfo>((event, emit) async {
emit(state.copyWith(isSubmitting: true));
await Future.delayed(const Duration(seconds: 2));
if (state.storeName.isEmpty || state.activityType.isEmpty) {
emit(state.copyWith(isSubmitting: false, errorMessage: "فیلدهای ستاره‌دار اجباری هستند."));
} else {
emit(state.copyWith(isSubmitting: false, isSuccess: true));
}
on<ProvinceChanged>((event, emit) {
emit(state.copyWith(province: event.province));
});
on<CityChanged>((event, emit) {
emit(state.copyWith(city: event.city));
});
on<AddressChanged>((event, emit) {
emit(state.copyWith(address: event.address));
});
on<PlaqueChanged>((event, emit) {
emit(state.copyWith(plaque: event.plaque));
});
on<PostalCodeChanged>((event, emit) {
emit(state.copyWith(postalCode: event.postalCode));
});
on<ContactPhoneChanged>((event, emit) {
emit(state.copyWith(contactPhone: event.phone));
});
on<LicenseNumberChanged>((event, emit) {
emit(state.copyWith(licenseNumber: event.license));
});
on<StoreLocationChanged>((event, emit) {
emit(state.copyWith(latitude: event.latitude, longitude: event.longitude));
});
on<WorkingScheduleChanged>((event, emit) {
on<WorkingScheduleChanged>((event, emit) {
emit(state.copyWith(
workingDays: event.days,
startTime: event.startTime,
@ -40,6 +64,89 @@ class StoreInfoBloc extends Bloc<StoreInfoEvent, StoreInfoState> {
));
});
on<StoreFeatureAdded>((event, emit) {
if (state.features.length < 3) {
final updatedFeatures = List<String>.from(state.features)..add('');
emit(state.copyWith(features: updatedFeatures));
}
});
on<StoreFeatureRemoved>((event, emit) {
final updatedFeatures = List<String>.from(state.features)..removeAt(event.index);
emit(state.copyWith(features: updatedFeatures));
});
on<StoreFeatureUpdated>((event, emit) {
final updatedFeatures = List<String>.from(state.features);
if (event.index < updatedFeatures.length) {
updatedFeatures[event.index] = event.value;
emit(state.copyWith(features: updatedFeatures));
}
});
on<SubmitStoreInfo>((event, emit) async {
emit(state.copyWith(isSubmitting: true, errorMessage: null));
try {
final token = await _tokenStorage.getAccessToken();
if (token == null) {
emit(state.copyWith(isSubmitting: false, errorMessage: "خطای احراز هویت. لطفا دوباره وارد شوید."));
return;
}
final schedule = state.workingDays.map((day) {
return {
'Day': day,
'StartTime': state.startTime,
'EndTime': state.endTime,
'Status': true,
};
}).toList();
final Map<String, dynamic> data = {
'Name': state.storeName,
'Category': state.activityTypeId,
'Province': state.province,
'City': state.city,
'Address': state.address,
'Property': jsonEncode(state.features),
'ShopNumber': state.plaque,
'PostalCode': state.postalCode,
'BusinessLicense': state.licenseNumber,
'Coordinates': jsonEncode({
'longitude': state.longitude?.toString(),
'latitude': state.latitude?.toString(),
}),
'Schedule': jsonEncode(schedule),
};
if (state.logoPath != null && state.logoPath!.isNotEmpty) {
data['Logo'] = await MultipartFile.fromFile(
state.logoPath!,
filename: state.logoPath!.split('/').last,
);
}
final formData = FormData.fromMap(data);
await _dio.post(
'https://fartak.liara.run/shop/add',
data: formData,
options: Options(
headers: {'Authorization': 'Bearer $token'},
),
);
emit(state.copyWith(isSubmitting: false, isSuccess: true));
} on DioException catch (e) {
emit(state.copyWith(
isSubmitting: false,
errorMessage: e.response?.data['message'] ?? 'خطایی در ارتباط با سرور رخ داد.'));
} catch (e) {
print('یک خطای پیش‌بینی نشده رخ داد: ${e.toString()}');
emit(state.copyWith(isSubmitting: false, errorMessage: 'یک خطای پیش‌بینی نشده رخ داد: ${e.toString()}'));
}
});
}
}

View File

@ -13,10 +13,11 @@ class StoreNameChanged extends StoreInfoEvent {
}
class ActivityTypeChanged extends StoreInfoEvent {
final String activityType;
ActivityTypeChanged(this.activityType);
final String activityTypeId;
ActivityTypeChanged(this.activityTypeId);
}
class ProvinceChanged extends StoreInfoEvent {
final String province;
ProvinceChanged(this.province);
@ -71,5 +72,18 @@ class WorkingScheduleChanged extends StoreInfoEvent {
});
}
class StoreFeatureAdded extends StoreInfoEvent {}
class StoreFeatureRemoved extends StoreInfoEvent {
final int index;
StoreFeatureRemoved(this.index);
}
class StoreFeatureUpdated extends StoreInfoEvent {
final int index;
final String value;
StoreFeatureUpdated(this.index, this.value);
}
class SubmitStoreInfo extends StoreInfoEvent {}

View File

@ -1,5 +1,3 @@
import 'package:equatable/equatable.dart';
class StoreInfoState {
final String? logoPath;
final String storeName;
@ -19,6 +17,8 @@ class StoreInfoState {
final List<String> workingDays;
final String? startTime;
final String? endTime;
final List<String> features;
final String? activityTypeId;
StoreInfoState({
this.logoPath,
@ -36,9 +36,11 @@ class StoreInfoState {
this.longitude,
this.contactPhone,
this.licenseNumber,
this.workingDays = const [], // مقدار اولیه یک لیست خالی است
this.workingDays = const [],
this.startTime,
this.endTime,
this.features = const [],
this.activityTypeId,
});
StoreInfoState copyWith({
@ -60,6 +62,8 @@ class StoreInfoState {
List<String>? workingDays,
String? startTime,
String? endTime,
List<String>? features,
String? activityTypeId,
}) {
return StoreInfoState(
logoPath: logoPath ?? this.logoPath,
@ -80,28 +84,30 @@ class StoreInfoState {
workingDays: workingDays ?? this.workingDays,
startTime: startTime ?? this.startTime,
endTime: endTime ?? this.endTime,
features: features ?? this.features,
activityTypeId: activityTypeId ?? this.activityTypeId,
);
}
@override
List<Object?> get props => [
logoPath,
storeName,
activityType,
province,
city,
address,
plaque,
postalCode,
isSubmitting,
isSuccess,
errorMessage,
latitude,
longitude,
contactPhone,
licenseNumber,
workingDays,
startTime,
endTime,
];
}
logoPath,
storeName,
activityType,
province,
city,
address,
plaque,
postalCode,
isSubmitting,
isSuccess,
errorMessage,
latitude,
longitude,
contactPhone,
licenseNumber,
workingDays,
startTime,
endTime,
features,
];
}

View File

@ -0,0 +1,89 @@
import 'package:business_panel/core/config/app_colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
Future<void> showInfoDialog(
BuildContext context, {
required String title,
required String content,
required String iconPath,
}) async {
await showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
elevation: 10,
backgroundColor: Colors.white,
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.topCenter,
children: [
Padding(
padding: const EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
title,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Text(
content,
style: const TextStyle(color: AppColors.hint, fontSize: 16, height: 1.6),
textAlign: TextAlign.start,
),
const SizedBox(height: 24),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: const BorderSide(color: AppColors.border),
),
padding: const EdgeInsets.symmetric(
horizontal: 90, vertical: 10),
),
onPressed: () async {
Navigator.of(context).pop();
},
child: const Text(
"متوجه شدم",
style: TextStyle(color: Colors.white),
),
),
],
),
),
Positioned(
top: -40,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 8,
offset: const Offset(0, 4),
),
],
),
child: CircleAvatar(
backgroundColor: Colors.white,
radius: 40,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: SvgPicture.asset(iconPath, height: 60, width: 60),
),
),
),
),
],
),
);
},
);
}

View File

@ -241,6 +241,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.11"
dio:
dependency: "direct main"
description:
name: dio
sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9"
url: "https://pub.dev"
source: hosted
version: "5.8.0+1"
dio_web_adapter:
dependency: transitive
description:
name: dio_web_adapter
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
equatable:
dependency: "direct main"
description:
@ -379,6 +395,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.28"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea"
url: "https://pub.dev"
source: hosted
version: "9.2.4"
flutter_secure_storage_linux:
dependency: transitive
description:
name: flutter_secure_storage_linux
sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
url: "https://pub.dev"
source: hosted
version: "1.2.3"
flutter_secure_storage_macos:
dependency: transitive
description:
name: flutter_secure_storage_macos
sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247"
url: "https://pub.dev"
source: hosted
version: "3.1.3"
flutter_secure_storage_platform_interface:
dependency: transitive
description:
name: flutter_secure_storage_platform_interface
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_secure_storage_web:
dependency: transitive
description:
name: flutter_secure_storage_web
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
url: "https://pub.dev"
source: hosted
version: "1.2.1"
flutter_secure_storage_windows:
dependency: transitive
description:
name: flutter_secure_storage_windows
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
url: "https://pub.dev"
source: hosted
version: "3.1.2"
flutter_svg:
dependency: "direct main"
description:
@ -617,10 +681,10 @@ packages:
dependency: transitive
description:
name: js
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.7.2"
version: "0.6.7"
json_annotation:
dependency: transitive
description:
@ -781,6 +845,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev"
source: hosted
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9
url: "https://pub.dev"
source: hosted
version: "2.2.17"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
path_provider_linux:
dependency: transitive
description:

View File

@ -46,6 +46,8 @@ dependencies:
equatable: ^2.0.7
intl: ^0.19.0
geolocator: ^14.0.2
dio: ^5.8.0+1
flutter_secure_storage: ^9.2.4
dev_dependencies: