From f764f06f0d0d4350687396b2d87aae1074712926 Mon Sep 17 00:00:00 2001
From: Chirag Rami <87525902+chiragramimi@users.noreply.github.com>
Date: Wed, 3 Jul 2024 14:06:01 +0530
Subject: [PATCH] Feature/ai-adviosr (#13)
---
.../xcschemes/NutritionUxExample.xcscheme | 2 +
example/ios/Podfile.lock | 4 +-
src/assets/icons/food_edit_image.png | Bin 0 -> 11676 bytes
src/assets/index.ts | 1 +
src/components/filed/FiledSelectionView.tsx | 120 ++++++++++++++
src/components/filed/FiledView.tsx | 138 ++++++++++++++++
src/components/filed/index.ts | 2 +
src/components/index.ts | 2 +
src/components/listPickers/ListPicker.tsx | 17 +-
src/components/listPickers/menu.styles.tsx | 10 +-
src/components/logOptions/LogOptions.tsx | 2 +
src/components/picker/Picker.tsx | 5 +-
src/components/tab/TabBar.tsx | 91 +++++++++++
src/components/tab/index.ts | 1 +
src/constants/colors.ts | 2 +-
src/navigaitons/BottomTabNavigations.tsx | 1 +
src/navigaitons/HomeBottomNavigations.tsx | 6 +
src/navigaitons/Nutrition-Navigator.tsx | 14 ++
src/navigaitons/Route.tsx | 4 +
src/navigaitons/TabBar.tsx | 4 +
.../params/NutritionNavigatorParam.ts | 10 ++
src/screens/advisor/AdvisorScreen.tsx | 1 +
src/screens/advisor/view/BottomBar.tsx | 85 +++++-----
.../view/message/MessageResponseView.tsx | 18 ++-
src/screens/foodCreator/FoodCreator.styles.ts | 15 ++
src/screens/foodCreator/FoodCreatorScreen.tsx | 63 ++++++++
src/screens/foodCreator/data.ts | 34 ++++
src/screens/foodCreator/index.tsx | 1 +
src/screens/foodCreator/useFoodCreator.ts | 36 +++++
.../views/FoodCreatorFoodDetail.tsx | 151 ++++++++++++++++++
.../foodCreator/views/OtherNutritionFacts.tsx | 130 +++++++++++++++
.../views/RequireNutritionFacts.tsx | 124 ++++++++++++++
src/screens/index.tsx | 2 +
src/screens/myFoods/MyFoodsScreen.styles.ts | 22 +++
src/screens/myFoods/MyFoodsScreen.tsx | 47 ++++++
src/screens/myFoods/index.tsx | 1 +
src/screens/myFoods/useMyFoodScreen.ts | 9 ++
37 files changed, 1121 insertions(+), 54 deletions(-)
create mode 100644 src/assets/icons/food_edit_image.png
create mode 100644 src/components/filed/FiledSelectionView.tsx
create mode 100644 src/components/filed/FiledView.tsx
create mode 100644 src/components/filed/index.ts
create mode 100644 src/components/tab/TabBar.tsx
create mode 100644 src/components/tab/index.ts
create mode 100644 src/screens/foodCreator/FoodCreator.styles.ts
create mode 100644 src/screens/foodCreator/FoodCreatorScreen.tsx
create mode 100644 src/screens/foodCreator/data.ts
create mode 100644 src/screens/foodCreator/index.tsx
create mode 100644 src/screens/foodCreator/useFoodCreator.ts
create mode 100644 src/screens/foodCreator/views/FoodCreatorFoodDetail.tsx
create mode 100644 src/screens/foodCreator/views/OtherNutritionFacts.tsx
create mode 100644 src/screens/foodCreator/views/RequireNutritionFacts.tsx
create mode 100644 src/screens/myFoods/MyFoodsScreen.styles.ts
create mode 100644 src/screens/myFoods/MyFoodsScreen.tsx
create mode 100644 src/screens/myFoods/index.tsx
create mode 100644 src/screens/myFoods/useMyFoodScreen.ts
diff --git a/example/ios/NutritionUxExample.xcodeproj/xcshareddata/xcschemes/NutritionUxExample.xcscheme b/example/ios/NutritionUxExample.xcodeproj/xcshareddata/xcschemes/NutritionUxExample.xcscheme
index 4042878..30f6f00 100644
--- a/example/ios/NutritionUxExample.xcodeproj/xcshareddata/xcschemes/NutritionUxExample.xcscheme
+++ b/example/ios/NutritionUxExample.xcodeproj/xcshareddata/xcschemes/NutritionUxExample.xcscheme
@@ -50,6 +50,8 @@
ReferencedContainer = "container:NutritionUxExample.xcodeproj">
+
+
C3U0;elhc__
zSbU2`>
z|Dy-03w?Gm|L2}x)Fs7;p(
z9D4dmEYeGY)?%L6N(|)d9LXZO;{*ZyrAO?9bI%aFNKs{Jb5UX_j|Ttpp}25gpn}~i
zMk`A%BG1HbY!C^lS)kz`3{32o>?kH4DFnanR4*xQM*xIKeG6c7>GoPQva=PS0F6Sg
z_DYmIs4FjU5hc^66Z_GImmG8Y(UJ)MpO=;Mp~3!y*%Z^0A0Xhon9eb+*Ef(kEg0sj
zGA+-{Y_2B3w#Kf_Tc%)a2r<(f@<76St3ap@4;4fX@78q(qD|>|G8?ld;5E8|GGSWS
ze_xz`Ldxa#;W2}KItK(zj&V9b-9T;pF9=j1Im={2OiCIGVNV~A06-c{r|!T}p&!%I
zY{1oBP%0Gm0V;9(H$ZWF7f4ucIBGGN8BLXl*goNZ^MXYbk*7<0`}5)-ZGDDiy=kUy
z;M;IccIefU&%6?taPsLYu*PT3GPcUkS~=w^j&@eR@!&~LN|BlI1H|Z=>a-{%e=v*L
z1{YV)hdro67)7wGEbvPo^FIP}nLSo)#EE;YegLG)809^-GaF=F(o${3a8lQ$y!u(7
z(~QZ-2(yNqdtNSTj*9^AIEUezY2&iia)>Vwir*^xlAvW_QnD#e62|;D7_1}|zqxI^
zVMset;Dz-D1D~*qgi0tSF?6jraw8U#-UA2t;=%l)d`Z?>EEXVE)dv;fu+;RvriTV&
zBiJB}t6s#dwrk;pF+1R*Ai5Jj4HM~Zv!QZW=OLtv#|Suap4IiWy&x_1>5)`Lw+4pw
z(lCeuf5wiNYu9IpgoVRK8p+{L=!7A}z=uAcRr`SMN|C7yJV+-7EI1vX_#HU-5KzZf
z{TxOLlJa`HzjyEpNBwY8%_XSnH7R2;5v0??nwrFRs`eMkQvjP@s2?SuQuW?hj)F6{
zoh+YLLXd51=xXI=E9)ul5-HcS*Tjs){`pYR0s~*8NaO=0ey0!tfoU5*EHhv~NVM_c
z;}f>8an}$9dql7wozGj!m59}tW{Tgm^oD;>;P}y(SF<|UT`)5%lB(X>-LYAggaIAW
zRLm0`LjKW2wREDcV5ov)wHeA->#M!26I6UC<7{JYVXG7BJa4n+JymG$p6A3{
z)=jG
ze)aJNcLuRMtq>E_6w98a_G-b7-V!Rj)Wi92*;C5Nmf^KjfxRko@3hklt~)>9)%CQM
zxty-nj)6QCLB}RN!TDD=f%Q2nX0Inw9!_+7vJE}$^f=_RXye`yzJ4ucR%_q3p4M?=
z@Jy1VHk>ZAf#jxnHTz>lpNn2i!#VbrTQjP0%jD~cx3qNE%E=IsNnBRI@WhzEi8Ne?
zZ)y6X;dVjd7W#2a!uL$86!WWQ+*4X1j<|Ne)0(L0*RNP-;WxFm_pL2X|4y)(8Ax2C
zE@Glt>Kc7k6&L)56MjW(Hs$`+f;akPioYK~-fRUz9mQ9fJI7(n}4YuyoN|6Cj+ozBPWhbTqwtVl;YW!&TcKPIX3lPuwYhV;DOj}-_w(CWE6dZG2Dk~S
z#36fyyW*ejk_Fd~Lt3lv)~BQlxxz**8tPjdr7sIgqo+(B!qZVAw4!Z>{?2=~RZh3#
zlj?5}$fls9XGH`Hy-ioi>>IWLcd;uKYDA|4bIFcz$^}|97QC4kgQo1eM$V}z|Rb!;>b0-d+)}9h=2oAt~3LP^?5`%%)WFfkW&}b`LZEeIlx0s6D=;BVHkvTkq6CujX$*#?#71
z31$j*NQ!(-%JF&qRC~Lo4(_bI@kbiZ@~z!DiyNX}ev&z@UgS9oI~$ntM_IL7kuyIS
zj;4a3X0k!WT&*7~AGiG#+NtbtG=8DmCa6M-y`Ba7s@yy+-FJC9ZA}zmb
zr0_O*cNY;HE4IiKKprgL$bH#!>YC|u9k*@nu`wX%eW>KSF|)Y!$v%Xqczm~mVrpc|
zB+kA4lCI#=JmJ%l2y2BUc7a%VVHHKqE#HOkM08DGj#6t*pH~-abFUNXLxgN3>cVQ|
z@UK>P%R~B|n3?O!cwj`e9u<;bpHi6+&j>^=ya39-`KOfpg)r<#zti9T=UuvP#X@fQ
zk(xUBvhD|cZ`H*7emq}!qu!4v=c{!3{>SJXz5s%dR-F323BssZ-@E+cJ7|=5&2g7a
zhUJ3G=-+(O@86&H9=I_N4iX;OOye=nHyyunpLlUidM{Kkzx9S&7?lU1Q&e+YaP`!g
zuF=JLOb}mjKPV0wU)2N4WYGIejP$qGmBtf<5a2>Gb~`7vEOyi`qj}x@8`eL_s+ld^
z_!_XF==BY!v`EwmjXp=k5JXtibR4orrzTCr0nT?Zv2r3_4fX%VwBP(-T>E^nvq(X<
z8u0EWl*PZyz;1%^|`ODz%@=-mF*dKGTm~I;h~51mpX!TbU1Uq;=@As2^8Pyz+Oq*y`5S
z9$u=9{(NlnW}&0MwKw7dtGK%9Q5eP0r=s=Tut&mPuf!!XY@*k8`N)pDL}VA!+P|Pa
zs`Ih7`O0@!=u}
zNcwvZSr~N*<5`tZ9}e=l(}uRa=dHu1eqJuoV@m`thUitUt_ENa-@P>M2)!K3ZTd8|
z!gXPgiqf_yS3;~G2wiyMQls)ys!4S6rSiO*Rdxl_d!_Q-uyPZ9jm*27>y2qq?mIH{
z2d^mkCzbk)<6n(IUSBF#%pbR%N$MKLNr(Ef_^ZX?2-pWdG-?$l-6d%sWLoiv{N
zab-PgI{iiO-{|^clY5ao9n`1hkIS$;2lEPxmyyk%aR!sU9Uieq%EWEXr}BM9S&Jio
zLErXO_6I$SB>v}vNX0vv>G2TZn&(_f6*8lCpF*!fCnWv?hHp_mr6pLt>Bt}T?_T|DgV(I@Aaspbf1%y*fj
zJx)tYhCd%;W2GpUYO8&yN?mwoGzOTR5j#$OcFj9iAThctM{PafeEfk0zc|a3;&Xp1
zdrAe7abN1Qe7w@QR4n*l-49*A?ktL&v!-e0rt%1e2-q{4Z}W4;zxPj5vBFraL!sy8
zdWkLJdBRcL#T}uR=&i=;$cx;GLZ)KEr}iXsc~01f9U5&uF%NQ=wvEC&u)O
zwYsSE1aKh%f9yz^rAX>46Q20M>%OS%m(8$QE`oA}OsHaS#1kw}?1hvxws&ajD%2f|
zv*w?oKib)Lr3FLA@hKT|L>rW4L-tCCl*|L3f__)P-@$Iteb@WH8G30Q33Wz06qf-r
z|Jh-|dAJQhbmAs@7kL>p3$ZHoU43k2B<&+M$wm=L@WP(ds=mcszZNK_XvLyce%oSlS#UWRIsa`}_`_u*gT#4Cpjp7_sc=%aeD_Hs-@6RgmANO;S7g&Q
zuO0=gY&!^Vt6hnRR|*I+}bsj%(-LZ7jq#z|3KZz!(DwB`HTm1%;S>u$3uht4K{z
zd7`gQ%|hJit`oi(gV=_@)XYTGVy2zJ;Xf`App3@2;mn=FCdkq|@Lpw9v*)>rM>7
zIxeBV)xL34d8Xpb3Mn^;hV&5=wFT{%yx%m4#l->^Nu
z(0)0ahXl-S@PL8Dkp9*U2a6$IY|`+{7Dm}
zLhT?iaoL_!zxx>l%3au+^rBh9LQtbOy#iaw)3ipLx}_{
zVk1S-HbTBBh21&Px378hT@#aKFVJtrn_(#WRoRDhIg@*z97=fV{{@ZRl87jF<$a^3
zOML~ft3o7Q-mDJl!uk)++BdWY!g&-ASZ+pK}3n8ycKcnzj
z>^h$u;_GsnvmhG&c(_U^QP45GoiQ+4y!`z=^I0sWL1V7U{jHiO9>Vf(u8->&iH(s{
zWA})%dz_7d?$sQ2aR2}l>-p&7*f0F+l=@fDb96T-j{QVmrD)GAI;cem075(pJ6ShQ
zns59*NU!7pM}Ay!iuktQeK9UGi(@<27aN|CHaA^PB~s%?
zAC!?=H?U;JxGr7w`7*Pm2`zA>Iqs4*C{*ATt+##aeC28HB)d`5|8k8pP8Po+;SoF8
zC_RVhOJYhh(1Q8{fM^K+y}nrd`7|8J!Jq|J*`Fu+vXGB*JLrxC5(1UvY5lE(gL|Ke
zSisCeA7-*K5l_&X+2^HSl14^{17^V@0NQFygodaoetN=WolEG#14B+7l1Koi4g?wV
zwk_wKp_I1J^q*ja%=`8A#nnVzGei{qN`4q2fIITDzZEUI6QIfp!~)=Paw_|KO?S~A
zeiCh;dmeKD@LW0cY)=x^S9SvZ8_LZ9j4X;+rgRa#x^CxP{OE@|d3)=&SSFza6liMU
zOsG7u$k4ebAM9y_W)1Wz&Glx6g(MN%7tFbuU+0^1_Z}T7SIcl*CZu}YnST6geoqMx
zom`ff^xfYlf#TKA*GNJn&`U#!(uDmDU$1Xr8&Um_Z4d~tKK8uJb;~6F*Hx3Pz#Ex&
zQMf=}pz3~fOObfn=Zz5zFtC#=P07Sn5*kU!O|wP_z@vrHV>DK|Z+!IL7=Q`Oh&Ot6
z1VLfE;}QTgIyZe@L{M;Y-(Kzd^K_-ar^D
zXI!{9v}JZmv9;R2mY{?_Zy;j!KpUpz8A_{}1e3U{_vUft*GR*W=gs%;LxG>lH61@#
zt92@{7e0!uO_6cW`l5$6
z6hM@ecRhmv0K?wf3QHGmv~oCTlaf4V31>1>Y(+Ch3iYUCrEkmB(k!ZNRK`^5xNXV(
zZ~E7b(ImI(+1YP2j3njF9fg;<45oTWwtW14a}?nZGfVe9CPP~$;~MM9t;)|>z*o6l
zhAzs*)U(%UU9$5UQy=3(0GNXQ+k>Z<9Z|CGU`*g8lTjernrQIDs=&a{$7m1L9r@1^lf}d;^7F
z_Tp#+Ramj1LlJufIUJAE&ItP7hE%9W^HNa%|J;*uJy)%n;i+5QUo=QE-oi9D`p7KE
zsBGw@eOs9(;)Pv9r8L5n$o3~G(;d2}E98WxZnCB>fWX579pm|-$1cKqHRGI@DvcZf
z*y2bfiUQ%9+5k|5z!ez@4Q0*60NASF%9FeMdJFV#rE!P>*o==)eRM2uKmA6&E&H>O
zkdTetn>Hqx;q7(uT-QBw-Y4>%iHj>>1R(gNzwMQpHEZ_+!#5Q31}f|wYdkqa|o
zv9bAiTR)RHLSbP8c?S&VY|rMGLt;j$y*f}cgj>K?)xTtw3j9$?wdQ$O&lL3LCOmf-
zM%}EMMd*P5w3A8)ap!^EMiPMm^@vK3+&v3M*ftgj_`+atxonOIGs8lgQk5T{HqOZW
zd5ED@X88EPOOaOWyu+g&>R;RM(Zlk!XEk@BBpkr)YjPz)-^CCM%(s}wZ+A#NZT2Dg
zo#-K%yYuRz5KX(CRbADo28s~U?I*Rh4TR|YM-~+v6~K;gIRsc?QPUWbJQ;*F!DG(*
zv3nBGvusT^97z4P7Koenck@JpsI5`HGs%kX
z6Wu@nc-|lWrxhGu$@AZO?O!E1At}Uy>%!~D(Md~hO_9I&Eu(7Z#h(B`syDejI)xCj
zbdCc6SH$~jN!QT{ASr2vfp?f+lU970cl3M2jZjAg8blvxEr0h;`F@%TA(UL@K(A7?
zL#l;%@$vm{dtQD~!;!83HafiE8;ZWfW>f8$=*bZ}8#J2ZK83WQgyNN=x!L6y^v!{^
z9igI60OG_N8Bj!p5iE=Ym=;`zrt-j!@1Ock4HOVuYqhk1z6`_BLZ6*#G@2tiaoR4B5bThk$?v
zXpz2G?3a^nbk37cSa{3$2>_*~2+MH2QAE3FZuuBR)NAvJRx$f0=B|_@eLI55ECren
zU*Vy<%;sjyF#Nkr8Ai-Goy`@OEJF{(wqUZogEwMK_o#4fehQ5MK(@w)gGq5!-4C+D
zN&vcnT+rD+Pht~+eW`3*00VHQ)|<5)Me&?m05=WqTQnA6^M$j}`-iS92+h(ZXF>ot
zy}{M#*?=}QAuIYBfZ(ruT}jSO$VM1rComrev;|GV;?+g)x27_ei^+T!~U
zky}_Nco1RqmwZDe?f>u6AaI*L&c;U_02Iulr-uhb2Ss2_?XG&sb9f-Ad?aWFuo1wKKR?V
z6k@u+D+4Mexy__y(7nVz3iBv*objq+fhVX+E~KM&Q!)ZtU%1E)WSdmG4X4&*>C^!wQbJm=$G2@f^`^d}b%x;t|5CydSVMlVwnN~oH*Ob
z8hjvhd}Vt7?b%!>^}FtN69A}vn_|(dIUxoM(t=mi`Va1}V*!0L*=}ux#-C5j-HGB3
z1Kiw{)9_>Q0n@gsGIQ$D9}987NKn(!T`V48D&C8~HAg-AZYmCVV;0&Z@K_)7WnuLv
zrXU-;wzZZvvwX
z3zoU4eAwIX8l=!!Rw_p}6e++Ddwb!jBlb&s($cZD9}n||pjR?EJU+zHh@4*(MrNRw
z*m_0*0+adfd=~Er{;#>45jH)L`fpw@OBmhPJab}bL>aO_Q^H3Qz&wi;
z8p4yRoM~bUQ$f7o^I74lt2&N(@OleuVUeE}X8EW=+XoiUxhr|y07&&=teVsO-k?
zhrOtDk#|_|>conyB<_cc@2f9tyK=p6uf?nrz5;I+ZYt(CP%Ru{@n;*{J^r%zZ&m8c
z@B2(>+{SZyyfs{SVG%?&8vmfHx~G9P*JUHE|y1CI8?>NZ#1P^=`nIJ~}@=8uxjn
zWkJ7HaQ9hm6UBHey~SU~(T(-pPsht!?c7|{+^I{cUz+4AyRpIsgs4KKDKpsdwzVg-
z{_Q7bIoUF3NOi3(-3|FWe;L$m77Jg=L1#%7L%FDz1{3v!EsrGpQ8KztmonN
z07;sdTER9d(l8a12JxWf
zSKcn_;`O_}Lqu?8O|PQyJ0x`od?-NhGN8_o#&vT((&he^eWmZ=e2w9&H
z%s=prk7=c3E#P7BA*G{(*jX3VDV^_9{r$gM1NKdYDXH#yi_xivsHo_T!V6=Mt5qkZ
z-KqTs;fK%Gw)pN+PKIP0Kd*ywuWpDg91fDcDC{XIK4I(?WshmK+jNmWuD<_depeaZ
z#}9Y2RqB$FD3A+!@jlwZ=}-znBfS1e0IHS5cc^W-dPGNDTKWgIe-lfl$Msp{rX4a}rM}zH*o3=az?kr~c
zoEkdS;wuYzeh_C{Zp5IJToc^>NO6R`XQrCzcopC8c(cE{<7Ui-8Rv1|0cVy1s!RIy
zQ7-C3*n2Tc%bKQdi77_CtXzgN@VDLJhw4Ku*-cLv^@&FA;|v{if$`6LD>)h?;l?qC
za?-XEY=kO@gO>W}c&!$k&6SQvw4sc6K`EV=@7>6u_puBJ`{KHila2@3Fc0JS;8$3~
z)nEw7boQgg(k;7{&8Vk6R?E1@Mlrw$@*5R?&HN4C3W_96u6oP&OUf1Nxm({+$l|
zg}WuBZUS%RO)!toGdFu5`xJ7=!o2jD*CWm>fOY;#<;_j&oG1QsGb|0Mi+grYs-v^C
zXA`ZAvz85BBh;Xm-%T|;{SyvfM3evGX!?&BJmWP{@U8guF@y_jli%kiW_y5Fha|*N
zWQ1)lcZ%)uQ-Q~BU%g0f&+_T}H{F@q)nn1NNvyzX&ueEeEBS^NryjXpoUQARvBD#y
z4JCiVT^=B(aed+8u&qTUdJ_c1o
z&f++6Y>)evUs1)R^n2c5rqi%}
zIuz}M1s1QGQM=2kxb2^JqjmWLqQ{y$^iDpiG#bkF$RMr0eKe+D;FQQA#$o#PHASJ&
z&(l>UXiY-)=Pze5dc8!LWdkbssTgIC4YbWYE>0bGDgQhLX;`eVaxRQ2_J3ebd797`
z`0hQgOzwyl9YMsl0L5bCzW3+iws7tryU*VKPDYYLb2@u}e%79Z(AA>rrKD{1qyJil
z<>jc;iGi8T*RamHw?h*S+YbUe=m*f5dyu)R4y~BnKY7+K@{vGsB0o~@NmE#Z#l#yE
zOgQb%hwckkk?5~w34hytIZGap581i_%7`bGlZy2$=lxNB!AT
zq;Q=kbA^PenE=d7gT3RsIz?@pCIwfEBH|Hy6k}uN;rqwhXbOm8#`Rw4Q-w?@^S|Ar
z>M?AprZ732$aVi8M(z!sA}1cyVL*5|vxDs$BFPLaE5e-%WaEM9!DKrbKMjb4sfn66
zz|J6nt8A2qMR*@GZ1mEP)|Vn|rt3+#t?wtt1~Go1fD*KdaFS8vnwlvRMk_G%cS6qbaPQ2ibh_Pg9e$0j
zSNvAhn$P$^_tyu$^plTlVyr*rA<>=<8-1tbq6Gcf#iZqeL4T+F5YnFL+DhZ3c@E+b
zw4`ty!?|tiS`ZjB(XI7if-9~6ql^SiKvBUGQ{ga85#@bI`
zKw;_{I$KAAHV*rE#-ieky>2lQq6Y_*sgFs`82LX|`cj6^$iL4f17o_T;*eVGf1ySy
zyKU!EOxW;7kxOBaGr`n(7B-Lh7L#*R!%Mb(!+qdgGe-erAEh_Y
z9Mrz$Omc7^vDEeKk$0#C{Gl&`FL2bKfiVS09o(&WeR6lLNrMM2mASNzZ+)~6iY&4-FJmbPv~ZHLGQ101EiIRumUBEb
z>1(B$yG8ryHBO2g)(QAR-yGM70FirKBc#oR^OX@J=_`zR_{85iGUWbu+C=nwj9<
z6Z(9TkKrOoe8vG0!o(r5lJ1k<>u5etf24S6y;$5{M=dypQIJi%wB-?kT{|W930mqX
zh!ehCsS^~?F=h-QixQVlfI#8oMy=`i;Af void;
+ isColum?: boolean;
+ isCenter?: boolean;
+}
+export interface FiledSelectionViewRef {
+ value: () => string | undefined;
+ errorCheck: () => boolean | undefined;
+}
+
+export const FiledSelectionView = React.forwardRef<
+ FiledSelectionViewRef,
+ Props
+>(
+ (
+ {
+ name,
+ lists,
+ labelList,
+ label,
+ onChange,
+ value: defaultValue,
+ isColum = false,
+ isCenter = false,
+ }: Props,
+ ref: React.Ref
+ ) => {
+ const branding = useBranding();
+
+ const styles = requireNutritionFactStyle(branding);
+ const [value, setValue] = useState(defaultValue);
+ const [error, setError] = useState();
+
+ useImperativeHandle(
+ ref,
+ () => ({
+ value: () => {
+ return value;
+ },
+ errorCheck: () => {
+ if (value === undefined || value?.length === 0) {
+ setError('please enter value');
+ } else {
+ setError(undefined);
+ }
+ return value?.length === 0;
+ },
+ }),
+ [value]
+ );
+
+ const renderFiled = () => {
+ return (
+
+
+ {name}
+
+ {
+ onChange?.(item);
+ setError(undefined);
+ setValue(item);
+ }}
+ lists={lists ?? []}
+ label={label}
+ labelList={labelList}
+ style={styles.pickerTextInput}
+ error={error ?? ''}
+ />
+
+ );
+ };
+
+ return {renderFiled()};
+ }
+);
+
+const requireNutritionFactStyle = ({}: Branding) =>
+ StyleSheet.create({
+ formRow: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ marginBottom: 10,
+ },
+ formColum: {
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ marginBottom: 10,
+ },
+ label: {
+ flex: 1,
+ },
+ labelMargin: {
+ marginTop: 10,
+ },
+ pickerTextInput: {
+ flexWrap: 'wrap',
+ textAlign: 'right',
+ },
+ });
diff --git a/src/components/filed/FiledView.tsx b/src/components/filed/FiledView.tsx
new file mode 100644
index 0000000..c182f24
--- /dev/null
+++ b/src/components/filed/FiledView.tsx
@@ -0,0 +1,138 @@
+import React, { useImperativeHandle, useState } from 'react';
+import { Text, TextInput } from '..';
+import {
+ Image,
+ KeyboardTypeOptions,
+ StyleSheet,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+import { Branding, useBranding } from '../../contexts';
+import { scaleHeight } from '../../utils';
+import { ICONS } from '../../assets';
+
+interface Props {
+ name: string;
+ value?: string;
+ label?: string;
+ keyboardType?: KeyboardTypeOptions;
+ isColum?: boolean;
+ onDelete?: () => void;
+}
+
+export interface FiledViewRef {
+ value: () => string | undefined;
+ errorCheck: () => boolean | undefined;
+}
+
+export const FiledView = React.forwardRef(
+ (
+ {
+ name,
+ value: defaultValue,
+ keyboardType = 'decimal-pad',
+ label = 'value',
+ isColum = false,
+ onDelete,
+ }: Props,
+ ref: React.Ref
+ ) => {
+ const branding = useBranding();
+ const [value, setValue] = useState(defaultValue);
+ const [error, setError] = useState();
+
+ const styles = requireNutritionFactStyle(branding);
+
+ useImperativeHandle(
+ ref,
+ () => ({
+ value: () => {
+ return value;
+ },
+ errorCheck: () => {
+ if (value === undefined || value?.length === 0) {
+ setError('please enter value');
+ } else {
+ setError(undefined);
+ }
+ return value?.length === 0;
+ },
+ }),
+ [value]
+ );
+
+ const renderFiled = () => {
+ return (
+
+
+ {name}
+
+ {
+ setValue(text);
+ setError(undefined);
+ }}
+ value={defaultValue}
+ containerStyle={styles.containerTextInput}
+ placeholder={label}
+ error={error}
+ enterKeyHint="next"
+ keyboardType={keyboardType}
+ />
+ {onDelete && (
+
+
+
+ )}
+
+ );
+ };
+
+ return {renderFiled()};
+ }
+);
+
+const requireNutritionFactStyle = ({ white, gray300 }: Branding) =>
+ StyleSheet.create({
+ formRow: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ marginBottom: 10,
+ },
+ formColum: {
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ marginBottom: 10,
+ },
+ label: {
+ flex: 1,
+ },
+ labelMargin: {
+ marginTop: 10,
+ },
+ delete: {
+ height: 24,
+ width: 24,
+ marginHorizontal: 6,
+ },
+ textInput: {
+ textAlign: 'left',
+ flex: 1,
+ fontWeight: '400',
+ fontSize: 14,
+ backgroundColor: white,
+ borderColor: gray300,
+ paddingVertical: scaleHeight(8),
+ borderRadius: scaleHeight(4),
+ },
+ containerTextInput: {
+ flex: 1,
+ },
+ });
diff --git a/src/components/filed/index.ts b/src/components/filed/index.ts
new file mode 100644
index 0000000..3f64981
--- /dev/null
+++ b/src/components/filed/index.ts
@@ -0,0 +1,2 @@
+export * from './FiledSelectionView';
+export * from './FiledView';
diff --git a/src/components/index.ts b/src/components/index.ts
index 356ce32..ec6124e 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -41,6 +41,8 @@ export * from './weeklyAddhernce';
export * from './progressBard';
export * from './timeStamp';
export * from './mealPlan';
+export * from './tab';
+export * from './filed';
import ActionSheet from './actionSheets/ActionSheet';
export { ActionSheet };
diff --git a/src/components/listPickers/ListPicker.tsx b/src/components/listPickers/ListPicker.tsx
index 399ca81..5fad0e1 100644
--- a/src/components/listPickers/ListPicker.tsx
+++ b/src/components/listPickers/ListPicker.tsx
@@ -18,11 +18,12 @@ interface Props {
labelList?: string[];
value: string;
title: string;
- error: string;
+ error?: string;
style: StyleProp;
label?: string;
extraWidth?: number;
onChange: (size: T) => void;
+ isCenter?: boolean;
}
export const ListPicker: React.FC> = ({
@@ -32,6 +33,8 @@ export const ListPicker: React.FC> = ({
extraWidth,
value,
onChange,
+ isCenter,
+ error,
}) => {
const branding = useBranding();
const styles = menuStyle(branding);
@@ -49,6 +52,8 @@ export const ListPicker: React.FC> = ({
}}
>
> = ({
return (
> = ({
}
>
- {label ?? value}
+
+ {label ?? value}
+
+ {error && (
+
+ {error}
+
+ )}
);
};
diff --git a/src/components/listPickers/menu.styles.tsx b/src/components/listPickers/menu.styles.tsx
index 95d4c7a..6a19ad5 100644
--- a/src/components/listPickers/menu.styles.tsx
+++ b/src/components/listPickers/menu.styles.tsx
@@ -2,11 +2,11 @@ import { StyleSheet } from 'react-native';
import type { Branding } from '../../contexts';
import { scaleHeight, scaleWidth } from '../../utils';
-const menuStyle = ({ white, border }: Branding) =>
+const menuStyle = ({ white, gray300, border, error }: Branding) =>
StyleSheet.create({
main: {
backgroundColor: white,
- borderColor: border,
+ borderColor: gray300,
flexDirection: 'row',
borderRadius: 4,
paddingVertical: 8,
@@ -17,13 +17,16 @@ const menuStyle = ({ white, border }: Branding) =>
mainTitle: {
flex: 1,
marginStart: 12,
- textTransform: 'capitalize',
},
icon: {
marginEnd: 12,
height: scaleHeight(20),
width: scaleWidth(20),
},
+ error: {
+ color: error,
+ },
+
optionContainer: {
backgroundColor: white,
paddingVertical: scaleHeight(16),
@@ -33,7 +36,6 @@ const menuStyle = ({ white, border }: Branding) =>
},
optionTitle: {
marginStart: scaleWidth(12),
- textTransform: 'capitalize',
},
optionIcon: {
height: scaleHeight(20),
diff --git a/src/components/logOptions/LogOptions.tsx b/src/components/logOptions/LogOptions.tsx
index ea92f92..418ee3f 100644
--- a/src/components/logOptions/LogOptions.tsx
+++ b/src/components/logOptions/LogOptions.tsx
@@ -13,6 +13,7 @@ interface Props {
onTakePicture: () => void;
onTakeCamera: () => void;
onAiAdvisor: () => void;
+ onMyFoods: () => void;
}
type Type = 'All' | 'UseImage';
@@ -45,6 +46,7 @@ export const LogOptions = ({
{type === 'All' ? (
<>
+ {/* {renderItem(ICONS.logOptionFavorite, 'My Foods', onMyFoods)} */}
{renderItem(ICONS.logOptionFavorite, 'Favorites', onFavorite)}
{renderItem(ICONS.Mic, 'Voice Logging', onVoiceLogging)}
{renderItem(ICONS.AIAdvisor, 'AI Advisor', onAiAdvisor)}
diff --git a/src/components/picker/Picker.tsx b/src/components/picker/Picker.tsx
index 5a998c9..af7c92e 100644
--- a/src/components/picker/Picker.tsx
+++ b/src/components/picker/Picker.tsx
@@ -3,13 +3,14 @@ import { View, Modal, Pressable, Platform } from 'react-native';
import { useBranding } from '../../contexts';
import tutorialStyle from './picker.styles';
import { Card } from '../cards';
-import { scaleWidth } from '../../utils';
+import { scaleWidth, screenHeight } from '../../utils';
interface PickerProps extends React.PropsWithChildren {
top?: boolean;
bottom?: boolean;
options: React.JSX.Element;
extraWidth?: number;
+ isCenter?: boolean;
}
export interface PickerRef {
onClose: () => void;
@@ -46,7 +47,7 @@ export const Picker = React.forwardRef(
(fx: number, fy: number, width: number, height: number) => {
const newMeasure: Matrix = {
x: fx,
- y: fy,
+ y: props.isCenter ? screenHeight / 2 : fy,
width: width,
height: height,
};
diff --git a/src/components/tab/TabBar.tsx b/src/components/tab/TabBar.tsx
new file mode 100644
index 0000000..228b399
--- /dev/null
+++ b/src/components/tab/TabBar.tsx
@@ -0,0 +1,91 @@
+import React, { useState } from 'react';
+import { StyleSheet, TouchableOpacity, View } from 'react-native';
+import { Text } from '../../components';
+import { Branding, useBranding } from '../../contexts';
+import { scaleHeight } from '../../utils';
+
+export interface TabBarProps {
+ list: string[];
+ onTabSelect: (value: string) => void;
+}
+
+export const TabBar = ({ list, onTabSelect }: TabBarProps) => {
+ const styles = tabStyles(useBranding());
+ const [tab, setTab] = useState(list[0]);
+
+ return (
+
+
+ {
+ setTab(list[0]);
+ onTabSelect(list[0]);
+ }}
+ >
+
+ {list[0]}
+
+
+ {
+ setTab(list[1]);
+ onTabSelect(list[1]);
+ }}
+ >
+
+ {list[1]}
+
+
+
+
+
+
+
+
+ );
+};
+
+const tabStyles = ({ primaryColor, text }: Branding) =>
+ StyleSheet.create({
+ tabContainer: {
+ flexDirection: 'row',
+ paddingVertical: scaleHeight(12),
+ },
+ touchableTab: {
+ flex: 1,
+ },
+ tabTex: {
+ fontSize: 18,
+ fontWeight: '400',
+ textAlign: 'center',
+ color: text,
+ },
+ tabSelectText: {
+ fontWeight: '600',
+ color: primaryColor,
+ },
+ lineContainer: {
+ flexDirection: 'row',
+ },
+ tabLine: {
+ height: 2,
+ borderRadius: 24,
+ flex: 1,
+ },
+ tabSelectLine: {
+ backgroundColor: primaryColor,
+ },
+ });
diff --git a/src/components/tab/index.ts b/src/components/tab/index.ts
new file mode 100644
index 0000000..832e14a
--- /dev/null
+++ b/src/components/tab/index.ts
@@ -0,0 +1 @@
+export * from './TabBar';
diff --git a/src/constants/colors.ts b/src/constants/colors.ts
index a4d66c4..a077578 100644
--- a/src/constants/colors.ts
+++ b/src/constants/colors.ts
@@ -20,7 +20,7 @@ export const COLORS = {
grayscale: '#6E7191',
grayscaleAsh: '#262338',
grayscaleBody: '#4E4B66',
- grayscaleLine: '#D9DBE9',
+ grayscaleLine: '#D1D5DB',
grayscaleInput: '#EFF0F6',
grey9: '#D0D3DA',
monochrome: '#6E7191',
diff --git a/src/navigaitons/BottomTabNavigations.tsx b/src/navigaitons/BottomTabNavigations.tsx
index 39db9ec..ce0f537 100644
--- a/src/navigaitons/BottomTabNavigations.tsx
+++ b/src/navigaitons/BottomTabNavigations.tsx
@@ -23,6 +23,7 @@ export interface TabBarProps extends BottomTabBarProps {
onTakePicture: () => void;
onTakeCamera: () => void;
onAiAdvisor: () => void;
+ onMyFoods: () => void;
}
export const renderTabBarIcons = (
diff --git a/src/navigaitons/HomeBottomNavigations.tsx b/src/navigaitons/HomeBottomNavigations.tsx
index 64c52fa..bcea557 100644
--- a/src/navigaitons/HomeBottomNavigations.tsx
+++ b/src/navigaitons/HomeBottomNavigations.tsx
@@ -144,6 +144,12 @@ export const HomeBottomNavigation = React.memo(() => {
logToMeal: undefined,
});
}}
+ onMyFoods={() => {
+ navigation.navigate('MyFoodsScreen', {
+ logToDate: mealLogDateRef.current,
+ logToMeal: undefined,
+ });
+ }}
onTakePicture={onTakePicture}
{...props}
items={menu}
diff --git a/src/navigaitons/Nutrition-Navigator.tsx b/src/navigaitons/Nutrition-Navigator.tsx
index dcfec6f..a9fd3f7 100644
--- a/src/navigaitons/Nutrition-Navigator.tsx
+++ b/src/navigaitons/Nutrition-Navigator.tsx
@@ -19,6 +19,8 @@ import {
TakePictureScreen,
AdvisorScreen,
ImagePickerScreen,
+ MyFoodsScreen,
+ FoodCreatorScreen,
} from '../screens';
import {
DashboardScreenRoute,
@@ -44,6 +46,8 @@ import {
TakePictureScreenRoute,
AdvisorScreenRoute,
ImagePickerScreenRoute,
+ MyFoodsScreenRoute,
+ FoodCreatorScreenRoute,
} from './Route';
import MyPlanScreen from '../screens/myPlans/MyPlanScreen';
import { HomeBottomNavigation } from './HomeBottomNavigations';
@@ -201,6 +205,16 @@ export const NutritionNavigator = () => {
name={ImagePickerScreenRoute}
component={ImagePickerScreen}
/>
+
+
{
floatingRef.current?.onClose();
props.onAiAdvisor();
}}
+ onMyFoods={() => {
+ floatingRef.current?.onClose();
+ props.onMyFoods();
+ }}
/>
}
/>
diff --git a/src/navigaitons/params/NutritionNavigatorParam.ts b/src/navigaitons/params/NutritionNavigatorParam.ts
index c0f4a90..0229789 100644
--- a/src/navigaitons/params/NutritionNavigatorParam.ts
+++ b/src/navigaitons/params/NutritionNavigatorParam.ts
@@ -60,6 +60,14 @@ export interface AdvisorScreenProps {
logToDate?: Date | undefined;
logToMeal?: MealLabel | undefined;
}
+export interface FoodCreatorNavProps {
+ logToDate?: Date | undefined;
+ logToMeal?: MealLabel | undefined;
+}
+export interface MyFoodsScreenNavProps {
+ logToDate?: Date | undefined;
+ logToMeal?: MealLabel | undefined;
+}
export type ParamList = {
MealLogScreen: MealLogScreenProps;
@@ -89,4 +97,6 @@ export type ParamList = {
TakePictureScreen: TakePictureScreenProps;
AdvisorScreen: AdvisorScreenProps;
ImagePickerScreen: ImagePickerProps;
+ FoodCreatorScreen: FoodCreatorNavProps;
+ MyFoodsScreen: MyFoodsScreenNavProps;
};
diff --git a/src/screens/advisor/AdvisorScreen.tsx b/src/screens/advisor/AdvisorScreen.tsx
index 996f961..1c80766 100644
--- a/src/screens/advisor/AdvisorScreen.tsx
+++ b/src/screens/advisor/AdvisorScreen.tsx
@@ -110,6 +110,7 @@ export const AdvisorScreen = () => {
keyExtractor={(_item, index) => index.toString()}
renderItem={renderItem}
showsVerticalScrollIndicator={false}
+ contentContainerStyle={{ flexGrow: 1 }}
style={styles.flatListStyle}
// onContentSizeChange={() => listRef.current?.scrollToEnd()}
// onLayout={() => listRef.current?.scrollToEnd()}
diff --git a/src/screens/advisor/view/BottomBar.tsx b/src/screens/advisor/view/BottomBar.tsx
index ec5862d..6daa06f 100644
--- a/src/screens/advisor/view/BottomBar.tsx
+++ b/src/screens/advisor/view/BottomBar.tsx
@@ -35,44 +35,55 @@ export const BottomBar = ({
return (
- {isOptionShow ? (
-
-
-
-
+ {inputValue.length === 0 && (
+ <>
+ {isOptionShow ? (
+
+
+
+
-
-
-
-
- ) : (
-
-
-
+
+
+
+
+ ) : (
+
+
+
+ )}
+ >
)}
- {renderText()}
+
+
+ {renderText()}
+
{tools && tools?.length > 0 && (
)}
-
+
);
};
@@ -98,7 +105,6 @@ const ResponseViewStyle = () =>
},
receivedMsgView: {
backgroundColor: '#6366F1',
- alignSelf: 'flex-start',
borderBottomRightRadius: 8,
borderBottomLeftRadius: 0,
},
diff --git a/src/screens/foodCreator/FoodCreator.styles.ts b/src/screens/foodCreator/FoodCreator.styles.ts
new file mode 100644
index 0000000..ba70ec2
--- /dev/null
+++ b/src/screens/foodCreator/FoodCreator.styles.ts
@@ -0,0 +1,15 @@
+import { StyleSheet } from 'react-native';
+import { getStatusBarHeight } from 'react-native-status-bar-height';
+import type { Branding } from '../../contexts';
+
+export const foodCreatorStyle = ({ searchBody }: Branding) =>
+ StyleSheet.create({
+ statusBarLayout: {
+ height: getStatusBarHeight(),
+ backgroundColor: searchBody,
+ },
+ body: {
+ backgroundColor: searchBody,
+ flex: 1,
+ },
+ });
diff --git a/src/screens/foodCreator/FoodCreatorScreen.tsx b/src/screens/foodCreator/FoodCreatorScreen.tsx
new file mode 100644
index 0000000..73b287c
--- /dev/null
+++ b/src/screens/foodCreator/FoodCreatorScreen.tsx
@@ -0,0 +1,63 @@
+import { ScrollView, View } from 'react-native';
+
+import React from 'react';
+import { foodCreatorStyle } from './FoodCreator.styles';
+import { useFoodCreator } from './useFoodCreator';
+import { BackNavigation, BasicButton } from '../../components';
+import { FoodCreatorFoodDetail } from './views/FoodCreatorFoodDetail';
+import { RequireNutritionFacts } from './views/RequireNutritionFacts';
+import { OtherNutritionFacts } from './views/OtherNutritionFacts';
+
+export const FoodCreatorScreen = () => {
+ const {
+ branding,
+ otherNutritionFactsRef,
+ requireNutritionFactsRef,
+ foodCreatorFoodDetailRef,
+ onSavePress,
+ } = useFoodCreator();
+
+ const styles = foodCreatorStyle(branding);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/screens/foodCreator/data.ts b/src/screens/foodCreator/data.ts
new file mode 100644
index 0000000..1316467
--- /dev/null
+++ b/src/screens/foodCreator/data.ts
@@ -0,0 +1,34 @@
+import type { NutrientType } from '../../models';
+
+export const Units = [
+ 'Servings',
+ 'Piece',
+ 'cup',
+ 'oz',
+ 'g',
+ 'ml',
+ 'handful',
+ 'scoop',
+ 'tbsp',
+ 'tsp',
+ 'slice',
+ 'can',
+ 'bottle',
+ 'bar',
+ 'packet',
+];
+
+export const OtherNutrients: NutrientType[] = [
+ 'satFat',
+ 'transFat',
+ 'cholesterol',
+ 'sodium',
+ 'fiber',
+ 'sugars',
+ 'sugarAdded',
+ 'vitaminD',
+ 'calcium',
+ 'iron',
+ 'potassium',
+];
+export const Weights = ['grams', 'ml'];
diff --git a/src/screens/foodCreator/index.tsx b/src/screens/foodCreator/index.tsx
new file mode 100644
index 0000000..df80ca5
--- /dev/null
+++ b/src/screens/foodCreator/index.tsx
@@ -0,0 +1 @@
+export * from './FoodCreatorScreen';
diff --git a/src/screens/foodCreator/useFoodCreator.ts b/src/screens/foodCreator/useFoodCreator.ts
new file mode 100644
index 0000000..8f8bf77
--- /dev/null
+++ b/src/screens/foodCreator/useFoodCreator.ts
@@ -0,0 +1,36 @@
+import { useRef } from 'react';
+import { useBranding } from '../../contexts';
+import type { OtherNutritionFactsRef } from './views/OtherNutritionFacts';
+import type { RequireNutritionFactsRef } from './views/RequireNutritionFacts';
+import type { FoodCreatorFoodDetailRef } from './views/FoodCreatorFoodDetail';
+
+export const useFoodCreator = () => {
+ const branding = useBranding();
+ const otherNutritionFactsRef = useRef(null);
+ const requireNutritionFactsRef = useRef(null);
+ const foodCreatorFoodDetailRef = useRef(null);
+
+ const onSavePress = () => {
+ const info = foodCreatorFoodDetailRef.current?.getValue();
+ const requireNutritionFact = requireNutritionFactsRef.current?.getValue();
+ const otherNutritionFact = otherNutritionFactsRef.current?.getValue();
+
+ if (info?.isNotValid) {
+ return;
+ }
+ if (requireNutritionFact?.isNotValid) {
+ return;
+ }
+ if (otherNutritionFact?.isNotValid) {
+ return;
+ }
+ };
+
+ return {
+ branding,
+ otherNutritionFactsRef,
+ requireNutritionFactsRef,
+ foodCreatorFoodDetailRef,
+ onSavePress,
+ };
+};
diff --git a/src/screens/foodCreator/views/FoodCreatorFoodDetail.tsx b/src/screens/foodCreator/views/FoodCreatorFoodDetail.tsx
new file mode 100644
index 0000000..8715dbc
--- /dev/null
+++ b/src/screens/foodCreator/views/FoodCreatorFoodDetail.tsx
@@ -0,0 +1,151 @@
+import React, { useImperativeHandle, useMemo, useRef } from 'react';
+import { Card, Text } from '../../../components';
+import { Image, StyleSheet, View } from 'react-native';
+import { Branding, useBranding } from '../../../contexts';
+import { FiledView, FiledViewRef } from '../../../components/filed/FiledView';
+import {
+ FiledSelectionView,
+ FiledSelectionViewRef,
+} from '../../../components/filed/FiledSelectionView';
+import { Units } from '../data';
+import { ICONS } from '../../../assets';
+
+interface Props {}
+
+export type FoodCreatorFoodDetailType = 'name' | 'brand' | 'barcode';
+
+interface Value {
+ records: Record;
+ isNotValid?: boolean;
+}
+
+export interface FoodCreatorFoodDetailRef {
+ getValue: () => Value;
+}
+
+export const FoodCreatorFoodDetail = React.forwardRef<
+ FoodCreatorFoodDetailRef,
+ Props
+>(({}: Props, ref: React.Ref) => {
+ const branding = useBranding();
+
+ const styles = requireNutritionFactStyle(branding);
+
+ const nameRef = useRef(null);
+ const brandNameRef = useRef(null);
+ const barcodeRef = useRef(null);
+
+ const refs = useMemo(
+ () => ({
+ name: nameRef,
+ brand: brandNameRef,
+ barcode: barcodeRef,
+ }),
+ []
+ );
+
+ useImperativeHandle(
+ ref,
+ () => ({
+ getValue: () => {
+ let record: Record = {} as Record<
+ FoodCreatorFoodDetailType,
+ string
+ >;
+ let isNotValid = false;
+
+ (Object.keys(refs) as FoodCreatorFoodDetailType[]).forEach((key) => {
+ const currentRef = refs[key].current;
+ const value = currentRef?.value();
+ currentRef?.errorCheck();
+ if (value === undefined || value.length === 0) {
+ isNotValid = true;
+ }
+ record[key] = value ?? '';
+ });
+
+ return {
+ records: record,
+ isNotValid,
+ };
+ },
+ }),
+ [refs]
+ );
+
+ return (
+
+ {
+
+ {'Scan Description'}
+
+
+
+
+ {'Edit Image'}
+
+
+
+
+
+
+
+
+
+ }
+
+ );
+});
+
+const requireNutritionFactStyle = ({}: Branding) =>
+ StyleSheet.create({
+ card: {
+ marginHorizontal: 16,
+ marginVertical: 16,
+ padding: 16,
+ },
+ title: {
+ marginBottom: 16,
+ },
+ container: {
+ flexDirection: 'row',
+ alignContent: 'space-around',
+ justifyContent: 'space-between',
+ },
+ left: {
+ flex: 1,
+ alignContent: 'center',
+ alignItems: 'center',
+ alignSelf: 'center',
+ },
+ right: {
+ flex: 1.5,
+ },
+ editImage: {
+ marginVertical: 4,
+ fontSize: 10,
+ },
+ icon: {
+ height: 80,
+ width: 80,
+ alignItems: 'center',
+ alignSelf: 'center',
+ justifyContent: 'center',
+ alignContent: 'center',
+ },
+ });
diff --git a/src/screens/foodCreator/views/OtherNutritionFacts.tsx b/src/screens/foodCreator/views/OtherNutritionFacts.tsx
new file mode 100644
index 0000000..8328df4
--- /dev/null
+++ b/src/screens/foodCreator/views/OtherNutritionFacts.tsx
@@ -0,0 +1,130 @@
+import React, { useImperativeHandle, useRef, useState } from 'react';
+import { Card, Text } from '../../../components';
+import { StyleSheet, View } from 'react-native';
+import { Branding, useBranding } from '../../../contexts';
+import { FiledView, FiledViewRef } from '../../../components/filed/FiledView';
+import { FiledSelectionView } from '../../../components/filed/FiledSelectionView';
+import { OtherNutrients } from '../data';
+import { FlatList } from 'react-native';
+import { nutrientName, type NutrientType } from '../../../models';
+
+interface Props {}
+
+interface Value {
+ records: Record;
+ isNotValid?: boolean;
+}
+export interface OtherNutritionFactsRef {
+ getValue: () => Value;
+}
+
+export const OtherNutritionFacts = React.forwardRef<
+ OtherNutritionFactsRef,
+ Props
+>(({}: Props, ref: React.Ref) => {
+ const branding = useBranding();
+
+ const styles = requireNutritionFactStyle(branding);
+ const [defaultList, setDefaultList] =
+ useState(OtherNutrients);
+ const [list, setList] = useState([]);
+ const labelList = defaultList.map((i) => {
+ return nutrientName[i].toString() ?? '';
+ });
+
+ const refs = useRef>>({});
+
+ useImperativeHandle(
+ ref,
+ () => ({
+ getValue: () => {
+ let record: Record = {} as Record<
+ NutrientType,
+ string
+ >;
+ let isNotValid = false;
+ list.forEach((item) => {
+ const sleetedRef = refs.current[item];
+ if (sleetedRef && sleetedRef.current) {
+ if (sleetedRef.current.errorCheck()) {
+ isNotValid = true;
+ }
+ record[item as NutrientType] = sleetedRef.current.value() ?? '';
+ }
+ });
+
+ return {
+ records: record,
+ isNotValid: isNotValid,
+ };
+ },
+ }),
+ [list]
+ );
+
+ // Initialize refs for each item in the list
+ list.forEach((item) => {
+ if (!refs.current[item]) {
+ refs.current[item] = React.createRef();
+ }
+ });
+
+ return (
+
+ {
+
+ {'Other Nutrition Facts'}
+ item}
+ renderItem={({ item }) => {
+ return (
+ {
+ setList((i) => [...i.filter((o) => item !== o)]);
+ setDefaultList((i) => [...i, item as NutrientType]);
+ }}
+ />
+ );
+ }}
+ />
+ {defaultList.length > 0 && (
+ {
+ setList((i) => [...i, item]);
+ setDefaultList((i) => [...i.filter((o) => item !== o)]);
+ }}
+ />
+ )}
+
+ }
+
+ );
+});
+
+const requireNutritionFactStyle = ({}: Branding) =>
+ StyleSheet.create({
+ card: {
+ marginHorizontal: 16,
+ marginVertical: 16,
+ padding: 16,
+ },
+ title: {
+ marginBottom: 16,
+ },
+ container: {
+ flexDirection: 'row',
+ alignContent: 'space-around',
+ justifyContent: 'space-between',
+ },
+ });
diff --git a/src/screens/foodCreator/views/RequireNutritionFacts.tsx b/src/screens/foodCreator/views/RequireNutritionFacts.tsx
new file mode 100644
index 0000000..0d5c47c
--- /dev/null
+++ b/src/screens/foodCreator/views/RequireNutritionFacts.tsx
@@ -0,0 +1,124 @@
+import React, { useImperativeHandle, useRef, useState, useMemo } from 'react';
+import { Card, FiledViewRef, Text } from '../../../components';
+import { StyleSheet, View } from 'react-native';
+import { Branding, useBranding } from '../../../contexts';
+import { FiledView } from '../../../components';
+import {
+ FiledSelectionView,
+ FiledSelectionViewRef,
+} from '../../../components/filed/FiledSelectionView';
+import { Units, Weights } from '../data';
+
+interface Props {}
+
+export type RequireNutritionFactsType =
+ | 'calories'
+ | 'ServingSize'
+ | 'Units'
+ | 'Weight'
+ | 'Fat'
+ | 'Carbs'
+ | 'Protein';
+
+interface Value {
+ records: Record;
+ isNotValid?: boolean;
+}
+
+export interface RequireNutritionFactsRef {
+ getValue: () => Value;
+}
+
+export const RequireNutritionFacts = React.forwardRef<
+ RequireNutritionFactsRef,
+ Props
+>(({}: Props, ref: React.Ref) => {
+ const branding = useBranding();
+ const styles = requireNutritionFactStyle(branding);
+
+ const [units, setUnits] = useState('');
+
+ const servingSizeRef = useRef(null);
+ const caloriesRef = useRef(null);
+ const fatRef = useRef(null);
+ const carbsRef = useRef(null);
+ const proteinRef = useRef(null);
+ const unitRef = useRef(null);
+ const weightRef = useRef(null);
+
+ const refs = useMemo(
+ () => ({
+ ServingSize: servingSizeRef,
+ Units: unitRef,
+ Weight: weightRef,
+ calories: caloriesRef,
+ Fat: fatRef,
+ Carbs: carbsRef,
+ Protein: proteinRef,
+ }),
+ []
+ );
+
+ useImperativeHandle(
+ ref,
+ () => ({
+ getValue: () => {
+ let record: Record = {} as Record<
+ RequireNutritionFactsType,
+ string
+ >;
+ let isNotValid = false;
+
+ (Object.keys(refs) as RequireNutritionFactsType[]).forEach((key) => {
+ const currentRef = refs[key].current;
+ const value = currentRef?.value();
+ currentRef?.errorCheck();
+ if (value === undefined || value.length === 0) {
+ isNotValid = true;
+ }
+ record[key] = value ?? '';
+ });
+
+ return {
+ records: record,
+ isNotValid,
+ };
+ },
+ }),
+ [refs]
+ );
+
+ return (
+
+
+ {'Required Nutrition Facts'}
+
+ setUnits(value)}
+ />
+ {units === 'g' || units === 'ml' ? null : (
+
+ )}
+
+
+
+
+
+
+ );
+});
+
+const requireNutritionFactStyle = ({}: Branding) =>
+ StyleSheet.create({
+ card: {
+ marginHorizontal: 16,
+ marginVertical: 16,
+ padding: 16,
+ },
+ title: {
+ marginBottom: 16,
+ },
+ });
diff --git a/src/screens/index.tsx b/src/screens/index.tsx
index a3b32e3..a296d0d 100644
--- a/src/screens/index.tsx
+++ b/src/screens/index.tsx
@@ -21,3 +21,5 @@ export * from './voiceLogging';
export * from './takePicture';
export * from './advisor';
export * from './imagePicker';
+export * from './foodCreator';
+export * from './myFoods';
diff --git a/src/screens/myFoods/MyFoodsScreen.styles.ts b/src/screens/myFoods/MyFoodsScreen.styles.ts
new file mode 100644
index 0000000..299e27b
--- /dev/null
+++ b/src/screens/myFoods/MyFoodsScreen.styles.ts
@@ -0,0 +1,22 @@
+import { StyleSheet } from 'react-native';
+import { getStatusBarHeight } from 'react-native-status-bar-height';
+import type { Branding } from '../../contexts';
+
+export const myFoodScreenStyle = ({ searchBody }: Branding) =>
+ StyleSheet.create({
+ statusBarLayout: {
+ height: getStatusBarHeight(),
+ backgroundColor: searchBody,
+ },
+ body: {
+ backgroundColor: searchBody,
+ flex: 1,
+ },
+ container: {
+ flex: 1,
+ },
+ button: {
+ marginVertical: 24,
+ marginHorizontal: 16,
+ },
+ });
diff --git a/src/screens/myFoods/MyFoodsScreen.tsx b/src/screens/myFoods/MyFoodsScreen.tsx
new file mode 100644
index 0000000..306a2af
--- /dev/null
+++ b/src/screens/myFoods/MyFoodsScreen.tsx
@@ -0,0 +1,47 @@
+import { View } from 'react-native';
+
+import React from 'react';
+import { myFoodScreenStyle } from './MyFoodsScreen.styles';
+import { useMyFoodScreen } from './useMyFoodScreen';
+import { BackNavigation, BasicButton, TabBar } from '../../components';
+import { useNavigation } from '@react-navigation/native';
+import type { StackNavigationProp } from '@react-navigation/stack';
+import type { ParamList } from '../../navigaitons';
+import { useSharedValue } from 'react-native-reanimated';
+
+type ScreenNavigationProps = StackNavigationProp;
+
+const TabList = ['Custom Foods', 'Recipe'];
+
+export const MyFoodsScreen = () => {
+ const { branding } = useMyFoodScreen();
+ const navigation = useNavigation();
+ const tab = useSharedValue(TabList[0]);
+
+ const styles = myFoodScreenStyle(branding);
+
+ const renderTab = () => {
+ return (
+ {
+ tab.value = value;
+ }}
+ />
+ );
+ };
+
+ return (
+
+
+
+ {
+ navigation.navigate('FoodCreatorScreen', {});
+ }}
+ />
+
+ );
+};
diff --git a/src/screens/myFoods/index.tsx b/src/screens/myFoods/index.tsx
new file mode 100644
index 0000000..25009ff
--- /dev/null
+++ b/src/screens/myFoods/index.tsx
@@ -0,0 +1 @@
+export * from './MyFoodsScreen';
diff --git a/src/screens/myFoods/useMyFoodScreen.ts b/src/screens/myFoods/useMyFoodScreen.ts
new file mode 100644
index 0000000..d4cb24d
--- /dev/null
+++ b/src/screens/myFoods/useMyFoodScreen.ts
@@ -0,0 +1,9 @@
+import { useBranding } from '../../contexts';
+
+export const useMyFoodScreen = () => {
+ const branding = useBranding();
+
+ return {
+ branding,
+ };
+};