Merge pull request 'fix_metrics' (#22) from fix_metrics into diary
Reviewed-on: maxxkim/eatvio_app#22
@@ -1,12 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="50px" height="50px" viewBox="0 0 50 50" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,24.705882%,29.411765%);fill-opacity:1;" d="M 5.449219 42.066406 L 1.972656 49.019531 C 1.652344 49.675781 1.28125 50 0.867188 50 C 0.289062 50 0 49.421875 0 48.269531 L 0 38.988281 C 0 37.617188 0.320312 36.929688 0.957031 36.929688 C 1.597656 36.929688 1.914062 37.617188 1.914062 38.988281 L 1.914062 44.96875 L 5.460938 37.871094 C 5.773438 37.242188 6.113281 36.929688 6.476562 36.929688 C 7.066406 36.929688 7.363281 37.582031 7.363281 38.886719 L 7.363281 47.9375 C 7.363281 49.3125 7.042969 50 6.40625 50 C 5.765625 50 5.449219 49.3125 5.449219 47.9375 Z M 5.449219 42.066406 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,24.705882%,29.411765%);fill-opacity:1;" d="M 12.921875 39.792969 C 12.230469 39.792969 11.800781 39.765625 11.628906 39.707031 C 11.113281 39.542969 10.855469 39.125 10.855469 38.449219 C 10.855469 37.539062 11.308594 37.085938 12.21875 37.085938 L 15.554688 37.085938 C 16.460938 37.085938 16.914062 37.539062 16.914062 38.449219 C 16.914062 39.125 16.65625 39.542969 16.140625 39.707031 C 15.972656 39.765625 15.542969 39.792969 14.851562 39.792969 L 14.851562 47.9375 C 14.851562 49.3125 14.53125 50 13.890625 50 C 13.246094 50 12.921875 49.3125 12.921875 47.9375 Z M 12.921875 39.792969 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,24.705882%,29.411765%);fill-opacity:1;" d="M 21.71875 49.84375 C 21.230469 49.84375 20.894531 49.71875 20.703125 49.476562 C 20.507812 49.21875 20.414062 48.730469 20.414062 48.007812 L 20.414062 39.128906 C 20.414062 38.371094 20.507812 37.84375 20.703125 37.539062 C 20.894531 37.238281 21.238281 37.085938 21.738281 37.085938 L 23.308594 37.085938 C 24.070312 37.085938 24.71875 37.324219 25.25 37.800781 C 25.894531 38.371094 26.21875 39.195312 26.21875 40.265625 C 26.21875 41.652344 25.886719 42.589844 25.226562 43.078125 L 25.226562 43.132812 C 25.71875 43.363281 26.070312 43.707031 26.289062 44.164062 C 26.503906 44.605469 26.609375 45.21875 26.609375 45.996094 C 26.609375 47.292969 26.316406 48.277344 25.722656 48.953125 C 25.199219 49.546875 24.496094 49.84375 23.609375 49.84375 Z M 22.328125 44.339844 L 22.328125 47.34375 L 23.285156 47.34375 C 23.695312 47.34375 24 47.261719 24.199219 47.097656 C 24.460938 46.878906 24.589844 46.480469 24.589844 45.910156 C 24.589844 45.246094 24.464844 44.804688 24.210938 44.582031 C 24.027344 44.417969 23.707031 44.339844 23.253906 44.339844 Z M 22.328125 39.566406 L 22.328125 42.066406 L 23.160156 42.066406 C 23.535156 42.066406 23.800781 41.996094 23.957031 41.855469 C 24.171875 41.671875 24.28125 41.320312 24.28125 40.808594 C 24.28125 39.980469 23.90625 39.566406 23.160156 39.566406 Z M 22.328125 39.566406 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,24.705882%,29.411765%);fill-opacity:1;" d="M 36.039062 42.066406 L 32.566406 49.019531 C 32.242188 49.675781 31.871094 50 31.457031 50 C 30.878906 50 30.589844 49.421875 30.589844 48.269531 L 30.589844 38.988281 C 30.589844 37.617188 30.910156 36.929688 31.550781 36.929688 C 32.1875 36.929688 32.507812 37.617188 32.507812 38.988281 L 32.507812 44.96875 L 36.050781 37.871094 C 36.367188 37.242188 36.703125 36.929688 37.066406 36.929688 C 37.660156 36.929688 37.953125 37.582031 37.953125 38.886719 L 37.953125 47.9375 C 37.953125 49.3125 37.636719 50 36.996094 50 C 36.359375 50 36.039062 49.3125 36.039062 47.9375 Z M 36.039062 42.066406 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,24.705882%,29.411765%);fill-opacity:1;" d="M 41.933594 43.480469 C 41.933594 41.570312 42.285156 40.015625 42.992188 38.816406 C 43.726562 37.558594 44.714844 36.929688 45.960938 36.929688 C 47.214844 36.929688 48.207031 37.550781 48.9375 38.796875 C 49.644531 39.996094 50 41.558594 50 43.480469 C 50 45.390625 49.644531 46.949219 48.9375 48.148438 C 48.199219 49.382812 47.207031 50 45.960938 50 C 44.714844 50 43.726562 49.375 42.992188 48.128906 C 42.285156 46.941406 41.933594 45.390625 41.933594 43.480469 Z M 43.964844 43.515625 C 43.964844 44.566406 44.121094 45.433594 44.4375 46.121094 C 44.789062 46.925781 45.296875 47.324219 45.960938 47.324219 C 46.621094 47.324219 47.132812 46.929688 47.496094 46.136719 C 47.8125 45.4375 47.96875 44.566406 47.96875 43.515625 C 47.96875 42.433594 47.820312 41.542969 47.519531 40.84375 C 47.15625 40.015625 46.636719 39.601562 45.960938 39.601562 C 45.28125 39.601562 44.765625 40.015625 44.414062 40.84375 C 44.113281 41.542969 43.964844 42.433594 43.964844 43.515625 Z M 43.964844 43.515625 "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(26.27451%,65.098039%,94.901961%);fill-opacity:1;" d="M 25.003906 0 C 30.546875 0 35.042969 3.753906 35.042969 12.304688 C 35.042969 20.84375 30.546875 27.777344 25.003906 27.777344 C 19.453125 27.777344 14.957031 20.84375 14.957031 12.304688 C 14.957031 3.753906 19.453125 0 25.003906 0 Z M 25.003906 0 "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 24.96875 18.042969 C 23.640625 18.042969 22.339844 17.644531 21.121094 16.882812 C 19.90625 16.109375 18.8125 14.980469 17.902344 13.5625 C 17.484375 12.917969 17.507812 11.886719 17.945312 11.28125 C 18.390625 10.664062 19.085938 10.703125 19.507812 11.34375 C 20.207031 12.441406 21.054688 13.3125 21.992188 13.902344 C 22.933594 14.5 23.941406 14.804688 24.96875 14.804688 C 25.992188 14.804688 27 14.5 27.9375 13.902344 C 28.878906 13.3125 29.726562 12.441406 30.425781 11.34375 C 30.847656 10.703125 31.542969 10.664062 31.988281 11.28125 C 32.425781 11.886719 32.449219 12.917969 32.03125 13.5625 C 31.121094 14.980469 30.027344 16.109375 28.808594 16.882812 C 27.59375 17.644531 26.292969 18.042969 24.96875 18.042969 Z M 24.96875 18.042969 "/>
|
||||
</g>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="234"
|
||||
height="234"
|
||||
viewBox="0 0 234 234"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg7"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs7" />
|
||||
<g
|
||||
id="g7"
|
||||
transform="translate(0,40)">
|
||||
<path
|
||||
d="M 25.496,128.722 9.23691,150.005 C 7.72443,152.002 5.99589,153 4.05128,153 1.35043,153 0,151.235 0,147.706 V 119.31 C 0,115.103 1.49447,113 4.48341,113 c 2.98894,0 4.48341,2.103 4.48341,6.31 v 18.289 L 25.55,115.888 c 1.4765,-1.925 3.061,-2.888 4.7535,-2.888 2.7729,0 4.1593,1.996 4.1593,5.989 v 27.701 c 0,4.207 -1.4944,6.31 -4.4834,6.31 -2.9889,0 -4.4834,-2.103 -4.4834,-6.31 z"
|
||||
fill="#323f4b"
|
||||
id="path1" />
|
||||
<path
|
||||
d="m 60.4763,121.77 c -3.2411,0 -5.2577,-0.089 -6.0499,-0.267 -2.4128,-0.499 -3.6192,-1.783 -3.6192,-3.851 0,-2.78 2.1247,-4.171 6.374,-4.171 h 15.6109 c 4.2494,0 6.374,1.391 6.374,4.171 0,2.068 -1.2063,3.352 -3.6191,3.851 -0.7922,0.178 -2.8089,0.267 -6.0499,0.267 v 24.92 c 0,4.207 -1.4945,6.31 -4.4834,6.31 -3.025,0 -4.5374,-2.103 -4.5374,-6.31 z"
|
||||
fill="#323f4b"
|
||||
id="path2" />
|
||||
<path
|
||||
d="m 101.636,152.519 c -2.2688,0 -3.8533,-0.375 -4.7535,-1.123 -0.9003,-0.785 -1.3505,-2.282 -1.3505,-4.492 v -27.166 c 0,-2.317 0.4502,-3.939 1.3505,-4.866 0.9002,-0.927 2.5208,-1.391 4.8615,-1.391 h 7.346 c 3.565,0 6.59,0.731 9.075,2.193 3.025,1.747 4.538,4.26 4.538,7.54 0,4.242 -1.549,7.112 -4.646,8.61 v 0.16 c 2.305,0.713 3.961,1.765 4.97,3.155 1.008,1.355 1.512,3.226 1.512,5.615 0,3.957 -1.386,6.97 -4.159,9.037 -2.449,1.819 -5.744,2.728 -9.885,2.728 z m 2.863,-16.845 v 9.198 h 4.483 c 1.909,0 3.331,-0.25 4.268,-0.749 1.224,-0.677 1.836,-1.889 1.836,-3.636 0,-2.032 -0.594,-3.387 -1.782,-4.065 -0.865,-0.499 -2.359,-0.748 -4.484,-0.748 z m 0,-14.599 v 7.647 h 3.889 c 1.765,0 3.007,-0.214 3.727,-0.642 1.009,-0.57 1.513,-1.64 1.513,-3.208 0,-2.532 -1.747,-3.797 -5.24,-3.797 z"
|
||||
fill="#323f4b"
|
||||
id="path3" />
|
||||
<path
|
||||
d="m 168.662,128.722 -16.259,21.283 c -1.512,1.997 -3.241,2.995 -5.186,2.995 -2.7,0 -4.051,-1.765 -4.051,-5.294 V 119.31 c 0,-4.207 1.495,-6.31 4.484,-6.31 2.989,0 4.483,2.103 4.483,6.31 v 18.289 l 16.583,-21.711 c 1.477,-1.925 3.061,-2.888 4.754,-2.888 2.773,0 4.159,1.996 4.159,5.989 v 27.701 c 0,4.207 -1.494,6.31 -4.483,6.31 -2.989,0 -4.484,-2.103 -4.484,-6.31 z"
|
||||
fill="#323f4b"
|
||||
id="path4" />
|
||||
<path
|
||||
d="m 196.242,133.053 c 0,-5.846 1.657,-10.606 4.97,-14.278 3.421,-3.85 8.048,-5.775 13.882,-5.775 5.87,0 10.515,1.907 13.936,5.722 3.313,3.672 4.97,8.449 4.97,14.331 0,5.847 -1.657,10.607 -4.97,14.279 -3.457,3.779 -8.102,5.668 -13.936,5.668 -5.834,0 -10.461,-1.907 -13.882,-5.722 -3.313,-3.636 -4.97,-8.378 -4.97,-14.225 z m 9.507,0.107 c 0,3.209 0.738,5.865 2.215,7.968 1.656,2.46 4.033,3.69 7.13,3.69 3.097,0 5.492,-1.212 7.184,-3.636 1.477,-2.139 2.215,-4.813 2.215,-8.022 0,-3.315 -0.702,-6.042 -2.107,-8.181 -1.692,-2.532 -4.123,-3.797 -7.292,-3.797 -3.169,0 -5.582,1.265 -7.238,3.797 -1.405,2.139 -2.107,4.866 -2.107,8.181 z"
|
||||
fill="#323f4b"
|
||||
id="path5" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 117.015,0 C 142.967,0 164,11.4817 164,37.6492 164,63.7871 142.967,85 117.015,85 91.0329,85 70,63.7871 70,37.6492 70,11.4817 91.0329,0 117.015,0 Z"
|
||||
fill="#43a6f2"
|
||||
id="path6" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="m 116.858,55.2072 c -6.217,0 -12.315,-1.2103 -18.0039,-3.5464 -5.6885,-2.3643 -10.8198,-5.8262 -15.0715,-10.1607 -1.9646,-1.9702 -1.8473,-5.1225 0.2053,-6.9802 2.0818,-1.8857 5.3366,-1.7731 7.3011,0.1971 3.2841,3.3493 7.2425,6.0232 11.641,7.8245 4.398,1.8295 9.119,2.7583 13.928,2.7583 4.779,0 9.5,-0.9288 13.898,-2.7583 4.399,-1.8013 8.357,-4.4752 11.641,-7.8245 1.965,-1.9702 5.219,-2.0828 7.301,-0.1971 2.053,1.8577 2.17,5.01 0.206,6.9802 -4.252,4.3345 -9.383,7.7964 -15.072,10.1607 -5.688,2.3361 -11.787,3.5464 -17.974,3.5464 z"
|
||||
fill="#ffffff"
|
||||
id="path7" />
|
||||
</g>
|
||||
<rect
|
||||
style="fill:#e6e6e6;stroke:#000000;fill-opacity:0;stroke-opacity:0"
|
||||
id="rect7"
|
||||
width="234"
|
||||
height="234"
|
||||
x="0.70127594"
|
||||
y="0.28842428" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 4.1 KiB |
3
assets/images/img_nav_bell.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="20" height="26" viewBox="0 0 20 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.35574 0.0773487C8.44252 0.298117 7.72096 0.966084 7.40528 1.88312C7.30944 2.1605 7.29253 2.35863 7.29253 3.16811V4.11912L7.14033 4.18138C7.05577 4.20969 6.78519 4.33988 6.53715 4.47008C4.44576 5.52864 2.90681 7.63443 2.53475 9.94968C2.48966 10.244 2.33182 11.7328 2.17961 13.2499L1.90903 16.0123L1.59898 16.1878C0.90561 16.5784 0.268609 17.4445 0.0713075 18.271C-0.0357989 18.7125 -0.0188873 19.5276 0.0994934 19.9409C0.42645 21.0504 1.22129 21.8769 2.3149 22.2448C2.67568 22.3637 2.80534 22.3693 4.68816 22.392L6.67244 22.409V22.7429C6.67244 23.5581 7.02195 24.3959 7.61949 25.0016C8.04228 25.4318 8.43688 25.6752 9.01187 25.862C9.56431 26.0488 10.4832 26.0432 11.0131 25.862C12.3942 25.3808 13.3243 24.1242 13.3243 22.7429V22.4033H15.1282C17.2252 22.4033 17.5409 22.3637 18.2512 21.9901C19.0404 21.5825 19.6323 20.8409 19.8973 19.9409C20.0495 19.4088 20.0326 18.588 19.8465 18.0162C19.5872 17.2294 19.0517 16.5558 18.3696 16.1708L18.0877 16.0123L17.8171 13.2499C17.6649 11.7328 17.5071 10.244 17.4564 9.94968C17.2703 8.80621 16.7517 7.58915 16.0527 6.65513C15.286 5.62487 14.0571 4.66255 12.941 4.21535L12.7042 4.11912V3.19075C12.7042 2.42655 12.6817 2.20012 12.5915 1.90577C12.1743 0.54719 10.7425 -0.262297 9.35574 0.0773487ZM10.2971 1.93407C10.7256 2.11521 10.8947 2.48882 10.9003 3.2417V3.63795H9.99838H9.09643V3.2417C9.10207 2.50014 9.27118 2.12087 9.68833 1.93407C9.90818 1.83784 10.0717 1.83784 10.2971 1.93407ZM10.844 5.5626C12.7324 5.8513 14.3728 7.07968 15.162 8.78922C15.5566 9.64966 15.6074 9.94402 15.9456 13.3065C16.1147 15.0274 16.2726 16.5048 16.2895 16.601C16.3797 17.0426 16.701 17.4219 17.1971 17.6709C17.7946 17.9709 18.1103 18.4408 18.1159 19.0352C18.1159 19.4767 17.9355 19.873 17.6029 20.156C17.1407 20.5579 17.5466 20.5353 9.99838 20.5353C2.24162 20.5353 2.7997 20.5692 2.29236 20.0598C1.80756 19.5729 1.71173 18.9955 2.02741 18.3785C2.17961 18.0728 2.4051 17.869 2.80534 17.6653C3.29577 17.4219 3.61709 17.0426 3.70729 16.601C3.7242 16.5048 3.88204 15.0274 4.05115 13.3065C4.38939 9.94402 4.44012 9.64966 4.83472 8.78922C5.61265 7.10232 7.27562 5.84564 9.12461 5.55694C9.73907 5.46071 10.2126 5.46071 10.844 5.5626ZM11.464 22.6467C11.464 23.2071 11.154 23.7166 10.6523 23.9713C9.69961 24.4751 8.53271 23.7449 8.53271 22.6467V22.4033H9.99838H11.464V22.6467Z" fill="#7B8794"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1016 B After Width: | Height: | Size: 1016 B |
3
assets/images/img_nav_diets.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.85135 0.0804901C1.70635 0.166418 1.60445 0.349989 1.33405 1.02569C0.656067 2.7208 0.185793 4.6776 0.0329544 6.44302C-0.0336677 7.21636 0.00552179 8.94662 0.107414 9.59108C0.275929 10.6495 0.53458 11.5635 0.918637 12.4345C2.14919 15.2232 4.88853 17.7346 8.59978 19.4766C9.3914 19.8477 9.79897 20 10.0067 20C10.234 20 10.8453 19.7617 11.7506 19.3165C15.3012 17.5745 17.8838 15.1529 19.1026 12.4228C19.4788 11.5752 19.7414 10.6456 19.9177 9.53249C19.9882 9.07552 20 8.83726 20 7.7163C20 6.60706 19.9882 6.34147 19.9177 5.80247C19.7335 4.47059 19.4631 3.28714 19.0712 2.10369C18.84 1.40846 18.499 0.537468 18.3658 0.30312C18.1777 -0.0327778 17.8563 -0.0835533 17.3155 0.135172C15.4854 0.873365 13.6866 1.93964 12.1739 3.19731C11.492 3.76365 10.6847 4.58777 10.1242 5.29081L10.0067 5.43923L9.71276 5.07599C8.16869 3.16606 5.54692 1.2991 2.84676 0.193758C2.31378 -0.0249653 2.06689 -0.0523071 1.85135 0.0804901ZM3.58352 1.88106C7.14585 3.67772 9.57168 6.15399 10.4809 8.91538C10.8297 9.98556 10.9864 11.0284 10.9825 12.3251C10.9825 13.5633 10.8179 14.8092 10.4848 16.1489C10.332 16.7504 10.0302 17.7346 9.99492 17.7346C9.98317 17.7346 8.80748 14.9342 7.38882 11.5127C5.97016 8.09516 4.77488 5.24003 4.73569 5.17754C4.63772 5.00959 4.45353 4.91585 4.23015 4.91585C3.87744 4.91585 3.63055 5.15801 3.63447 5.50172C3.63447 5.65405 4.06947 6.72814 6.17003 11.7783C7.56517 15.1295 8.74086 17.9534 8.78005 18.0588L8.85451 18.2424L8.45086 18.0432C7.47896 17.555 6.35422 16.8402 5.48421 16.1489C4.85326 15.649 3.77555 14.5866 3.34055 14.0398C2.08648 12.454 1.43986 10.8409 1.24783 8.81773C1.18904 8.185 1.2204 6.59925 1.30661 5.94698C1.4908 4.55262 1.89837 2.94343 2.38432 1.69358L2.50973 1.37331L2.71352 1.45923C2.82717 1.5061 3.21906 1.69358 3.58352 1.88106ZM17.8524 2.32632C18.9967 5.66576 19.1182 8.90757 18.2012 11.3916C17.8759 12.2665 17.3312 13.2117 16.6571 14.0632C16.2456 14.5827 15.1954 15.6216 14.6428 16.063C14.004 16.5707 13.3691 17.0121 12.6951 17.4144C11.9701 17.8479 11.1471 18.2736 11.1745 18.1994C11.1863 18.1682 12.4991 15.0162 14.0863 11.1925C17.2097 3.68944 17.0765 4.03705 16.9001 3.74802C16.6885 3.41213 16.1947 3.37697 15.9243 3.68163C15.8773 3.72849 15.0308 5.72045 14.0432 8.10688L12.2444 12.4423L12.1974 11.6885C12.1464 10.8136 12.0994 10.4386 11.9662 9.76684C11.7702 8.78258 11.4763 7.94284 11.0099 7.0367L10.7395 6.51332L11.0099 6.15399C12.3267 4.41982 14.49 2.76767 16.9275 1.63499L17.4958 1.37331L17.5663 1.53735C17.6055 1.62718 17.7348 1.98261 17.8524 2.32632Z" fill="#2F80ED"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
4
assets/images/img_nav_exit.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.69922 0.0718498C0.894531 0.306305 0.269531 0.947153 0.0625 1.7443C0.0078125 1.95531 0 2.84234 0 10.005C0 16.9214 0.0078125 18.0624 0.0585938 18.2461C0.277344 19.0706 0.929688 19.7232 1.74609 19.9264C2.04688 20.0045 2.16406 20.0045 7.14844 19.9967L12.2461 19.985L12.5039 19.899C13.1758 19.6685 13.7695 19.0745 13.9922 18.4063C14.0781 18.1562 14.082 18.0898 14.0938 16.3196L14.1003 15.2956C14.1032 14.8541 13.7461 14.4948 13.3047 14.4948C12.8615 14.4948 12.5015 14.8524 12.4984 15.2956L12.4922 16.2063L12.4805 17.9218L12.375 18.0624C12.3125 18.1367 12.207 18.2422 12.1406 18.293L12.0117 18.3829H7.04688H2.08594L1.94531 18.2891C1.76172 18.164 1.65234 17.9921 1.60156 17.7576C1.57422 17.6209 1.5625 15.1982 1.57031 9.86429C1.58203 2.42813 1.58594 2.16241 1.65625 2.02956C1.75781 1.83809 1.83203 1.75993 2.01172 1.66224L2.16797 1.58018H7.03125H11.8945L12.0742 1.67006C12.1836 1.72476 12.3008 1.82245 12.3672 1.92015L12.4805 2.08036L12.4922 3.77625L12.4984 4.67139C12.5014 5.11237 12.8598 5.46824 13.3008 5.46824C13.743 5.46824 14.1016 5.10972 14.1016 4.66746V3.73718C14.1016 1.81464 14.0977 1.77556 13.8398 1.24804C13.6563 0.872908 13.2539 0.46261 12.8711 0.263323C12.3281 -0.0180244 12.6875 -0.00239372 7.02734 0.00151253C2.29688 0.00151253 1.91797 0.00932884 1.69922 0.0718498Z" fill="#2F80ED"/>
|
||||
<path d="M15.7422 6.85542C15.4293 7.16838 15.4293 7.67567 15.7422 7.98863L16.0547 8.30123L16.9336 9.18044H11.9023H7.67606C7.23365 9.18044 6.875 9.53909 6.875 9.9815C6.875 10.4239 7.23365 10.7826 7.67606 10.7826H11.9219H16.9727L16.0742 11.6813L15.7422 12.0135C15.4293 12.3264 15.4293 12.8337 15.7422 13.1467C16.055 13.4595 16.5622 13.4595 16.875 13.1467L18.1523 11.8689C18.1587 11.8625 18.1651 11.8561 18.1715 11.8497C19.1997 10.8207 19.1823 9.1592 18.1566 8.12768L16.9029 6.86682C16.5823 6.54447 16.0636 6.53392 15.7422 6.85542Z" fill="#2F80ED"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
7
assets/images/img_nav_feed.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.20343 0.061348C1.644 0.21007 0.70593 0.868757 0.467242 1.35954C0.217366 1.87263 0.0332161 1.50954 0.0332161 9.58142C0.0332161 16.7721 -0.0414616 17.0806 0.0331284 17.3706C0.130095 17.7498 0.243422 18.4085 0.467192 18.6688C0.896085 19.167 2.04446 19.8182 2.63745 19.967C2.92835 20.0413 3.16171 19.967 10.0165 19.967C16.8714 19.967 17.1047 20.0413 17.3956 19.9669C17.556 19.9261 18.0698 19.6309 18.2637 19.5342C18.5658 19.3855 18.8111 19.4212 19.1319 19.1015C19.4526 18.7817 19.4168 18.5372 19.5659 18.236C19.9165 17.5296 20 17.8584 20 10.8796C20 4.06443 19.8345 4.47273 19.5659 3.95592C19.3795 3.60271 18.7363 3.27149 18.3969 3.1079C17.9307 2.88481 17.8673 2.87738 16.2562 2.87738H14.7905V2.60596C14.7905 1.66158 13.9986 0.306738 13.055 0.061348C12.738 -0.0204487 2.50925 -0.0204487 2.20343 0.061348ZM13.0078 1.8103C13.2465 1.92556 13.3844 2.07056 13.5001 2.31967L13.5784 2.48698L13.597 9.83012L13.6157 17.1733L13.7052 17.4335C13.7947 17.7012 13.9439 18.0098 14.0856 18.2255L14.1639 18.3482L8.67036 18.337L3.17307 18.3259L2.94184 18.2478C2.36377 18.047 1.92369 17.6008 1.7484 17.0245C1.685 16.8126 1.68127 16.4705 1.68127 9.66281C1.68127 3.89612 1.69246 2.49814 1.72976 2.38659C1.8491 2.05569 2.14746 1.79543 2.48685 1.7285C2.57635 1.70991 4.9334 1.69876 7.72307 1.69876L12.7952 1.70619L13.0078 1.8103ZM17.8297 3.95592C18.0796 4.07118 18.1481 4.1507 18.2637 4.38865V4.82138V10.8796C18.2637 16.5533 18.3271 16.7259 18.2637 16.9378C18.0251 17.7112 17.3713 18.3073 16.5844 18.3073C15.8049 18.3073 15.4864 17.6963 15.2253 16.9378V10.4469V4.45592C15.2253 4.17978 15.4492 3.95592 15.7253 3.95592H16.0934C17.4137 3.96708 17.6693 3.88156 17.8297 3.95592Z" fill="#7B8794"/>
|
||||
<path d="M3.12399 2.9518C3.05686 2.9927 2.97108 3.07821 2.93006 3.14514C2.8592 3.26411 2.85547 3.33848 2.85547 5.25699C2.85547 7.1755 2.8592 7.24986 2.93006 7.36884C2.97108 7.43576 3.05686 7.52128 3.12399 7.56217C3.24334 7.63282 3.31793 7.63654 5.24235 7.63654C7.16677 7.63654 7.24136 7.63282 7.36071 7.56217C7.42784 7.52128 7.51362 7.43576 7.55464 7.36884C7.6255 7.24986 7.62923 7.1755 7.62923 5.25699C7.62923 3.33848 7.6255 3.26411 7.55464 3.14514C7.51362 3.07821 7.42784 2.9927 7.36071 2.9518C7.24136 2.88116 7.16677 2.87744 5.24235 2.87744C3.31793 2.87744 3.24334 2.88116 3.12399 2.9518ZM6.43579 5.25699V6.44676H5.24235H4.04891V5.25699V4.06721H5.24235H6.43579V5.25699Z" fill="#7B8794"/>
|
||||
<path d="M3.22842 9.23893C2.99346 9.33188 2.85547 9.55497 2.85547 9.83382C2.85547 10.0755 2.95989 10.2502 3.15756 10.3506C3.29555 10.425 3.39625 10.425 7.63669 10.425H11.9741L12.1158 10.3395C12.3247 10.2131 12.403 10.0755 12.403 9.82638C12.403 9.59586 12.3209 9.43599 12.1307 9.2947C12.0263 9.21662 12.0226 9.21662 7.67398 9.20919C4.8321 9.20547 3.28809 9.21662 3.22842 9.23893Z" fill="#7B8794"/>
|
||||
<path d="M3.22842 12.2134C2.99346 12.3064 2.85547 12.5295 2.85547 12.8083C2.85547 13.05 2.95989 13.2247 3.15756 13.3251C3.29555 13.3995 3.39625 13.3995 7.63669 13.3995H11.9741L12.1158 13.314C12.3247 13.1875 12.403 13.05 12.403 12.8009C12.403 12.5704 12.3209 12.4105 12.1307 12.2692C12.0263 12.1911 12.0226 12.1911 7.67398 12.1837C4.8321 12.18 3.28809 12.1911 3.22842 12.2134Z" fill="#7B8794"/>
|
||||
<path d="M3.22842 15.1878C2.99346 15.2808 2.85547 15.5039 2.85547 15.7827C2.85547 16.0244 2.95989 16.1992 3.15756 16.2995C3.29555 16.3739 3.39625 16.3739 7.63669 16.3739H11.9741L12.1158 16.2884C12.3247 16.162 12.403 16.0244 12.403 15.7753C12.403 15.5448 12.3209 15.3849 12.1307 15.2436C12.0263 15.1655 12.0226 15.1655 7.67398 15.1581C4.8321 15.1544 3.28809 15.1655 3.22842 15.1878Z" fill="#7B8794"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
4
assets/images/img_nav_finance.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="15" height="20" viewBox="0 0 15 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.15062 0.0898266C1.85736 0.285101 1.87691 -0.0312443 1.87691 4.60066V8.74439L1.13787 8.76001C0.316728 8.77172 0.277626 8.78344 0.0899351 9.06464C0 9.19352 0 9.20523 0 10.619C0 11.9898 0.00391022 12.0484 0.0821147 12.189C0.234613 12.4546 0.316728 12.4819 1.14569 12.4937L1.87691 12.5093V13.1459V13.7864L1.12614 13.7981C0.402753 13.8098 0.367561 13.8137 0.238524 13.9035C0.00391022 14.0715 0 14.1066 0 15.6766C0 17.0904 0 17.0982 0.0899351 17.231C0.250254 17.4731 0.35974 17.5005 1.16525 17.5005H1.87691V18.5237C1.87691 19.6719 1.88864 19.7422 2.14671 19.9102C2.27966 20 2.28748 20 3.73035 20C5.11066 20 5.18886 19.9961 5.31008 19.9219C5.38047 19.8789 5.4704 19.7891 5.51341 19.7188C5.58771 19.5977 5.59162 19.5196 5.59162 18.5433V17.5005H7.57019C9.50575 17.5005 9.55267 17.5005 9.69735 17.4185C9.99453 17.2505 9.99062 17.2701 9.99062 15.6376C9.99062 14.2316 9.98671 14.1847 9.9085 14.0793C9.86549 14.0207 9.77946 13.9348 9.72081 13.8918C9.61524 13.8137 9.5644 13.8098 7.60147 13.7981L5.59162 13.7864V13.1459V12.5015H7.22609C8.97005 12.5015 9.52139 12.4702 10.1197 12.3413C12.5596 11.8141 14.46 9.84573 14.9214 7.36575C15.0348 6.77211 15.0231 5.56141 14.9019 5.00293C14.6633 3.89377 14.1628 2.89006 13.4629 2.10896C12.544 1.08963 11.5078 0.472565 10.1275 0.128881L9.7169 0.027338L6.00219 0.0156212L2.28357 0L2.15062 0.0898266ZM9.63088 1.26928C11.4804 1.62859 12.9624 2.90568 13.545 4.65143C14.4287 7.29545 12.9624 10.1816 10.3034 11.0291C9.55267 11.2673 9.25549 11.2908 6.86244 11.2908C4.5515 11.2908 4.64143 11.279 4.46547 11.6071C4.37554 11.775 4.37554 11.7789 4.38727 13.1927C4.399 14.5479 4.40291 14.6104 4.48111 14.712C4.52413 14.7706 4.61015 14.8565 4.6688 14.8994C4.77438 14.9775 4.82521 14.9814 6.78814 14.9932L8.798 15.0049V15.6454V16.2859L6.78814 16.2976C4.82521 16.3093 4.77438 16.3132 4.6688 16.3913C4.61015 16.4343 4.52413 16.5202 4.48111 16.5788C4.40291 16.6803 4.399 16.7467 4.38727 17.7583L4.37554 18.8284H3.73426H3.09299L3.08125 17.7583C3.06952 16.7467 3.06561 16.6803 2.98741 16.5788C2.79581 16.321 2.76062 16.3093 1.9512 16.2976L1.21217 16.2859V15.6415V15.001H1.90428C2.52209 15.001 2.61203 14.9932 2.76062 14.919C2.88183 14.8604 2.94831 14.794 3.00696 14.6729C3.08516 14.5167 3.08908 14.4425 3.08908 13.1224C3.08908 11.8492 3.08516 11.7282 3.01478 11.6032C2.86619 11.3259 2.81927 11.3103 1.97075 11.2986L1.21217 11.2869V10.6229V9.9629H1.9512C2.65113 9.9629 2.69414 9.95899 2.81927 9.87307C3.10863 9.6817 3.08908 9.99805 3.08908 5.34271V1.17165L6.18988 1.18727C8.90749 1.19898 9.32979 1.2107 9.63088 1.26928Z" fill="#2F80ED"/>
|
||||
<path d="M4.69172 2.57371C4.61352 2.61667 4.51967 2.71821 4.46884 2.81585L4.37891 2.98379V6.22924C4.37891 9.34582 4.38282 9.48252 4.45711 9.63874C4.50012 9.73637 4.58615 9.83792 4.66044 9.88478C4.78557 9.95899 4.85204 9.96289 6.9792 9.96289C8.30868 9.96289 9.27059 9.94727 9.42309 9.91993C10.2755 9.78714 11.1592 9.256 11.7106 8.5491C11.996 8.1898 12.2893 7.58054 12.4027 7.13141C12.5278 6.63151 12.5278 5.83088 12.4027 5.33879C12.0742 4.02264 11.0497 2.98379 9.71636 2.61276C9.41136 2.52684 9.34489 2.52294 7.11606 2.51513C4.93807 2.50341 4.82076 2.50341 4.69172 2.57371ZM9.36835 3.78441C9.8454 3.90939 10.1504 4.08904 10.5219 4.45615C10.7956 4.72563 10.8894 4.85061 11.0224 5.12009C11.2883 5.66295 11.3587 6.18628 11.2413 6.73696C11.081 7.48681 10.561 8.16246 9.87277 8.49833C9.36835 8.74828 9.32143 8.75219 7.36241 8.75219H5.59107V6.23315V3.71411H7.34285C8.91476 3.71411 9.12592 3.72192 9.36835 3.78441Z" fill="#2F80ED"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
4
assets/images/img_nav_logo.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="44" height="40" viewBox="0 0 44 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.8819 0C33.9607 0 43.75 5.40314 43.75 17.7173C43.75 30.0175 33.9607 40 21.8819 40C9.78925 40 0 30.0175 0 17.7173C0 5.40314 9.78925 0 21.8819 0Z" fill="#43A6F2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.8083 25.9799C18.9151 25.9799 16.0764 25.4103 13.4289 24.311C10.7813 23.1984 8.39309 21.5692 6.41425 19.5295C5.49989 18.6023 5.55448 17.1189 6.50978 16.2447C7.47873 15.3573 8.99357 15.4103 9.90793 16.3374C11.4364 17.9136 13.2788 19.1719 15.3259 20.0196C17.3729 20.8805 19.5701 21.3176 21.8083 21.3176C24.0327 21.3176 26.2299 20.8805 28.277 20.0196C30.3241 19.1719 32.1665 17.9136 33.6949 16.3374C34.6093 15.4103 36.1241 15.3573 37.0931 16.2447C38.0484 17.1189 38.103 18.6023 37.1886 19.5295C35.2098 21.5692 32.8215 23.1984 30.174 24.311C27.5264 25.4103 24.6878 25.9799 21.8083 25.9799Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 971 B |
3
assets/images/img_nav_plans.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18.0529 10V17C18.0529 17.5304 17.8533 18.0391 17.498 18.4142C17.1426 18.7893 16.6607 19 16.1582 19H2.89477C2.39228 19 1.91034 18.7893 1.55498 18.4142C1.19961 18.0391 1 17.5304 1 17V3C1 2.4696 1.19961 1.9609 1.55498 1.5858C1.91034 1.2107 2.39228 1 2.89477 1H13.316" stroke="#2F80ED" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 461 B |
3
assets/images/img_nav_recipes.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="17" height="20" viewBox="0 0 17 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.173112 0.128904C0.0782671 0.222652 0.0347965 0.308588 0.0150371 0.433586C0.0031815 0.527336 -0.00472224 4.57805 0.0031815 9.43344C0.0150371 17.8942 0.018989 18.2692 0.0861708 18.4763C0.339091 19.2106 0.868641 19.734 1.57207 19.9372C1.76572 19.9919 2.48496 19.9997 8.65778 19.9997C16.2375 19.9997 15.6921 20.0192 15.8265 19.7575C15.9529 19.5192 15.8739 19.1677 15.6724 19.0544C15.6052 19.0153 14.2023 18.9997 8.74868 18.9841L1.91194 18.9645L1.68668 18.8552C0.852834 18.4528 0.852834 17.3278 1.68668 16.9255L1.91194 16.8161L9.30589 16.7966C16.6327 16.7771 16.7038 16.7771 16.7907 16.6989C16.9883 16.5232 16.9765 16.9099 16.9923 8.92564C17.0081 1.73435 17.0041 1.41795 16.937 1.19139C16.7315 0.542959 16.3402 0.167967 15.7316 0.0429688C15.5815 0.0117188 13.3249 0 7.91483 0H0.303524L0.173112 0.128904ZM15.6407 1.11326C15.7158 1.15623 15.8107 1.24217 15.8581 1.30076L15.9411 1.41013L15.9529 8.59752L15.9608 15.781H8.95022C4.50832 15.781 1.86847 15.7966 1.73805 15.8201C1.62345 15.8396 1.42586 15.9021 1.29544 15.9529L1.06228 16.0466V8.53111V1.01561L8.28631 1.02342C15.4273 1.03514 15.5064 1.03514 15.6407 1.11326Z" fill="#2F80ED"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
3
assets/images/img_nav_settings.svg
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
6
assets/images/img_nav_support.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="19" height="20" viewBox="0 0 19 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.89072 0.0934658C1.8212 0.372349 0.891395 1.11764 0.409631 2.08892C-0.0191395 2.94481 0.000131078 2.68516 0.000131078 7.69063C0.000131078 12.7105 -0.0191395 12.4365 0.419266 13.3164C0.611971 13.7059 0.71796 13.8405 1.13228 14.254C1.54659 14.6675 1.68149 14.7733 2.07172 14.9656C2.79918 15.3263 3.10269 15.384 4.34564 15.384H5.39589V17.4371C5.39589 19.4037 5.40071 19.4999 5.49224 19.6538C5.54524 19.7403 5.65604 19.8509 5.74276 19.9038C5.95474 20.0288 6.37869 20.0336 6.57621 19.9086C6.65811 19.8605 7.88661 18.8219 9.30781 17.6006L11.8997 15.384H13.5522C15.4648 15.384 15.6382 15.3599 16.4283 14.9656C16.8185 14.7733 16.9534 14.6675 17.3677 14.254C17.782 13.8405 17.888 13.7059 18.0807 13.3164C18.5191 12.4365 18.4999 12.7105 18.4999 7.69063C18.4999 2.67073 18.5191 2.94481 18.0807 2.06488C17.888 1.67541 17.782 1.54077 17.3677 1.12726C16.9534 0.713739 16.8185 0.607956 16.4283 0.415623C15.5274 -0.0315514 16.0332 -0.00270081 9.23073 0.00210762C3.48329 0.00210762 3.23759 0.00691605 2.89072 0.0934658ZM15.3395 1.6706C16.0862 1.94948 16.621 2.51206 16.8474 3.24292C16.9293 3.51219 16.9341 3.80069 16.9341 7.69063C16.9341 11.5806 16.9293 11.8691 16.8474 12.1383C16.621 12.8692 16.0766 13.4414 15.3395 13.7107C15.0697 13.8068 14.9445 13.8116 13.1523 13.8405C11.4854 13.8645 11.2301 13.879 11.1289 13.9511C11.0614 13.9944 10.0979 14.807 8.98503 15.759L6.96162 17.4948L6.93753 15.8936C6.91826 14.4752 6.90381 14.2829 6.82673 14.1675C6.63402 13.8741 6.61957 13.8741 4.98639 13.8405C3.66154 13.8164 3.4592 13.802 3.19423 13.7155C2.45713 13.4751 1.88383 12.8836 1.65258 12.1383C1.57068 11.8691 1.56586 11.5806 1.56586 7.69063C1.56586 3.80069 1.57068 3.51219 1.65258 3.24292C1.92719 2.34377 2.66429 1.71387 3.58927 1.58405C3.74826 1.56482 6.39314 1.55039 9.4668 1.5552L15.0553 1.56001L15.3395 1.6706Z" fill="#2F80ED"/>
|
||||
<path d="M4.00856 6.25294C3.02577 6.63279 2.75598 8.03202 3.51717 8.79654C4.11455 9.38797 5.13589 9.38797 5.73328 8.79654C6.49929 8.02721 6.22468 6.62318 5.22743 6.25294C4.87092 6.1183 4.36025 6.1183 4.00856 6.25294Z" fill="#2F80ED"/>
|
||||
<path d="M8.63357 6.25294C7.65077 6.6328 7.38098 8.03203 8.14217 8.79655C8.91299 9.56108 10.3197 9.287 10.6907 8.29168C10.9171 7.69544 10.7822 7.01266 10.3583 6.58472C9.92951 6.16158 9.22613 6.02695 8.63357 6.25294Z" fill="#2F80ED"/>
|
||||
<path d="M13.2586 6.25294C12.2758 6.6328 12.006 8.03203 12.7672 8.79655C13.538 9.56108 14.9447 9.287 15.3157 8.29168C15.5421 7.69544 15.4072 7.01266 14.9833 6.58472C14.5545 6.16158 13.8511 6.02695 13.2586 6.25294Z" fill="#2F80ED"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -79,7 +79,33 @@ class ImageConstant {
|
||||
|
||||
static String imgEllipse3 = '$imagePath/img_ellipse_3.png';
|
||||
|
||||
static String imgNav = '$imagePath/img_nav.svg';
|
||||
//------------------NAVIGATION---------------------------------
|
||||
|
||||
static String imgDiary = '$imagePath/img_nav_diary.svg';
|
||||
|
||||
static String imgFeed = '$imagePath/img_nav_feed.svg';
|
||||
|
||||
static String imgChat = '$imagePath/img_nav_chat.svg';
|
||||
|
||||
static String imgLogo = '$imagePath/img_nav_logo.svg';
|
||||
|
||||
static String imgBell = '$imagePath/img_nav_bell.svg';
|
||||
|
||||
static String imgSettings = '$imagePath/img_nav_settings.svg';
|
||||
|
||||
static String imgRecipes = '$imagePath/img_nav_recipes.svg';
|
||||
|
||||
static String imgDiets = '$imagePath/img_nav_diets.svg';
|
||||
|
||||
static String imgPlans = '$imagePath/img_nav_plans.svg';
|
||||
|
||||
static String imgFinance = '$imagePath/img_nav_finance.svg';
|
||||
|
||||
static String imgSupport = '$imagePath/img_nav_support.svg';
|
||||
|
||||
static String imgExit = '$imagePath/img_nav_exit.svg';
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
||||
static String imgNavBlueGray400 = '$imagePath/img_nav_blue_gray_400.svg';
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ class UserRegistrationSheet {
|
||||
'favorite_foods': favoriteFoods,
|
||||
'unfavorite_foods': unfavoriteFoods,
|
||||
'additional_info': additionalInfo,
|
||||
'activity_coefficient': '1.2',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class AuthScreen extends StatelessWidget {
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(children: [
|
||||
SizedBox(height: 39.v),
|
||||
SizedBox(height: 36.v),
|
||||
Text("user_authorization".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 60.v),
|
||||
@@ -58,32 +58,32 @@ class AuthScreen extends StatelessWidget {
|
||||
controller: passwordController,
|
||||
);
|
||||
}),
|
||||
Spacer(),
|
||||
SizedBox(height: 50.v),
|
||||
NextStepButton(
|
||||
text: "no_account".tr.toUpperCase(),
|
||||
margin:
|
||||
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapNoAccount(context)),
|
||||
NextStepButton(
|
||||
/*NextStepButton(
|
||||
text: "Тест дневника".toUpperCase(),
|
||||
margin:
|
||||
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapDiaryTest(context)),
|
||||
NextStepButton(
|
||||
text: "Тест профиля".toUpperCase(),
|
||||
text: "Тест чата".toUpperCase(),
|
||||
margin:
|
||||
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapProfileTest(context)),
|
||||
onPressed: onTapProfileTest(context)),*/
|
||||
BlocBuilder<AuthBloc, AuthState>(builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "authentificate".tr.toUpperCase(),
|
||||
margin:
|
||||
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: () => onTapAuth(state, context));
|
||||
onPressed: onTapAuth(state, context));
|
||||
}),
|
||||
])));
|
||||
}
|
||||
@@ -102,6 +102,7 @@ class AuthScreen extends StatelessWidget {
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode(credentials),
|
||||
encoding: utf8);
|
||||
print(response.statusCode);
|
||||
if (response.statusCode == 200) {
|
||||
var res = await jsonDecode(response.body);
|
||||
final box = await Hive.openBox('token');
|
||||
|
||||
20
lib/presentation/chat/chat_screen/bloc/chat_bloc.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_screen/models/chat_model.dart';
|
||||
part 'chat_event.dart';
|
||||
part 'chat_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a Chat according to the event that is dispatched to it.
|
||||
class ChatBloc extends Bloc<ChatEvent, ChatState> {
|
||||
ChatBloc(ChatState initialState) : super(initialState) {
|
||||
on<ChatInitialEvent>(_onInitialize);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
ChatInitialEvent event,
|
||||
Emitter<ChatState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(chatModelObj: state.chatModelObj?.copyWith()));
|
||||
}
|
||||
}
|
||||
28
lib/presentation/chat/chat_screen/bloc/chat_event.dart
Normal file
@@ -0,0 +1,28 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'chat_bloc.dart';
|
||||
|
||||
/// Abstract class for all events that can be dispatched from the
|
||||
///Chat widget.
|
||||
///
|
||||
/// Events must be immutable and implement the [Equatable] interface.
|
||||
@immutable
|
||||
abstract class ChatEvent extends Equatable {}
|
||||
|
||||
/// Event that is dispatched when the Chat widget is first created.
|
||||
class ChatInitialEvent extends ChatEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
///event for dropdown selection
|
||||
class ChangeDropDownEvent extends ChatEvent {
|
||||
ChangeDropDownEvent({required this.value});
|
||||
|
||||
SelectionPopupModel value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
value,
|
||||
];
|
||||
}
|
||||
31
lib/presentation/chat/chat_screen/bloc/chat_state.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'chat_bloc.dart';
|
||||
|
||||
/// Represents the state of Chat in the application.
|
||||
class ChatState extends Equatable {
|
||||
ChatState({
|
||||
this.selectedDropDownValue,
|
||||
this.chatModelObj,
|
||||
});
|
||||
|
||||
SelectionPopupModel? selectedDropDownValue;
|
||||
|
||||
ChatModel? chatModelObj;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
selectedDropDownValue,
|
||||
chatModelObj,
|
||||
];
|
||||
ChatState copyWith({
|
||||
SelectionPopupModel? selectedDropDownValue,
|
||||
ChatModel? chatModelObj,
|
||||
}) {
|
||||
return ChatState(
|
||||
selectedDropDownValue:
|
||||
selectedDropDownValue ?? this.selectedDropDownValue,
|
||||
chatModelObj: chatModelObj ?? this.chatModelObj,
|
||||
);
|
||||
}
|
||||
}
|
||||
20
lib/presentation/chat/chat_screen/chat_screen.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import 'bloc/chat_bloc.dart';
|
||||
import 'models/chat_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChatScreen extends StatelessWidget {
|
||||
const ChatScreen({Key? key}) : super(key: key);
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<ChatBloc>(
|
||||
create: (context) => ChatBloc(ChatState(chatModelObj: ChatModel()))
|
||||
..add(ChatInitialEvent()),
|
||||
child: ChatScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
16
lib/presentation/chat/chat_screen/models/chat_model.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
/// This class defines the variables used in the [chat_screen],
|
||||
/// and is typically used to hold data that is passed between different parts of the application.
|
||||
class ChatModel extends Equatable {
|
||||
ChatModel();
|
||||
|
||||
ChatModel copyWith() {
|
||||
return ChatModel();
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_select_model.dart';
|
||||
part 'chat_select_event.dart';
|
||||
part 'chat_select_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a ChatSelect according to the event that is dispatched to it.
|
||||
class ChatSelectBloc extends Bloc<ChatSelectEvent, ChatSelectState> {
|
||||
ChatSelectBloc(ChatSelectState initialState) : super(initialState) {
|
||||
on<ChatSelectInitialEvent>(_onInitialize);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
ChatSelectInitialEvent event,
|
||||
Emitter<ChatSelectState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
chatSelectModelObj: state.chatSelectModelObj?.copyWith()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'chat_select_bloc.dart';
|
||||
|
||||
/// Abstract class for all events that can be dispatched from the
|
||||
///ChatSelect widget.
|
||||
///
|
||||
/// Events must be immutable and implement the [Equatable] interface.
|
||||
@immutable
|
||||
abstract class ChatSelectEvent extends Equatable {}
|
||||
|
||||
/// Event that is dispatched when the ChatSelect widget is first created.
|
||||
class ChatSelectInitialEvent extends ChatSelectEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
///event for dropdown selection
|
||||
class ChangeDropDownEvent extends ChatSelectEvent {
|
||||
ChangeDropDownEvent({required this.value});
|
||||
|
||||
SelectionPopupModel value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
value,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'chat_select_bloc.dart';
|
||||
|
||||
/// Represents the state of ChatSelect in the application.
|
||||
class ChatSelectState extends Equatable {
|
||||
ChatSelectState({
|
||||
this.selectedDropDownValue,
|
||||
this.chatSelectModelObj,
|
||||
});
|
||||
|
||||
SelectionPopupModel? selectedDropDownValue;
|
||||
|
||||
ChatSelectModel? chatSelectModelObj;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
selectedDropDownValue,
|
||||
chatSelectModelObj,
|
||||
];
|
||||
ChatSelectState copyWith({
|
||||
SelectionPopupModel? selectedDropDownValue,
|
||||
ChatSelectModel? chatSelectModelObj,
|
||||
}) {
|
||||
return ChatSelectState(
|
||||
selectedDropDownValue:
|
||||
selectedDropDownValue ?? this.selectedDropDownValue,
|
||||
chatSelectModelObj: chatSelectModelObj ?? this.chatSelectModelObj,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'bloc/chat_select_bloc.dart';
|
||||
import 'models/chat_select_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChatSelectScreen extends StatelessWidget {
|
||||
const ChatSelectScreen({Key? key}) : super(key: key);
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<ChatSelectBloc>(
|
||||
create: (context) => ChatSelectBloc(
|
||||
ChatSelectState(chatSelectModelObj: ChatSelectModel()))
|
||||
..add(ChatSelectInitialEvent()),
|
||||
child: ChatSelectScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
/// This class defines the variables used in the [chat_select_screen],
|
||||
/// and is typically used to hold data that is passed between different parts of the application.
|
||||
class ChatSelectModel extends Equatable {
|
||||
ChatSelectModel();
|
||||
|
||||
ChatSelectModel copyWith() {
|
||||
return ChatSelectModel();
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import 'package:image_picker/image_picker.dart';
|
||||
import 'package:eatvio_app/presentation/diary/diary_edit_screen/models/diary_edit_model.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
part 'diary_edit_event.dart';
|
||||
@@ -44,142 +45,91 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
Emitter<DiaryEditState> emit,
|
||||
) async {
|
||||
try {
|
||||
final token =
|
||||
"9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a";
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/index'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
if (data is Map<String, dynamic> && data.containsKey('id')) {
|
||||
final int diaryId = data['id'];
|
||||
try {
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/$diaryId/show/'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
final diary = jsonDecode(response.body)['diary'];
|
||||
print("Screen load success");
|
||||
if (diary is Map<String, dynamic>) {
|
||||
final String diaryDate =
|
||||
diary['date'] ?? DateTime.now().toString();
|
||||
final responseChart = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! +
|
||||
'/diary/$diaryId/dailyNutritionData/'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
if (responseChart.statusCode == 200) {
|
||||
final recommendedChartValues = jsonDecode(
|
||||
responseChart.body)['dailyNutritionRecommendation'];
|
||||
final consumedChartValues =
|
||||
jsonDecode(responseChart.body)['dailyNutritionIntake'];
|
||||
|
||||
if (state is DiaryEditLoadedState) {
|
||||
// Если текущее состояние уже загружено, обновляем его
|
||||
var currentState = state as DiaryEditLoadedState;
|
||||
emit((currentState).copyWith(
|
||||
currentMeal: currentState.currentMeal,
|
||||
wakeupExpanded: currentState.wakeupExpanded,
|
||||
moodExpanded: currentState.moodExpanded,
|
||||
moderationExpanded: currentState.moderationExpanded,
|
||||
token: currentState.token,
|
||||
meals: currentState.meals,
|
||||
portions: currentState.portions,
|
||||
photos: currentState.photos,
|
||||
wakeupController: currentState.wakeupController,
|
||||
retireController: currentState.retireController,
|
||||
commentController: currentState.commentController,
|
||||
mealTimeController: currentState.mealTimeController,
|
||||
productNameController: currentState.productNameController,
|
||||
caloriesController: currentState.caloriesController,
|
||||
proteinsController: currentState.proteinsController,
|
||||
fatsController: currentState.fatsController,
|
||||
carbsController: currentState.carbsController,
|
||||
selectedSatiety: currentState.selectedSatiety,
|
||||
selectedMood: currentState.selectedMood,
|
||||
diaryDate: currentState.diaryDate,
|
||||
diaryId: currentState.diaryId,
|
||||
productQuantityController:
|
||||
currentState.productQuantityController,
|
||||
recommendedChartValues:
|
||||
currentState.recommendedChartValues,
|
||||
consumedChartValues: currentState.consumedChartValues,
|
||||
autocompleteList: currentState.autocompleteList,
|
||||
diaryEditModelObj: currentState.diaryEditModelObj));
|
||||
} else {
|
||||
// Если текущее состояние - начальное, создаем новое загруженное состояние
|
||||
emit(DiaryEditLoadedState(
|
||||
currentMeal: SelectionPopupModel(
|
||||
id: 1, title: "Прием пищи 1", isSelected: true),
|
||||
portionController: SelectionPopupModel(
|
||||
id: 0, title: "порций", isSelected: true),
|
||||
wakeupExpanded: true,
|
||||
moodExpanded: true,
|
||||
moderationExpanded: false,
|
||||
token: token,
|
||||
recommendedChartValues: recommendedChartValues.values
|
||||
.map<int>((value) => value as int)
|
||||
.toList(),
|
||||
consumedChartValues: consumedChartValues.values
|
||||
.map<int>((value) => value as int)
|
||||
.toList() ??
|
||||
[0, 0, 0, 0],
|
||||
meals: diary['meals'],
|
||||
portions: diary['meals'][0]['portions'],
|
||||
photos: diary['meals'][0]['photos'],
|
||||
wakeupController: toTime(diary['wakeup'] ?? "09:00"),
|
||||
retireController: toTime(diary['retire'] ?? "23:00"),
|
||||
mealTimeController:
|
||||
toTime(diary['meals'][0]['time'] ?? "10:00"),
|
||||
selectedSatiety: diary['meals'][0]['satiety'],
|
||||
selectedMood: diary['meals'][0]['mood'],
|
||||
commentController:
|
||||
TextEditingController(text: diary['comment']),
|
||||
productNameController: TextEditingController(),
|
||||
productQuantityController: TextEditingController(),
|
||||
caloriesController: TextEditingController(),
|
||||
proteinsController: TextEditingController(),
|
||||
fatsController: TextEditingController(),
|
||||
carbsController: TextEditingController(),
|
||||
diaryId: diaryId,
|
||||
diaryDate: diaryDate,
|
||||
autocompleteList: [],
|
||||
diaryEditModelObj: state.diaryEditModelObj?.copyWith(
|
||||
mealList: fillMealList(),
|
||||
portionList: fillPortions())));
|
||||
}
|
||||
} else {
|
||||
emit(DiaryEditErrorState(
|
||||
'Ошибка при декодировании данных КБЖУ'));
|
||||
}
|
||||
} else {
|
||||
// Ошибка при декодировании JSON
|
||||
emit(DiaryEditErrorState(
|
||||
'Ошибка при декодировании данных дневника'));
|
||||
}
|
||||
} catch (e) {
|
||||
// Ошибка при получении данных дневника
|
||||
emit(DiaryEditErrorState(
|
||||
'Ошибка при получении данных дневника: $e'));
|
||||
// final token =
|
||||
// "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a";
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
//print(await fetchDiaryId(token));
|
||||
final int diaryId = await fetchDiaryId(token, emit);
|
||||
try {
|
||||
print("Diary ID fetched");
|
||||
final diary = await fetchDiaryData(token, diaryId);
|
||||
print("Screen load success");
|
||||
if (diary is Map<String, dynamic>) {
|
||||
final String diaryDate = diary['date'] ?? DateTime.now().toString();
|
||||
final chartValues = await fetchChartValues(token, diaryId, emit);
|
||||
if (state is DiaryEditLoadedState) {
|
||||
// Если текущее состояние уже загружено, обновляем его
|
||||
var currentState = state as DiaryEditLoadedState;
|
||||
emit((currentState).copyWith(
|
||||
currentMeal: currentState.currentMeal,
|
||||
wakeupExpanded: currentState.wakeupExpanded,
|
||||
moodExpanded: currentState.moodExpanded,
|
||||
moderationExpanded: currentState.moderationExpanded,
|
||||
token: currentState.token,
|
||||
meals: currentState.meals,
|
||||
portions: currentState.portions,
|
||||
photos: currentState.photos,
|
||||
wakeupController: currentState.wakeupController,
|
||||
retireController: currentState.retireController,
|
||||
commentController: currentState.commentController,
|
||||
mealTimeController: currentState.mealTimeController,
|
||||
productNameController: currentState.productNameController,
|
||||
caloriesController: currentState.caloriesController,
|
||||
proteinsController: currentState.proteinsController,
|
||||
fatsController: currentState.fatsController,
|
||||
carbsController: currentState.carbsController,
|
||||
selectedSatiety: currentState.selectedSatiety,
|
||||
selectedMood: currentState.selectedMood,
|
||||
diaryDate: currentState.diaryDate,
|
||||
diaryId: currentState.diaryId,
|
||||
productQuantityController:
|
||||
currentState.productQuantityController,
|
||||
recommendedChartValues: currentState.recommendedChartValues,
|
||||
consumedChartValues: currentState.consumedChartValues,
|
||||
autocompleteList: currentState.autocompleteList,
|
||||
diaryEditModelObj: currentState.diaryEditModelObj));
|
||||
} else {
|
||||
// Если текущее состояние - начальное, создаем новое загруженное состояние
|
||||
final List<SelectionPopupModel> meals =
|
||||
fillMealList(diary['meals']);
|
||||
emit(DiaryEditLoadedState(
|
||||
currentMeal: meals[0],
|
||||
portionController: SelectionPopupModel(
|
||||
id: 0, title: "порций", isSelected: true),
|
||||
wakeupExpanded: true,
|
||||
moodExpanded: true,
|
||||
moderationExpanded: false,
|
||||
token: token,
|
||||
recommendedChartValues: chartValues[0],
|
||||
consumedChartValues: chartValues[1],
|
||||
meals: diary['meals'],
|
||||
portions: diary['meals'][0]['portions'],
|
||||
photos: diary['meals'][0]['photos'],
|
||||
wakeupController: toTime(diary['wakeup'] ?? "09:00"),
|
||||
retireController: toTime(diary['retire'] ?? "23:00"),
|
||||
mealTimeController:
|
||||
toTime(diary['meals'][0]['time'] ?? "10:00"),
|
||||
selectedSatiety: diary['meals'][0]['satiety'],
|
||||
selectedMood: diary['meals'][0]['mood'],
|
||||
commentController:
|
||||
TextEditingController(text: diary['comment']),
|
||||
productNameController: TextEditingController(),
|
||||
productQuantityController: TextEditingController(),
|
||||
caloriesController: TextEditingController(),
|
||||
proteinsController: TextEditingController(),
|
||||
fatsController: TextEditingController(),
|
||||
carbsController: TextEditingController(),
|
||||
diaryId: diaryId,
|
||||
diaryDate: diaryDate,
|
||||
autocompleteList: [],
|
||||
diaryEditModelObj: state.diaryEditModelObj
|
||||
?.copyWith(mealList: meals, portionList: fillPortions())));
|
||||
}
|
||||
} else {
|
||||
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку
|
||||
emit(
|
||||
DiaryEditErrorState('Некоторые необходимые данные отсутствуют.'));
|
||||
}
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
emit(DiaryEditErrorState('Ошибка сервера: ${response.statusCode}'));
|
||||
} catch (e) {
|
||||
// Ошибка при получении данных дневника
|
||||
emit(DiaryEditErrorState('Ошибка при получении данных дневника: $e'));
|
||||
}
|
||||
} catch (e) {
|
||||
// Ошибка при получении данных дневника
|
||||
@@ -187,12 +137,91 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
}
|
||||
}
|
||||
|
||||
reloadScreen(DiaryEditEvent event, Emitter<DiaryEditState> emit) async {
|
||||
fetchDiaryId(String token, Emitter<DiaryEditState> emit) async {
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/index'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
if (data is Map<String, dynamic> && data.containsKey('id')) {
|
||||
final int diaryId = data['id'];
|
||||
return diaryId;
|
||||
} else {
|
||||
emit(DiaryEditErrorState('Некоторые необходимые данные отсутствуют.'));
|
||||
print('fail');
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
emit(DiaryEditErrorState('Ошибка сервера: ${response.statusCode}'));
|
||||
print('fail');
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fetchDiaryData(String token, int diaryId) async {
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/$diaryId/show/'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
final diary = jsonDecode(response.body)['diary'];
|
||||
|
||||
return diary;
|
||||
}
|
||||
|
||||
fetchChartValues(
|
||||
String token, int diaryID, Emitter<DiaryEditState> emit) async {
|
||||
final responseChart = await http.get(
|
||||
Uri.parse(
|
||||
dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/dailyNutritionData/'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
if (responseChart.statusCode == 200) {
|
||||
final recommendedChartValues =
|
||||
jsonDecode(responseChart.body)['dailyNutritionRecommendation']
|
||||
.values
|
||||
.map<int>((value) => value as int)
|
||||
.toList();
|
||||
final consumedChartValues =
|
||||
jsonDecode(responseChart.body)['dailyNutritionIntake']
|
||||
.values
|
||||
.map<int>((value) => value as int)
|
||||
.toList();
|
||||
return [recommendedChartValues, consumedChartValues];
|
||||
} else {
|
||||
emit(DiaryEditErrorState('Ошибка при декодировании данных КБЖУ'));
|
||||
print('fail');
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
refreshScreen(
|
||||
int mealID,
|
||||
DiaryEditEvent event,
|
||||
Emitter<DiaryEditState> emit,
|
||||
) async {
|
||||
await reloadScreen(event, emit);
|
||||
}
|
||||
|
||||
reloadScreen(
|
||||
DiaryEditEvent event,
|
||||
Emitter<DiaryEditState> emit,
|
||||
) async {
|
||||
print("Reloading...");
|
||||
try {
|
||||
final token =
|
||||
"9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a";
|
||||
|
||||
//final token =
|
||||
// "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a"; final box = await Hive.openBox('token');
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/index'),
|
||||
headers: {
|
||||
@@ -231,45 +260,46 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
responseChart.body)['dailyNutritionRecommendation'];
|
||||
final consumedChartValues =
|
||||
jsonDecode(responseChart.body)['dailyNutritionIntake'];
|
||||
final List<SelectionPopupModel> meals =
|
||||
fillMealList(diary['meals']);
|
||||
try {
|
||||
await Future(() => emit(DiaryEditLoadedState(
|
||||
currentMeal: SelectionPopupModel(
|
||||
id: 1, title: "Прием пищи 1", isSelected: true),
|
||||
portionController: SelectionPopupModel(
|
||||
id: 0, title: "порций", isSelected: true),
|
||||
wakeupExpanded: true,
|
||||
moodExpanded: true,
|
||||
moderationExpanded: false,
|
||||
token: token,
|
||||
recommendedChartValues: recommendedChartValues.values
|
||||
.map<int>((value) => value as int)
|
||||
.toList(),
|
||||
consumedChartValues: consumedChartValues.values
|
||||
.map<int>((value) => value as int)
|
||||
.toList(),
|
||||
meals: diary['meals'],
|
||||
portions: diary['meals'][0]['portions'],
|
||||
photos: diary['meals'][0]['photos'],
|
||||
wakeupController: toTime(diary['wakeup'] ?? "09:00"),
|
||||
retireController: toTime(diary['retire'] ?? "23:00"),
|
||||
mealTimeController:
|
||||
toTime(diary['meals'][0]['time'] ?? "10:00"),
|
||||
selectedSatiety: diary['meals'][0]['satiety'],
|
||||
selectedMood: diary['meals'][0]['mood'],
|
||||
commentController:
|
||||
TextEditingController(text: diary['comment']),
|
||||
productNameController: TextEditingController(),
|
||||
productQuantityController: TextEditingController(),
|
||||
caloriesController: TextEditingController(),
|
||||
proteinsController: TextEditingController(),
|
||||
fatsController: TextEditingController(),
|
||||
carbsController: TextEditingController(),
|
||||
diaryId: diaryId,
|
||||
diaryDate: diaryDate,
|
||||
autocompleteList: [],
|
||||
diaryEditModelObj: state.diaryEditModelObj?.copyWith(
|
||||
mealList: fillMealList(),
|
||||
portionList: fillPortions()))));
|
||||
diaryEditModelObj: state.diaryEditModelObj?.copyWith(
|
||||
mealList: meals, portionList: fillPortions()),
|
||||
currentMeal: meals[0],
|
||||
portionController: SelectionPopupModel(
|
||||
id: 0, title: "порций", isSelected: true),
|
||||
wakeupExpanded: true,
|
||||
moodExpanded: true,
|
||||
moderationExpanded: false,
|
||||
token: token,
|
||||
recommendedChartValues: recommendedChartValues.values
|
||||
.map<int>((value) => value as int)
|
||||
.toList(),
|
||||
consumedChartValues: consumedChartValues.values
|
||||
.map<int>((value) => value as int)
|
||||
.toList(),
|
||||
meals: diary['meals'],
|
||||
portions: diary['meals'][0]['portions'],
|
||||
photos: diary['meals'][0]['photos'],
|
||||
wakeupController: toTime(diary['wakeup'] ?? "09:00"),
|
||||
retireController: toTime(diary['retire'] ?? "23:00"),
|
||||
mealTimeController:
|
||||
toTime(diary['meals'][0]['time'] ?? "10:00"),
|
||||
selectedSatiety: diary['meals'][0]['satiety'],
|
||||
selectedMood: diary['meals'][0]['mood'],
|
||||
commentController:
|
||||
TextEditingController(text: diary['comment']),
|
||||
productNameController: TextEditingController(),
|
||||
productQuantityController: TextEditingController(),
|
||||
caloriesController: TextEditingController(),
|
||||
proteinsController: TextEditingController(),
|
||||
fatsController: TextEditingController(),
|
||||
carbsController: TextEditingController(),
|
||||
diaryId: diaryId,
|
||||
diaryDate: diaryDate,
|
||||
autocompleteList: [],
|
||||
)));
|
||||
|
||||
print("Updated");
|
||||
} catch (e) {
|
||||
@@ -351,6 +381,8 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
currentState.diaryId);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print(
|
||||
'Mood change success! meal_id: ${currentState.currentMeal?.id}, mood: ${event.selectedElement}');
|
||||
updatedState.selectedMood = event.selectedElement;
|
||||
emit(updatedState); // Передаем обновленное состояние в emit
|
||||
}
|
||||
@@ -387,6 +419,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
var response = await sendWakeupData(
|
||||
currentState.token, event.selectedTime, currentState.diaryId);
|
||||
if (response.statusCode == 200) {
|
||||
await reloadScreen(event, emit);
|
||||
var updatedState =
|
||||
currentState.copyWith(wakeupController: event.selectedTime);
|
||||
print("Wakeup time changed to ${event.selectedTime}");
|
||||
@@ -403,6 +436,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
var response = await sendRetireData(
|
||||
currentState.token, event.selectedTime, currentState.diaryId);
|
||||
if (response.statusCode == 200) {
|
||||
await reloadScreen(event, emit);
|
||||
var updatedState =
|
||||
currentState.copyWith(retireController: event.selectedTime);
|
||||
print("Retire time changed to ${event.selectedTime}");
|
||||
@@ -496,11 +530,10 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
if (state is DiaryEditLoadedState) {
|
||||
var currentState = state as DiaryEditLoadedState;
|
||||
final meal = currentState.meals?.firstWhere(
|
||||
(meal) => meal['type'] == event.value.id,
|
||||
(meal) => meal['id'] == event.value.id,
|
||||
orElse: () => null);
|
||||
|
||||
print(meal);
|
||||
int? id = event.value.id;
|
||||
print(meal['photos']);
|
||||
DiaryEditLoadedState updatedState = currentState.copyWith(
|
||||
currentMeal: event.value,
|
||||
portions: meal['portions'],
|
||||
@@ -508,6 +541,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
mealTimeController: toTime(meal['time'] ?? "1$id:00"),
|
||||
selectedMood: meal['mood'],
|
||||
selectedSatiety: meal['satiety']);
|
||||
print(updatedState.photos);
|
||||
emit(updatedState);
|
||||
}
|
||||
}
|
||||
@@ -727,7 +761,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print("finished");
|
||||
await reloadScreen(event, emit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -901,15 +935,16 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
||||
return timeOfDay;
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillMealList() {
|
||||
return [
|
||||
SelectionPopupModel(id: 1, title: "Прием пищи 1", isSelected: true),
|
||||
SelectionPopupModel(id: 2, title: "Прием пищи 2"),
|
||||
SelectionPopupModel(id: 3, title: "Прием пищи 3"),
|
||||
SelectionPopupModel(id: 4, title: "Прием пищи 4"),
|
||||
SelectionPopupModel(id: 5, title: "Прием пищи 5"),
|
||||
SelectionPopupModel(id: 6, title: "Прием пищи 6"),
|
||||
];
|
||||
List<SelectionPopupModel> fillMealList(List<dynamic> meals) {
|
||||
meals.sort(compareTypes);
|
||||
return meals.map((meal) {
|
||||
String title = "Прием пищи ${meal['type']}";
|
||||
return SelectionPopupModel(id: meal['id'], title: title);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
int compareTypes(a, b) {
|
||||
return a['type'].compareTo(b['type']);
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillPortions() {
|
||||
|
||||
@@ -139,6 +139,7 @@ class DiaryEditLoadedState extends DiaryEditState {
|
||||
diaryDate: diaryDate ?? this.diaryDate,
|
||||
token: token ?? this.token,
|
||||
meals: meals ?? this.meals,
|
||||
photos: photos ?? this.photos,
|
||||
autocompleteList: autocompleteList ?? this.autocompleteList,
|
||||
portions: portions ?? this.portions,
|
||||
recommendedChartValues:
|
||||
|
||||
@@ -13,6 +13,8 @@ import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
|
||||
import 'package:eatvio_app/widgets/custom_edit_drop_down.dart';
|
||||
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
|
||||
import 'package:eatvio_app/widgets/custom_scale_element.dart';
|
||||
//import 'package:eatvio_app/widgets/custom_bottom_bar.dart';
|
||||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class DiaryEditScreen extends StatelessWidget {
|
||||
@@ -229,7 +231,6 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
state.autocompleteList!.map((dynamic item) => item as String).toList();
|
||||
//print(_options);
|
||||
FocusNode focusNodeName = FocusNode();
|
||||
FocusNode focusNodeQuantity = FocusNode();
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 16.h),
|
||||
padding: EdgeInsets.symmetric(
|
||||
@@ -318,10 +319,7 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
hintText: "Введите название продукта",
|
||||
controller: productEditingController,
|
||||
focusNode: focusNodeName,
|
||||
onChanged: getAutocomplete(context, focusNodeQuantity),
|
||||
/*onFieldSubmitted: (String value) {
|
||||
onFieldSubmitted();
|
||||
},*/
|
||||
onChanged: getAutocomplete(context, focusNodeName),
|
||||
);
|
||||
},
|
||||
optionsViewBuilder: (
|
||||
@@ -341,7 +339,7 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final String option = options.elementAt(index);
|
||||
return GestureDetector(
|
||||
onTap: selectProduct(onSelected, option),
|
||||
onTap: selectProduct(onSelected, option, state),
|
||||
child: ListTile(
|
||||
title: Text(option),
|
||||
),
|
||||
@@ -374,7 +372,7 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
width: 150.h,
|
||||
hintText: "Кол-во",
|
||||
textInputAction: TextInputAction.done,
|
||||
focusNode: focusNodeQuantity,
|
||||
// focusNode: focusNodeQuantity,
|
||||
controller: state.productQuantityController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[digitsOnly],
|
||||
@@ -404,11 +402,14 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
.map((portion) => _buildProduct(context, portion))
|
||||
.toList(),
|
||||
SizedBox(height: 30.v),
|
||||
...state.photos != null
|
||||
? state.photos!
|
||||
.map((photo) => _buildPhoto(context, photo))
|
||||
.toList()
|
||||
: [],
|
||||
/*...state.photos != null
|
||||
? state.photos!.isEmpty
|
||||
? [Text('Фото пока нет')]
|
||||
: state.photos!
|
||||
.map((photo) => _buildPhoto(context, photo))
|
||||
.toList()
|
||||
: [Text('Фото нет')],*/
|
||||
_buildCarousel(context, state),
|
||||
SizedBox(height: 20.v),
|
||||
_buildAddPhoto(context),
|
||||
SizedBox(height: 30.v),
|
||||
@@ -561,7 +562,9 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
};
|
||||
}
|
||||
|
||||
selectProduct(AutocompleteOnSelected<String> onSelected, String option) {
|
||||
selectProduct(AutocompleteOnSelected<String> onSelected, String option,
|
||||
DiaryEditLoadedState state) {
|
||||
state.productNameController?.text = option;
|
||||
return () {
|
||||
onSelected(option);
|
||||
};
|
||||
@@ -600,6 +603,20 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
};
|
||||
}
|
||||
|
||||
_buildCarousel(BuildContext context, DiaryEditLoadedState state) {
|
||||
if (state.photos!.isEmpty) {
|
||||
return Text("Фото нет");
|
||||
} else {
|
||||
return CarouselSlider(
|
||||
options: CarouselOptions(height: 340.0),
|
||||
items: state.photos!.map<Widget>((photo) {
|
||||
return _buildPhoto(
|
||||
context, photo); // Assuming photos are stored as strings
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_buildProduct(BuildContext context, Map<String, dynamic> portion) {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 10.h),
|
||||
@@ -764,25 +781,37 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
BarChartGroupData(x: 0, barRods: [
|
||||
BarChartRodData(
|
||||
toY: consumedValues[0] / recommendedValues[0] * 100,
|
||||
color: Colors.blue,
|
||||
color: checkConsumedValues(
|
||||
[recommendedValues[0]], [consumedValues[1]])
|
||||
? Colors.red
|
||||
: Colors.blue,
|
||||
)
|
||||
]),
|
||||
BarChartGroupData(x: 1, barRods: [
|
||||
BarChartRodData(
|
||||
toY: consumedValues[1] / recommendedValues[1] * 100,
|
||||
color: Colors.red,
|
||||
color: checkConsumedValues(
|
||||
[recommendedValues[1]], [consumedValues[1]])
|
||||
? Colors.red
|
||||
: Colors.blue,
|
||||
)
|
||||
]),
|
||||
BarChartGroupData(x: 2, barRods: [
|
||||
BarChartRodData(
|
||||
toY: consumedValues[2] / recommendedValues[2] * 100,
|
||||
color: Colors.green,
|
||||
color: checkConsumedValues(
|
||||
[recommendedValues[2]], [consumedValues[2]])
|
||||
? Colors.red
|
||||
: Colors.blue,
|
||||
)
|
||||
]),
|
||||
BarChartGroupData(x: 3, barRods: [
|
||||
BarChartRodData(
|
||||
toY: consumedValues[3] / recommendedValues[3] * 100,
|
||||
color: Colors.orange,
|
||||
color: checkConsumedValues(
|
||||
[recommendedValues[3]], [consumedValues[3]])
|
||||
? Colors.red
|
||||
: Colors.blue,
|
||||
)
|
||||
]),
|
||||
],
|
||||
@@ -889,7 +918,7 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
SizedBox(height: 19.v),
|
||||
if (checkConsumedValues(recommendedValues, consumedValues))
|
||||
Text(
|
||||
"*Превышенная суточная норма углеводов",
|
||||
"*Превышенная суточная норма",
|
||||
style: theme.textTheme.labelLarge,
|
||||
)
|
||||
],
|
||||
@@ -1042,7 +1071,6 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
|
||||
Function() onFinishDayPressed(BuildContext context) {
|
||||
return () {
|
||||
print("sad");
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext dialogContext) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/profile/my_profile_screen/models/my_profile_model.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
//import 'package:hive/hive.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
part 'my_profile_event.dart';
|
||||
@@ -21,28 +22,29 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
|
||||
Emitter<MyProfileState> emit,
|
||||
) async {
|
||||
try {
|
||||
/*final box = await Hive.openBox('token');
|
||||
final token = box.get('token');*/
|
||||
final token =
|
||||
"9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a";
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
); // Если токен есть, запускаем приложение
|
||||
}
|
||||
//final token =
|
||||
// "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a";
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/profile/index'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
// Проверка наличия ключевых полей в JSON
|
||||
if (data is Map<String, dynamic> &&
|
||||
data.containsKey('user') &&
|
||||
data.containsKey('userDetails') &&
|
||||
data.containsKey('chartPoints') &&
|
||||
data.containsKey('circumferences')) {
|
||||
// Все ключевые поля присутствуют, продолжаем обработку
|
||||
if (state is MyProfileLoadedState) {
|
||||
// Если текущее состояние уже загружено, обновляем его
|
||||
var currentState = state as MyProfileLoadedState;
|
||||
var plans = []
|
||||
..addAll(data["finishedPlans"])
|
||||
@@ -51,9 +53,6 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
|
||||
..addAll(data["paidPlan"])
|
||||
..addAll(data["requestedPlan"])
|
||||
..addAll(data["initedPlan"]);
|
||||
|
||||
// Обновляем значения контроллеров только если они уже были созданы
|
||||
|
||||
emit((currentState).copyWith(
|
||||
chartPoints: currentState.chartPoints,
|
||||
chartDates: currentState.chartDates,
|
||||
@@ -123,18 +122,6 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
|
||||
})
|
||||
: data["chartPoints"];
|
||||
|
||||
/*List<double> weights = [0.0, 0.0, 0.0, 0.0];
|
||||
List<String> dates = [
|
||||
"0000-00-00 00:00:00",
|
||||
"0000-00-00 00:00:00",
|
||||
"0000-00-00 00:00:00",
|
||||
"0000-00-00 00:00:00"
|
||||
];
|
||||
for (int i = 0; i < data["chartPoints"].length; i++) {
|
||||
weights[i] = data["chartPoints"][i]["weight"].toDouble();
|
||||
dates[i] = data["chartPoints"][i]["created_at"].toString();
|
||||
}
|
||||
print(data);*/
|
||||
List<String> dates = [
|
||||
"0000-00-00 00:00:00",
|
||||
"0000-00-00 00:00:00",
|
||||
@@ -169,14 +156,7 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
|
||||
};
|
||||
}
|
||||
}
|
||||
print(data['userDetails']);
|
||||
/*print(chartPoints);
|
||||
print(circumferences);*/
|
||||
/*print(weights);
|
||||
print(weights.runtimeType);
|
||||
print(circumferences);
|
||||
print(circumferences.runtimeType);*/
|
||||
// Если текущее состояние - начальное, создаем новое загруженное состояние
|
||||
|
||||
emit(MyProfileLoadedState(
|
||||
chartPoints: chartPoints,
|
||||
chartDates: dates,
|
||||
@@ -231,7 +211,7 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
|
||||
selectedCity: data['userDetails']['city'],
|
||||
selectedCountry: data['userDetails']['country'],
|
||||
selectedActivity: determineActivityLevel(
|
||||
double.parse(data['userDetails']['activity_coefficient'])),
|
||||
data['userDetails']['activity_coefficient']),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -182,7 +182,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
switch (chartType) {
|
||||
case 1: // График веса
|
||||
return GestureDetector(
|
||||
onTap: _editWeight(context, state),
|
||||
onTap: () => _editWeight(context, state),
|
||||
child: Column(children: [
|
||||
Text(
|
||||
"weight_chart".tr,
|
||||
@@ -225,7 +225,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
]);
|
||||
case 3: //График обхватов
|
||||
return GestureDetector(
|
||||
onTap: _editCircumference(context, state),
|
||||
onTap: () => _editCircumference(context, state),
|
||||
child: Column(children: [
|
||||
Text(
|
||||
"circumferences_chart".tr,
|
||||
@@ -279,10 +279,8 @@ class MyProfileScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
/// Section Widget
|
||||
_buildChart(
|
||||
BuildContext context, List<double> chartPoints, List<String>? dates) {
|
||||
// Определение осей графика
|
||||
List<FlSpot> spots = [];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
spots.add(
|
||||
@@ -428,7 +426,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
};
|
||||
}
|
||||
|
||||
mapSpots() {
|
||||
List<LineTooltipItem?> Function(List<LineBarSpot>) mapSpots() {
|
||||
return (touchedSpots) {
|
||||
return touchedSpots.map((LineBarSpot touchedSpot) {
|
||||
final textStyle = TextStyle(
|
||||
@@ -635,7 +633,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
mapTouchedSpots() {
|
||||
List<LineTooltipItem?> Function(List<LineBarSpot>) mapTouchedSpots() {
|
||||
return (touchedSpots) {
|
||||
return touchedSpots.map((LineBarSpot touchedSpot) {
|
||||
final textStyle = TextStyle(
|
||||
|
||||
@@ -76,16 +76,18 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
UserRegistrationSheet sheet =
|
||||
state.additionalInformationModelObj!.userRegistrationSheet;
|
||||
sheet.additionalInfo = state.editTextController!.text;
|
||||
//print(json.encode(sheet.toJson()));
|
||||
|
||||
final response = await http.post(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/register'),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(sheet.toJson()),
|
||||
);
|
||||
print(response.statusCode);
|
||||
print(response.body);
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/register'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: jsonEncode(sheet.toJson()),
|
||||
encoding: utf8);
|
||||
|
||||
var res = await jsonDecode(response.body);
|
||||
if (response.statusCode == 200) {
|
||||
var res = await jsonDecode(response.body);
|
||||
final box = await Hive.openBox('token');
|
||||
final token = res['token'];
|
||||
box.put('token', token);
|
||||
@@ -93,6 +95,8 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
} else {
|
||||
showErrorMessage(context, res['message']);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -118,7 +122,7 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
/// Section Widget
|
||||
_buildTextFormField(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 257.v,
|
||||
height: 315.v,
|
||||
width: 343.h,
|
||||
child: Stack(alignment: Alignment.center, children: [
|
||||
Align(
|
||||
@@ -139,7 +143,10 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
builder: (context, editTextController) {
|
||||
return CustomTextFormField(
|
||||
controller: editTextController,
|
||||
textInputAction: TextInputAction.done);
|
||||
hintText:
|
||||
"У меня крепкое здоровье, но последнее время часто утомляюсь, однако, это мне не мешает радоваться жизни",
|
||||
textInputAction: TextInputAction.done,
|
||||
maxLines: 8);
|
||||
})
|
||||
]))
|
||||
]));
|
||||
@@ -152,12 +159,12 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
|
||||
/// Displays an alert dialog when the action is triggered.
|
||||
/// The dialog box contains a title and a message with the `Теперь вы можете пользоваться полным функционалом приложения`
|
||||
showSuccessMessage(BuildContext context, String text) {
|
||||
showErrorMessage(BuildContext context, String text) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => AlertDialog(
|
||||
title: const Text('Регистрация завершена!'),
|
||||
content: const Text('1'),
|
||||
title: const Text('Ошибка'),
|
||||
content: Text(text),
|
||||
actions: [
|
||||
TextButton(onPressed: onTapOk(context), child: const Text('Ok'))
|
||||
],
|
||||
|
||||
@@ -10,7 +10,6 @@ class CityOfLivingBloc extends Bloc<CityOfLivingEvent, CityOfLivingState> {
|
||||
CityOfLivingBloc(CityOfLivingState initialState) : super(initialState) {
|
||||
on<CityOfLivingInitialEvent>(_onInitialize);
|
||||
on<ChangeDropDownEvent>(_changeDropDown);
|
||||
on<ChangeDropDown1Event>(_changeDropDown1);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
@@ -19,8 +18,8 @@ class CityOfLivingBloc extends Bloc<CityOfLivingEvent, CityOfLivingState> {
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
cityOfLivingModelObj: state.cityOfLivingModelObj?.copyWith(
|
||||
dropdownItemList: fillDropdownItemList(),
|
||||
dropdownItemList1: fillDropdownItemList1())));
|
||||
dropdownItemList: fillDropdownItemList(),
|
||||
)));
|
||||
}
|
||||
|
||||
_changeDropDown(
|
||||
@@ -32,50 +31,7 @@ class CityOfLivingBloc extends Bloc<CityOfLivingEvent, CityOfLivingState> {
|
||||
event.value.title;
|
||||
}
|
||||
|
||||
_changeDropDown1(
|
||||
ChangeDropDown1Event event,
|
||||
Emitter<CityOfLivingState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedDropDownValue1: event.value));
|
||||
state.cityOfLivingModelObj?.userRegistrationSheet.city = event.value.title;
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillDropdownItemList() {
|
||||
return [SelectionPopupModel(id: 1, title: "Россия", isSelected: true)];
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillDropdownItemList1() {
|
||||
return [
|
||||
SelectionPopupModel(id: 1, title: "Москва", isSelected: true),
|
||||
SelectionPopupModel(id: 2, title: "Санкт-Петербург"),
|
||||
SelectionPopupModel(id: 3, title: "Новосибирск"),
|
||||
SelectionPopupModel(id: 4, title: "Екатеринбург"),
|
||||
SelectionPopupModel(id: 5, title: "Нижний Новгород"),
|
||||
SelectionPopupModel(id: 6, title: "Казань"),
|
||||
SelectionPopupModel(id: 7, title: "Самара"),
|
||||
SelectionPopupModel(id: 8, title: "Омск"),
|
||||
SelectionPopupModel(id: 9, title: "Челябинск"),
|
||||
SelectionPopupModel(id: 10, title: "Ростов-на-Дону"),
|
||||
SelectionPopupModel(id: 11, title: "Уфа"),
|
||||
SelectionPopupModel(id: 12, title: "Волгоград"),
|
||||
SelectionPopupModel(id: 13, title: "Пермь"),
|
||||
SelectionPopupModel(id: 14, title: "Красноярск"),
|
||||
SelectionPopupModel(id: 15, title: "Воронеж"),
|
||||
SelectionPopupModel(id: 16, title: "Саратов"),
|
||||
SelectionPopupModel(id: 17, title: "Краснодар"),
|
||||
SelectionPopupModel(id: 18, title: "Тольятти"),
|
||||
SelectionPopupModel(id: 19, title: "Барнаул"),
|
||||
SelectionPopupModel(id: 20, title: "Ижевск"),
|
||||
SelectionPopupModel(id: 21, title: "Ульяновск"),
|
||||
SelectionPopupModel(id: 22, title: "Тюмень"),
|
||||
SelectionPopupModel(id: 23, title: "Иркутск"),
|
||||
SelectionPopupModel(id: 24, title: "Хабаровск"),
|
||||
SelectionPopupModel(id: 25, title: "Ярославль"),
|
||||
SelectionPopupModel(id: 26, title: "Кемерово"),
|
||||
SelectionPopupModel(id: 27, title: "Магнитогорск"),
|
||||
SelectionPopupModel(id: 28, title: "Новокузнецк"),
|
||||
SelectionPopupModel(id: 29, title: "Томск"),
|
||||
SelectionPopupModel(id: 30, title: "Астрахань")
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,15 +26,3 @@ class ChangeDropDownEvent extends CityOfLivingEvent {
|
||||
value,
|
||||
];
|
||||
}
|
||||
|
||||
///event for dropdown selection
|
||||
class ChangeDropDown1Event extends CityOfLivingEvent {
|
||||
ChangeDropDown1Event({required this.value});
|
||||
|
||||
SelectionPopupModel value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
value,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -6,20 +6,20 @@ part of 'city_of_living_bloc.dart';
|
||||
class CityOfLivingState extends Equatable {
|
||||
CityOfLivingState({
|
||||
this.selectedDropDownValue,
|
||||
this.selectedDropDownValue1,
|
||||
this.cityController,
|
||||
this.cityOfLivingModelObj,
|
||||
});
|
||||
|
||||
SelectionPopupModel? selectedDropDownValue;
|
||||
|
||||
SelectionPopupModel? selectedDropDownValue1;
|
||||
TextEditingController? cityController;
|
||||
|
||||
CityOfLivingModel? cityOfLivingModelObj;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
selectedDropDownValue,
|
||||
selectedDropDownValue1,
|
||||
cityController,
|
||||
cityOfLivingModelObj,
|
||||
];
|
||||
CityOfLivingState copyWith({
|
||||
@@ -30,8 +30,7 @@ class CityOfLivingState extends Equatable {
|
||||
return CityOfLivingState(
|
||||
selectedDropDownValue:
|
||||
selectedDropDownValue ?? this.selectedDropDownValue,
|
||||
selectedDropDownValue1:
|
||||
selectedDropDownValue1 ?? this.selectedDropDownValue1,
|
||||
cityController: cityController ?? this.cityController,
|
||||
cityOfLivingModelObj: cityOfLivingModelObj ?? this.cityOfLivingModelObj,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,8 @@ class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
|
||||
builder: (context, enterinformationController) {
|
||||
return CustomTextFormField(
|
||||
controller: enterinformationController,
|
||||
hintText: "enter_information".tr,
|
||||
hintText:
|
||||
"Я занимаюсь плаванием , почти каждый вечер прогулки на свежем воздухе, пару раз в месяц играю в волейбол. Стараюсь не сидеть на месте!",
|
||||
textInputAction: TextInputAction.done,
|
||||
maxLines: 8);
|
||||
})
|
||||
|
||||
@@ -9,7 +9,6 @@ part 'height_state.dart';
|
||||
class HeightBloc extends Bloc<HeightEvent, HeightState> {
|
||||
HeightBloc(HeightState initialState) : super(initialState) {
|
||||
on<HeightInitialEvent>(_onInitialize);
|
||||
on<ChangeDropDownEvent>(_changeDropDown);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
@@ -17,25 +16,7 @@ class HeightBloc extends Bloc<HeightEvent, HeightState> {
|
||||
Emitter<HeightState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
heightModelObj: state.heightModelObj
|
||||
?.copyWith(dropdownItemList: fillDropdownItemList())));
|
||||
}
|
||||
|
||||
_changeDropDown(
|
||||
ChangeDropDownEvent event,
|
||||
Emitter<HeightState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedDropDownValue: event.value));
|
||||
state.heightModelObj?.userRegistrationSheet.height = event.value.title;
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillDropdownItemList() {
|
||||
List<SelectionPopupModel> selectionPopupModels = [];
|
||||
|
||||
for (int i = 140; i <= 220; i++) {
|
||||
selectionPopupModels
|
||||
.add(SelectionPopupModel(id: i - 34, title: i.toString()));
|
||||
}
|
||||
return selectionPopupModels;
|
||||
heightModelObj: state.heightModelObj?.copyWith(),
|
||||
heightController: state.heightController));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,15 +14,3 @@ class HeightInitialEvent extends HeightEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
///event for dropdown selection
|
||||
class ChangeDropDownEvent extends HeightEvent {
|
||||
ChangeDropDownEvent({required this.value});
|
||||
|
||||
SelectionPopupModel value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
value,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,26 +5,25 @@ part of 'height_bloc.dart';
|
||||
/// Represents the state of Height in the application.
|
||||
class HeightState extends Equatable {
|
||||
HeightState({
|
||||
this.selectedDropDownValue,
|
||||
this.heightController,
|
||||
this.heightModelObj,
|
||||
});
|
||||
|
||||
SelectionPopupModel? selectedDropDownValue;
|
||||
TextEditingController? heightController;
|
||||
|
||||
HeightModel? heightModelObj;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
selectedDropDownValue,
|
||||
heightController,
|
||||
heightModelObj,
|
||||
];
|
||||
HeightState copyWith({
|
||||
SelectionPopupModel? selectedDropDownValue,
|
||||
TextEditingController? heightController,
|
||||
HeightModel? heightModelObj,
|
||||
}) {
|
||||
return HeightState(
|
||||
selectedDropDownValue:
|
||||
selectedDropDownValue ?? this.selectedDropDownValue,
|
||||
heightController: heightController ?? this.heightController,
|
||||
heightModelObj: heightModelObj ?? this.heightModelObj,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
|
||||
import 'package:eatvio_app/widgets/custom_drop_down.dart';
|
||||
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:eatvio_app/widgets/next_step_button.dart';
|
||||
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HeightScreen extends StatefulWidget {
|
||||
class HeightScreen extends StatelessWidget {
|
||||
const HeightScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
@@ -22,82 +23,91 @@ class HeightScreen extends StatefulWidget {
|
||||
child: HeightScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<HeightScreen> createState() => _HeightScreenState();
|
||||
}
|
||||
|
||||
class _HeightScreenState extends State<HeightScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(children: [
|
||||
SizedBox(height: 7.v),
|
||||
Container(
|
||||
height: 16.v,
|
||||
width: 343.h,
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.onPrimary,
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary, width: 1.h)),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.55,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Column(children: [
|
||||
Text("height_measurements".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 174.v),
|
||||
Column(children: [
|
||||
Text("your_height".tr, style: theme.textTheme.bodyLarge),
|
||||
child: Scaffold(
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 7.v),
|
||||
Container(
|
||||
height: 16.v,
|
||||
width: 343.h,
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.onPrimary,
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
width: 1.h,
|
||||
),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.55,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 39.v),
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
"height_measurements".tr,
|
||||
style: theme.textTheme.headlineSmall,
|
||||
),
|
||||
SizedBox(height: 174.v),
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
"your_height".tr,
|
||||
style: theme.textTheme.bodyLarge,
|
||||
),
|
||||
SizedBox(height: 4.v),
|
||||
BlocSelector<HeightBloc, HeightState, HeightModel?>(
|
||||
selector: (state) => state.heightModelObj,
|
||||
builder: (context, heightModelObj) {
|
||||
return CustomDropDown(
|
||||
icon: Container(
|
||||
margin: EdgeInsets.fromLTRB(
|
||||
30.h, 11.v, 17.h, 11.v),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(1.h)),
|
||||
child: CustomImageView(
|
||||
imagePath: ImageConstant.imgFavorite,
|
||||
height: 12.adaptSize,
|
||||
width: 12.adaptSize)),
|
||||
hintText: "170",
|
||||
items: heightModelObj?.dropdownItemList ?? [],
|
||||
onChanged: newMethod(context));
|
||||
})
|
||||
])
|
||||
]),
|
||||
Spacer(),
|
||||
BlocBuilder<HeightBloc, HeightState>(
|
||||
builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapNext(state, context));
|
||||
}),
|
||||
]))));
|
||||
}
|
||||
|
||||
newMethod(BuildContext context) {
|
||||
return (value) {
|
||||
context.read<HeightBloc>().add(ChangeDropDownEvent(value: value));
|
||||
};
|
||||
BlocBuilder<HeightBloc, HeightState>(
|
||||
builder: (context, state) {
|
||||
return CustomTextFormField(
|
||||
width: 150.h,
|
||||
textInputAction: TextInputAction.done,
|
||||
controller: state.heightController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
);
|
||||
})
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
BlocBuilder<HeightBloc, HeightState>(
|
||||
builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
right: 16.h,
|
||||
bottom: 50.v,
|
||||
),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapNext(state, context),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
onTapNext(HeightState state, BuildContext context) {
|
||||
|
||||
@@ -17,7 +17,7 @@ class SplashBloc extends Bloc<SplashEvent, SplashState> {
|
||||
) async {
|
||||
Future.delayed(const Duration(milliseconds: 3000), () {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ part 'weight_state.dart';
|
||||
class WeightBloc extends Bloc<WeightEvent, WeightState> {
|
||||
WeightBloc(WeightState initialState) : super(initialState) {
|
||||
on<WeightInitialEvent>(_onInitialize);
|
||||
on<ChangeDropDownEvent>(_changeDropDown);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
@@ -17,25 +16,7 @@ class WeightBloc extends Bloc<WeightEvent, WeightState> {
|
||||
Emitter<WeightState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
weightModelObj: state.weightModelObj
|
||||
?.copyWith(dropdownItemList: fillDropdownItemList())));
|
||||
}
|
||||
|
||||
_changeDropDown(
|
||||
ChangeDropDownEvent event,
|
||||
Emitter<WeightState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedDropDownValue: event.value));
|
||||
state.weightModelObj?.userRegistrationSheet.weight = event.value.title;
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillDropdownItemList() {
|
||||
List<SelectionPopupModel> selectionPopupModels = [];
|
||||
|
||||
for (int i = 35; i <= 200; i++) {
|
||||
selectionPopupModels
|
||||
.add(SelectionPopupModel(id: i - 34, title: i.toString()));
|
||||
}
|
||||
return selectionPopupModels;
|
||||
weightModelObj: state.weightModelObj?.copyWith(),
|
||||
weightController: state.weightController));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,15 +14,3 @@ class WeightInitialEvent extends WeightEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
///event for dropdown selection
|
||||
class ChangeDropDownEvent extends WeightEvent {
|
||||
ChangeDropDownEvent({required this.value});
|
||||
|
||||
SelectionPopupModel value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
value,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,26 +5,25 @@ part of 'weight_bloc.dart';
|
||||
/// Represents the state of Weight in the application.
|
||||
class WeightState extends Equatable {
|
||||
WeightState({
|
||||
this.selectedDropDownValue,
|
||||
this.weightController,
|
||||
this.weightModelObj,
|
||||
});
|
||||
|
||||
SelectionPopupModel? selectedDropDownValue;
|
||||
TextEditingController? weightController;
|
||||
|
||||
WeightModel? weightModelObj;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
selectedDropDownValue,
|
||||
weightController,
|
||||
weightModelObj,
|
||||
];
|
||||
WeightState copyWith({
|
||||
SelectionPopupModel? selectedDropDownValue,
|
||||
TextEditingController? weightController,
|
||||
WeightModel? weightModelObj,
|
||||
}) {
|
||||
return WeightState(
|
||||
selectedDropDownValue:
|
||||
selectedDropDownValue ?? this.selectedDropDownValue,
|
||||
weightController: weightController ?? this.weightController,
|
||||
weightModelObj: weightModelObj ?? this.weightModelObj,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
|
||||
import 'package:eatvio_app/widgets/custom_drop_down.dart';
|
||||
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:eatvio_app/widgets/next_step_button.dart';
|
||||
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WeightScreen extends StatefulWidget {
|
||||
class WeightScreen extends StatelessWidget {
|
||||
const WeightScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
@@ -22,96 +23,94 @@ class WeightScreen extends StatefulWidget {
|
||||
child: WeightScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<WeightScreen> createState() => _WeightScreenState();
|
||||
}
|
||||
|
||||
class _WeightScreenState extends State<WeightScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(children: [
|
||||
SizedBox(height: 7.v),
|
||||
Container(
|
||||
height: 16.v,
|
||||
width: 343.h,
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.onPrimary,
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary, width: 1.h)),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.48,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Column(children: [
|
||||
Text("weight_measurements".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 174.v),
|
||||
Column(children: [
|
||||
Text("your_weight".tr, style: theme.textTheme.bodyLarge),
|
||||
child: Scaffold(
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 7.v),
|
||||
Container(
|
||||
height: 16.v,
|
||||
width: 343.h,
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.onPrimary,
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
width: 1.h,
|
||||
),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.55,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 39.v),
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
"weight_measurements".tr,
|
||||
style: theme.textTheme.headlineSmall,
|
||||
),
|
||||
SizedBox(height: 174.v),
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
"your_weight".tr,
|
||||
style: theme.textTheme.bodyLarge,
|
||||
),
|
||||
SizedBox(height: 4.v),
|
||||
BlocSelector<WeightBloc, WeightState, WeightModel?>(
|
||||
selector: (state) => state.weightModelObj,
|
||||
builder: (context, weightModelObj) {
|
||||
return CustomDropDown(
|
||||
icon: Container(
|
||||
margin: EdgeInsets.fromLTRB(
|
||||
30.h, 11.v, 17.h, 11.v),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(1.h)),
|
||||
child: CustomImageView(
|
||||
imagePath: ImageConstant.imgFavorite,
|
||||
height: 12.adaptSize,
|
||||
width: 12.adaptSize)),
|
||||
hintText: "Не выбрано",
|
||||
items: weightModelObj?.dropdownItemList ?? [],
|
||||
onChanged: _onDropDownChanged);
|
||||
})
|
||||
])
|
||||
]),
|
||||
Spacer(),
|
||||
BlocBuilder<WeightBloc, WeightState>(
|
||||
builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapNext(context, state));
|
||||
}),
|
||||
]))));
|
||||
BlocBuilder<WeightBloc, WeightState>(
|
||||
builder: (context, state) {
|
||||
return CustomTextFormField(
|
||||
width: 150.h,
|
||||
textInputAction: TextInputAction.done,
|
||||
controller: state.weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
);
|
||||
})
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
BlocBuilder<WeightBloc, WeightState>(
|
||||
builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
right: 16.h,
|
||||
bottom: 50.v,
|
||||
),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapNext(state, context),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Section Widget
|
||||
_buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(
|
||||
leadingWidth: 29.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v),
|
||||
onTap: () => onTapArrowLeft(context)),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
}
|
||||
|
||||
onTapNext(BuildContext context, WeightState state) {
|
||||
onTapNext(WeightState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet = state.weightModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
@@ -122,7 +121,26 @@ class _WeightScreenState extends State<WeightScreen> {
|
||||
};
|
||||
}
|
||||
|
||||
void _onDropDownChanged(value) {
|
||||
context.read<WeightBloc>().add(ChangeDropDownEvent(value: value));
|
||||
/// Section Widget
|
||||
_buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(
|
||||
leadingWidth: 29.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v),
|
||||
onTap: onTapBack(context)),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
}
|
||||
|
||||
Function onTapBack(BuildContext context) {
|
||||
return () {
|
||||
onTapArrowLeft(context);
|
||||
};
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ class AppbarTitleCircleimage extends StatelessWidget {
|
||||
Key? key,
|
||||
this.imagePath,
|
||||
this.margin,
|
||||
this.onTap,
|
||||
}) : super(
|
||||
key: key,
|
||||
);
|
||||
@@ -16,13 +15,10 @@ class AppbarTitleCircleimage extends StatelessWidget {
|
||||
|
||||
EdgeInsetsGeometry? margin;
|
||||
|
||||
Function? onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
borderRadius: BorderRadiusStyle.circleBorder8,
|
||||
onTap: onTapCall,
|
||||
child: Padding(
|
||||
padding: margin ?? EdgeInsets.zero,
|
||||
child: CustomImageView(
|
||||
@@ -37,8 +33,4 @@ class AppbarTitleCircleimage extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void onTapCall() {
|
||||
onTap!.call();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_title_circleimage.dart';
|
||||
import 'package:eatvio_app/widgets/custom_navigation_menu.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomBottomBar extends StatefulWidget {
|
||||
@@ -16,41 +18,45 @@ class CustomBottomBarState extends State<CustomBottomBar> {
|
||||
|
||||
List<BottomMenuModel> bottomMenuList = [
|
||||
BottomMenuModel(
|
||||
icon: ImageConstant.imgNav,
|
||||
activeIcon: ImageConstant.imgNav,
|
||||
title: "diary".tr,
|
||||
type: BottomBarEnum.tf,
|
||||
),
|
||||
icon: ImageConstant.imgLogo,
|
||||
activeIcon: ImageConstant.imgLogo,
|
||||
type: BottomBarEnum.tf,
|
||||
image: false),
|
||||
BottomMenuModel(
|
||||
icon: ImageConstant.imgNavBlueGray400,
|
||||
activeIcon: ImageConstant.imgNavBlueGray400,
|
||||
title: "my_blog".tr,
|
||||
type: BottomBarEnum.tf,
|
||||
),
|
||||
icon: ImageConstant.imgFeed,
|
||||
activeIcon: ImageConstant.imgFeed,
|
||||
title: "Лента",
|
||||
type: BottomBarEnum.tf,
|
||||
image: false),
|
||||
BottomMenuModel(
|
||||
icon: ImageConstant.imgNavBlueGray40024x23,
|
||||
activeIcon: ImageConstant.imgNavBlueGray40024x23,
|
||||
title: "profile".tr,
|
||||
type: BottomBarEnum.tf,
|
||||
),
|
||||
icon: ImageConstant.imgDiary,
|
||||
activeIcon: ImageConstant.imgDiary,
|
||||
title: "diary".tr,
|
||||
type: BottomBarEnum.tf,
|
||||
image: false),
|
||||
BottomMenuModel(
|
||||
icon: ImageConstant.imgNavPrimary,
|
||||
activeIcon: ImageConstant.imgNavPrimary,
|
||||
title: "admin".tr,
|
||||
type: BottomBarEnum.tf,
|
||||
),
|
||||
icon: ImageConstant.imgChat,
|
||||
activeIcon: ImageConstant.imgChat,
|
||||
title: "chat".tr,
|
||||
type: BottomBarEnum.tf,
|
||||
image: false),
|
||||
BottomMenuModel(
|
||||
icon: ImageConstant.imgNavBlueGray40024x25,
|
||||
activeIcon: ImageConstant.imgNavBlueGray40024x25,
|
||||
title: "chat".tr,
|
||||
icon: ImageConstant.imgBell,
|
||||
activeIcon: ImageConstant.imgBell,
|
||||
type: BottomBarEnum.tf,
|
||||
image: false),
|
||||
BottomMenuModel(
|
||||
icon: ImageConstant.imgEllipse1,
|
||||
activeIcon: ImageConstant.imgEllipse1,
|
||||
type: BottomBarEnum.tf,
|
||||
)
|
||||
image: true,
|
||||
),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 80.v,
|
||||
height: 83.v,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: appTheme.whiteA700,
|
||||
@@ -72,31 +78,100 @@ class CustomBottomBarState extends State<CustomBottomBar> {
|
||||
}
|
||||
|
||||
void changeMeny(index) {
|
||||
selectedIndex = index;
|
||||
widget.onChanged?.call(bottomMenuList[index].type);
|
||||
setState(() {});
|
||||
setState(() {
|
||||
selectedIndex = index;
|
||||
});
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
Navigator.pushNamed(context, AppRoutes.myProfile);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
Navigator.pushNamed(context, AppRoutes.diaryEdit);
|
||||
break;
|
||||
case 3:
|
||||
Navigator.pushNamed(context, '/chat');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BottomNavigationBarItem bottomMenu(index) {
|
||||
bool isSelected = selectedIndex == index;
|
||||
|
||||
double iconHeight;
|
||||
double iconWidth;
|
||||
|
||||
if (index == 0) {
|
||||
// Для логотипа-
|
||||
iconHeight = 52.v; // Увеличиваем высоту
|
||||
iconWidth = 48.h; // Меняем ширину, чтобы сохранить пропорции
|
||||
} else if (index == bottomMenuList.length - 2) {
|
||||
// Для колокольчика
|
||||
iconHeight = 20.v; // Уменьшаем высоту
|
||||
iconWidth = 20.h; // Меняем ширину, чтобы сохранить пропорции
|
||||
} else if (index == bottomMenuList.length - 1) {
|
||||
// Для колокольчика
|
||||
iconHeight = 40.v; // Уменьшаем высоту
|
||||
iconWidth = 40.h; // Меняем ширину, чтобы сохранить пропорции
|
||||
} else {
|
||||
// Для остальных иконок
|
||||
iconHeight = 24.v; // Стандартная высота
|
||||
iconWidth = 19.h; // Стандартная ширина
|
||||
}
|
||||
|
||||
return BottomNavigationBarItem(
|
||||
icon: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
CustomImageView(
|
||||
imagePath: bottomMenuList[index].icon,
|
||||
height: 24.v,
|
||||
width: 19.h,
|
||||
color: appTheme.blueGray400,
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 8.v),
|
||||
child: Text(
|
||||
bottomMenuList[index].title ?? "",
|
||||
style: CustomTextStyles.bodySmallMulishBluegray80012.copyWith(
|
||||
color: appTheme.blueGray800,
|
||||
if (!bottomMenuList[index].image)
|
||||
CustomImageView(
|
||||
imagePath: bottomMenuList[index].icon,
|
||||
height: iconHeight,
|
||||
width: iconWidth,
|
||||
color:
|
||||
isSelected ? theme.colorScheme.primary : appTheme.blueGray400,
|
||||
),
|
||||
if (bottomMenuList[index].image)
|
||||
GestureDetector(
|
||||
onTap: () => showMenu(
|
||||
context: context,
|
||||
color: Colors.white,
|
||||
shadowColor: Colors.white,
|
||||
surfaceTintColor: Colors.white,
|
||||
position: RelativeRect.fromLTRB(
|
||||
// Указываем позицию справа по центру
|
||||
MediaQuery.of(context).size.width -
|
||||
50, // Расположение от правого края
|
||||
kToolbarHeight + 340, // Расположение от верхнего края
|
||||
0, // Не смещаем по горизонтали
|
||||
0, // Не смещаем по вертикали
|
||||
),
|
||||
items: [
|
||||
PopupMenuItem(
|
||||
child:
|
||||
CustomNavigationMenu(), // Используйте ваше меню здесь
|
||||
)
|
||||
],
|
||||
),
|
||||
child: AppbarTitleCircleimage(
|
||||
imagePath: ImageConstant.imgEllipse1,
|
||||
),
|
||||
),
|
||||
if (bottomMenuList[index].title !=
|
||||
null) // Проверяем, существует ли title
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 8.v),
|
||||
child: Text(
|
||||
bottomMenuList[index].title!,
|
||||
style: CustomTextStyles.bodySmallMulishBluegray80012.copyWith(
|
||||
color: isSelected
|
||||
? theme.colorScheme.primary
|
||||
: appTheme.blueGray800,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
activeIcon: Column(
|
||||
@@ -104,8 +179,8 @@ class CustomBottomBarState extends State<CustomBottomBar> {
|
||||
children: [
|
||||
CustomImageView(
|
||||
imagePath: bottomMenuList[index].activeIcon,
|
||||
height: 24.adaptSize,
|
||||
width: 24.adaptSize,
|
||||
height: iconHeight, // Используем тот же размер для активной иконки
|
||||
width: iconWidth, // Используем тот же размер для активной иконки
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
Padding(
|
||||
@@ -134,6 +209,7 @@ class BottomMenuModel {
|
||||
required this.activeIcon,
|
||||
this.title,
|
||||
required this.type,
|
||||
required this.image,
|
||||
});
|
||||
|
||||
String icon;
|
||||
@@ -143,4 +219,6 @@ class BottomMenuModel {
|
||||
String? title;
|
||||
|
||||
BottomBarEnum type;
|
||||
|
||||
bool image;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class CustomTextFormField extends StatelessWidget {
|
||||
this.prefixConstraints,
|
||||
this.suffix,
|
||||
this.suffixConstraints,
|
||||
this.onFieldSubmitted,
|
||||
this.initialValue,
|
||||
this.contentPadding,
|
||||
this.inputFormatters,
|
||||
@@ -66,6 +67,8 @@ class CustomTextFormField extends StatelessWidget {
|
||||
|
||||
final Widget? suffix;
|
||||
|
||||
final Function(String)? onFieldSubmitted;
|
||||
|
||||
final BoxConstraints? suffixConstraints;
|
||||
|
||||
final EdgeInsets? contentPadding;
|
||||
@@ -112,6 +115,7 @@ class CustomTextFormField extends StatelessWidget {
|
||||
keyboardType: keyboardType,
|
||||
onSaved: onSaved,
|
||||
onChanged: onChanged,
|
||||
onFieldSubmitted: onFieldSubmitted,
|
||||
inputFormatters: inputFormatters,
|
||||
initialValue: initialValue,
|
||||
),
|
||||
|
||||
@@ -255,7 +255,7 @@ class _ExpandableListState extends State<ExpandableList> {
|
||||
],
|
||||
),
|
||||
NextStepButton(
|
||||
onPressed: sendData(state),
|
||||
onPressed: () => sendProfileData(state),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
text: "save".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(top: 20.h, bottom: 20.h)),
|
||||
@@ -327,65 +327,16 @@ class _ExpandableListState extends State<ExpandableList> {
|
||||
|
||||
Future<void> sendProfileData(MyProfileLoadedState? state) async {
|
||||
try {
|
||||
// Создаем JSON объект с данными профиля
|
||||
Map<String, dynamic> profileData = {
|
||||
'first_name': state?.firstNameFormController?.text,
|
||||
'last_name': state?.lastNameFormController?.text,
|
||||
'chest_circumference': state?.chestCircumferenceFormController?.text,
|
||||
'waist_circumference': state?.waistCircumferenceFormController?.text,
|
||||
'hip_circumference': state?.hipCircumferenceFormController?.text,
|
||||
'birthdate': state?.dateFormController?.text,
|
||||
'height': state?.heightFormController?.text,
|
||||
'weight': state?.weightFormController?.text,
|
||||
'blood_pressure_up': state?.upPressureFormController?.text,
|
||||
'blood_pressure_down': state?.downPressureFormController?.text,
|
||||
'about_alergy': state?.allergiesFormController?.text,
|
||||
'about_taking_pils': state?.pillsFormController?.text,
|
||||
'about_sport_hobbies': state?.sportsFormController?.text,
|
||||
'favorite_foods': state?.favoriteFormController?.text,
|
||||
'unfavorite_foods': state?.unfavoriteFormController?.text,
|
||||
'additional_info': state?.additionalFormController?.text,
|
||||
'country': state?.selectedCountry ?? 'Россия',
|
||||
'city': state?.selectedCity ?? 'Москва',
|
||||
'has_hypo': state?.hypoFormController,
|
||||
'has_hyper': state?.hyperFormController,
|
||||
'activity_coefficient':
|
||||
determineActivityFactor(state?.selectedActivity ?? 'сидячий')
|
||||
.toString,
|
||||
};
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
String apiUrl = dotenv.env['SERVER_ROOT']! + '/profile/update';
|
||||
http.Response response = await http.post(
|
||||
Uri.parse(apiUrl),
|
||||
body: json.encode(profileData),
|
||||
encoding: utf8,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
final profileData = _createProfileData(state);
|
||||
final token = await _getTokenFromBox();
|
||||
final apiUrl = _buildApiUrl();
|
||||
final response = await _sendHttpRequest(profileData, apiUrl, token);
|
||||
|
||||
print(response.body);
|
||||
if (response.statusCode == 200) {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
_navigateToProfilePage();
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Ошибка'),
|
||||
content: Text('Ошибка при отправке данных профиля'.tr),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: onTapOk(context),
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
final errorMessage = _getErrorMessage(response);
|
||||
_showErrorDialog(errorMessage);
|
||||
throw Exception('Ошибка при отправке данных профиля');
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -393,6 +344,84 @@ class _ExpandableListState extends State<ExpandableList> {
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _createProfileData(MyProfileLoadedState? state) {
|
||||
return {
|
||||
'first_name': state?.firstNameFormController?.text,
|
||||
'last_name': state?.lastNameFormController?.text,
|
||||
'chest_circumference': state?.chestCircumferenceFormController?.text,
|
||||
'waist_circumference': state?.waistCircumferenceFormController?.text,
|
||||
'hip_circumference': state?.hipCircumferenceFormController?.text,
|
||||
'birthdate': state?.dateFormController?.text,
|
||||
'height': state?.heightFormController?.text,
|
||||
'weight': state?.weightFormController?.text,
|
||||
'blood_pressure_up': state?.upPressureFormController?.text,
|
||||
'blood_pressure_down': state?.downPressureFormController?.text,
|
||||
'about_alergy': state?.allergiesFormController?.text ?? 'Нет аллергий',
|
||||
'about_taking_pils': state?.pillsFormController?.text,
|
||||
'about_sport_hobbies': state?.sportsFormController?.text,
|
||||
'favorite_foods': state?.favoriteFormController?.text,
|
||||
'unfavorite_foods': state?.unfavoriteFormController?.text,
|
||||
'additional_info': state?.additionalFormController?.text,
|
||||
'country': state?.selectedCountry ?? 'Россия',
|
||||
'city': state?.selectedCity ?? 'Москва',
|
||||
'has_hypo': state?.hypoFormController,
|
||||
'has_hyper': state?.hyperFormController,
|
||||
'activity_coefficient':
|
||||
determineActivityFactor(state?.selectedActivity ?? 'сидячий'),
|
||||
};
|
||||
}
|
||||
|
||||
Future<String?> _getTokenFromBox() async {
|
||||
final box = await Hive.openBox('token');
|
||||
return box.get('token');
|
||||
}
|
||||
|
||||
String _buildApiUrl() {
|
||||
return dotenv.env['SERVER_ROOT']! + '/profile/update';
|
||||
}
|
||||
|
||||
Future<http.Response> _sendHttpRequest(
|
||||
Map<String, dynamic> profileData, String apiUrl, String? token) {
|
||||
return http.post(
|
||||
Uri.parse(apiUrl),
|
||||
body: json.encode(profileData),
|
||||
encoding: utf8,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _navigateToProfilePage() {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
}
|
||||
|
||||
String _getErrorMessage(http.Response response) {
|
||||
final res = jsonDecode(response.body);
|
||||
return res['message'];
|
||||
}
|
||||
|
||||
void _showErrorDialog(String errorMessage) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Ошибка'),
|
||||
content: Text(errorMessage),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: onTapOk(context),
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
onTapOk(BuildContext context) {
|
||||
return () {
|
||||
Navigator.pop(context);
|
||||
|
||||
64
lib/widgets/custom_navigation_menu.dart
Normal file
@@ -0,0 +1,64 @@
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:eatvio_app/widgets/custom_navigation_menu_item.dart';
|
||||
|
||||
class CustomNavigationMenu extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
MenuItem(
|
||||
icon: ImageConstant.imgSettings,
|
||||
text: 'Настройки профиля',
|
||||
onTap: () => Navigator.pushNamed(context, AppRoutes.mySettings),
|
||||
),
|
||||
MenuItem(
|
||||
icon: ImageConstant.imgRecipes,
|
||||
text: 'Мои рецепты',
|
||||
onTap: () {
|
||||
// Действие при нажатии на "Мои рецепты"
|
||||
},
|
||||
),
|
||||
MenuItem(
|
||||
icon: ImageConstant.imgDiets,
|
||||
text: 'Мои диеты',
|
||||
onTap: () {
|
||||
// Действие при нажатии на "Мои диеты"
|
||||
},
|
||||
),
|
||||
MenuItem(
|
||||
icon: ImageConstant.imgPlans,
|
||||
text: 'Мои планы',
|
||||
onTap: () {
|
||||
// Действие при нажатии на "Мои планы"
|
||||
},
|
||||
),
|
||||
MenuItem(
|
||||
icon: ImageConstant.imgFinance,
|
||||
text: 'Финансы',
|
||||
onTap: () {
|
||||
// Действие при нажатии на "Финансы"
|
||||
},
|
||||
),
|
||||
MenuItem(
|
||||
icon: ImageConstant.imgSupport,
|
||||
text: 'Поддержка',
|
||||
onTap: () {
|
||||
// Действие при нажатии на "Поддержка"
|
||||
},
|
||||
),
|
||||
MenuItem(
|
||||
icon: ImageConstant.imgExit,
|
||||
text: 'Выход',
|
||||
onTap: () {
|
||||
// Действие при нажатии на "Выход"
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
36
lib/widgets/custom_navigation_menu_item.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:eatvio_app/widgets/custom_image_view.dart';
|
||||
|
||||
class MenuItem extends StatelessWidget {
|
||||
final String icon;
|
||||
final String text;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const MenuItem({
|
||||
required this.icon,
|
||||
required this.text,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center, // Выравнивание по центру вертикально
|
||||
children: <Widget>[
|
||||
CustomImageView(imagePath: icon),
|
||||
SizedBox(
|
||||
width:
|
||||
8.0), // Добавляем небольшой отступ между иконкой и текстом
|
||||
Text(text),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ class CustomTextFormField extends StatelessWidget {
|
||||
this.filled = true,
|
||||
this.validator,
|
||||
this.keyboardType,
|
||||
this.onFieldSubmitted,
|
||||
this.onSaved,
|
||||
}) : super(
|
||||
key: key,
|
||||
@@ -56,6 +57,7 @@ class CustomTextFormField extends StatelessWidget {
|
||||
final bool? filled;
|
||||
final TextInputType? keyboardType;
|
||||
final FormFieldValidator<String>? validator;
|
||||
final Function(String)? onFieldSubmitted;
|
||||
final void Function(String?)? onSaved;
|
||||
|
||||
@override
|
||||
@@ -73,6 +75,7 @@ class CustomTextFormField extends StatelessWidget {
|
||||
obscureText: obscureText!,
|
||||
textInputAction: textInputAction,
|
||||
maxLines: maxLines ?? 1,
|
||||
onFieldSubmitted: onFieldSubmitted,
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText ?? "",
|
||||
hintStyle: hintStyle ?? theme.textTheme.bodyLarge,
|
||||
|
||||
@@ -24,6 +24,7 @@ void main() {
|
||||
diaryId: 1,
|
||||
selectedSatiety: 4,
|
||||
autocompleteList: [],
|
||||
photos: [],
|
||||
portions: [],
|
||||
wakeupExpanded: false,
|
||||
moderationExpanded: false,
|
||||
|
||||