From 713fd918a4fbb9090a76fbe88ba84a4f80bb03ac Mon Sep 17 00:00:00 2001 From: joshslee Date: Thu, 10 Dec 2020 14:08:10 -0800 Subject: [PATCH 01/10] update search empty state --- components/Navbar.js | 2 +- components/{ => Search}/Search.js | 45 +++++++++++++++---------- components/{ => Search}/SearchEntry.js | 4 +-- components/modal/UploadPaperModal.js | 2 -- static/icons/search-empty.png | Bin 0 -> 20631 bytes 5 files changed, 30 insertions(+), 23 deletions(-) rename components/{ => Search}/Search.js (93%) rename components/{ => Search}/SearchEntry.js (99%) create mode 100644 static/icons/search-empty.png diff --git a/components/Navbar.js b/components/Navbar.js index 6c8b3bb05d..19b1118fa6 100644 --- a/components/Navbar.js +++ b/components/Navbar.js @@ -23,7 +23,7 @@ import InviteToHubModal from "../components/modal/InviteToHubModal"; import LoginModal from "../components/modal/LoginModal"; import PermissionNotificationWrapper from "./PermissionNotificationWrapper"; import Reputation from "./Reputation"; -import Search from "./Search"; +import Search from "./Search/Search"; import TransactionModal from "../components/modal/TransactionModal"; import UploadPaperModal from "../components/modal/UploadPaperModal"; import Notification from "./Notifications/Notification"; diff --git a/components/Search.js b/components/Search/Search.js similarity index 93% rename from components/Search.js rename to components/Search/Search.js index 9bb5c23f52..1281b7858c 100644 --- a/components/Search.js +++ b/components/Search/Search.js @@ -4,7 +4,7 @@ import ReactPlaceholder from "react-placeholder"; import InfiniteScroll from "react-infinite-scroller"; import SearchEntry from "./SearchEntry"; -import HubSearchResult from "./HubSearchResult"; +import HubSearchResult from "../HubSearchResult"; import Loader from "~/components/Loader/Loader"; // Config @@ -134,10 +134,13 @@ export default class Search extends Component { if (results.length === 0 || universityCount === results.length) { return (
-

+

We can't find what you're looking for! Please try another search. -

- + +
); } @@ -147,22 +150,26 @@ export default class Search extends Component { getResultComponent = (result, index, firstOfItsType) => { const indexName = result.meta.index; - switch (indexName) { - // case "author": - // return ( - // - // ); + case "author": + return ( + + ); case "crossref_paper": case "paper": + const hit = { + ...result, + __highlightResult: result.meta._highlightResult, + }; + return ( +bQIrlvGiP6{9V7zeS0tf_R)O@C92m(=&Kp<)Z`ttw; ze#`d=_{Z?}nYlLzbXDl=k4n=}@Gk(Q@;1~^0aXoiZ2=FoPRh@fL7;E(7mr_^1A+8K zHPw`j1E}^E7*lelV4Fv$u!;(2278NG_e+8WYy7{bZomKeXQ7aN6hX}gZKr| zRC$9J1F%in7!xhOjDEx|5X(WicLUVjVpRs@jpq?KF_}#_HVa zI~FD;!?52$il*m5xR3dCq?a_79qRJJ){*Tn!=c0-Hx5}6521LV%}w#(mavyJ8@TG6=& z+m%s729QroEDw5Yu3`PYM!7tkm|A8%^)CM7NQjm5^Oj;P>I7zRY+^LA5p!-zK2-b( zb-wVeHUCD0C0oye{OSFj=~VC|{zYUxMi}E33cJY^AJq=$mEZ=%C^1}iuA7W1Xa>yHCe>5tMbw@JQaCNY3SL-XlcA6d$Cj07od z#Sn}LHf`44dI~ylgyKaBwA)`%|SUdyO#N@Y!TrE$4;Sot|?b89sEF_-%OO z;E|FpQ$0#FbubB$#3^)B3&*`d9CZy*2)zW%@VM=)c=*`K817L96|@kj+HvCmWkdmp z?^%lF!87)958xxSop0fsJ2%x#nDf~HPKLv&wwZ<&+Tur}C*S+Yg1py+lz6XCsAF{s zch`!G)y0jyneRN$tU!l08^W2j@z^{wNh;Rf-Gz{Q;ty|GYs?CBvr~ndBk3rFJxKA1 zo>$MVp<@gF-zP=7)ba?g4XOJA2j47xy5+8Cyt!h}TM(}n^P?6PcLa5m7$9G;M`B1v_SkmQ@mLPHi+HaS3$#n9pX{O ztNxSm1FzT)Rv#$!TA~h+M+z<1GmnWOZ%;py($m3H%pc!=r}xx%g|?w7rwLvABaY== z#d07g#(E!&$-ka%-Ss?Dzq(ywC@n&3P} zPAPl6Lm5w9_bTF7k0M=H`hd3{3t1Cred2Ako8(|ljXR9%5DFoo*}QOS-`rM0nw~AU zY*mXZy4jQwF5iJ~@_2c3mx_W|ykX}k8sLeN;}3GBDmRFMxS@eH?+|j{I+`=RLBaTu zgq?>jPuBG;g~yZzhvW%cYrmepsK_{KTETSeQ`F~{a$RRc2?Yj{Q*~v=UPD~ z&qu*5po}T}I6^*v!?)Mc@A_$&@Cjg-ca2~z7J6%uTy52-e{ceun9qUs&7w+*x&cLC zJLomzxL{3C{_`1STSf7oWMRux~J8zKND zqkpyfuFK*qCtoEVe#(>#DQL;&`Oal6wh)4Il;04U6}XQb%R?xOhs-a=>Q$^%z_e~a zXXiC!q0S%0%j7+?LYtzq%C~!%dA`btfcUIwVO)fDj@QJUQ#_-qAjrrO-0>5oFkK}E z_D!kP^GcrnWo|S9sVDuMt@NR?pGeXs9$mj4ZwGMLanf-da;imr?|~Ee)OFyNo?>lK z4uaxl-n37G>h#W+{1qH_5!vSV{eAp!_X;Sp@r^pTGLQ`yRl+CJD2ZrNSjpq(0G}n72kel&cpZY#V zn6EfJ0z(4G|5R<*^BSQGrGqGnA7MXi*Zdw@@$r{|q~t2{d-v{>X>D~>trobNQQ7u~DC9HZlDIO2o{SkHZzWJB0+@3n;l zKKx4gyG_g*I6~A;9rGejS!2Fs-OG|nt7Sd#ek19*G-@Zs5IVW@Vr)}yz;7!lj~|Q} z5sam7u@4^0e$|+F$$KUL?_Qg*ZHlM?#EmkyV<*K)6M8Ch9^tq4 zZv0%EFvbbcU-c<><;dr8O!q?xinit@c>jlukDuKOl5yPaJ4~;b?SD#Z6Bl@X*1^3w zs?)yfQ1sU{B#1a6Pni@c`bd0zW-xB-e#zv=@k@5|BML$mW(S|@R6l;2wg&+T!T*lI zYLX|{D9!lZpZpF@%wyjZZf)4IgX?ki#%7)HKfTZBE$w5TI8M4ut|3`@Y4ZnRC!;qz zv%dHs6l8E0J4Vg4?aGbCU8Sa*M&E12p*;V-bZ7!S%k@s*_pWs)m#8gWea93yKv*Si z9|>U6Q~Lg>%iUVT=vyc@b*cTjES!hgq2|E+&8>V<>tSd5*e`85Ws8Z*@Qv;$n0G>8 zqnwfyGD~Jy3jSRnyKo8R%z>o|e0L)=WY1&nDRx*#cOS@SCJyC8Y+;$;pdwLuuZt)z zn8B!r+UAt1V~Ie_YA}`PYu(WqZ*9FFbx`apW9(jsjf71gEZ3h}Q9!FdF}H3C$#^2) zI5)%mQSczjmy*5s$0cp22YPe^JA!OT@2R%7d<;GDD#}kToPV3~k-2#APYJZCEuYy) zQ8mEkvxV?=<14aXdyL7NT+`lOUbSyj+BVmHdOTZC*qqaMxl8D4)kR90(yK(%&ndaA zZMJXrl1h+E;R)|hjkB}sWE-aS*$M>*x&uh5iFrHp!iCpAk+<&i4rNcE5EtaD)!xA4 z78It%XM6Csemxl*5>{oWO1R*C2Lk6f<$pudly^c<#<#{MjKv1uSC9Gk#s+Mwump1K zL(*yW1KMrl$vVe}+Mq=oDZjAV{ej^5fYq)}KG2<()~gq(o-=EE-f;RS6G4%XSiI4V zLR!~id~K1uo;J0%-*)9nxUj+%MDx2=rF>5SUm@+?+cR5oE2Tm;tVmV_)_y?KFT6S8-y zVdflM#7Sc1U&xDiW~$xC;B!`oSXC4<$l!IqDVC!;);%q&0!iMfpz2DV*rUN-jto-l zI2n^#F&7g0E!_z@-xA#u?}F-Y*$)?Z>n;f=b_ZYK zfWG8k$=BGu^f+s#bR8F@U~7r?_N?9zFhH2l?HpUoZffZX`*xml!H#XICr*rBfnv~^2zf)l8XZjq=PyC+(2^DH8b2V`T?SnSMK$&%Do5Zo6H|%-aui6-`qs}jBH+QtqNrx zy~aMr`(cf}a|35Z?=(#pV~-F)rRSJe)TgAt@5t2P+b1PeJd45f62scW>D>dEI!I7= zMw!=FebIZABQ2*WylgAv(FkA176N@8i?sWx&@>B$=lF}`r;Og`ogQhG>Zwghoi2;b z^a|+lqPM^8k+IWl;;^=^%%j;F0NMDg5mD=^SeX0h)9Zv%J-^czDhdUER98&Mr6C%) z@@#cI%vI}TtFo~)52Dj)~1z)!YuuVPua0rFGi-$jqztmwIa9Xal z!*5`U-J{!S9V;h=q|esHdyn2NdF?sRABxH`Z#_MZsK_*nJ4xAE*9}lajM;hELY9@4 zV>4ZBw~8#C=7~P8FGlo`cpt&3cI!y+BG{JnFE{;A0=*1XQ+76&0I>=yZpsTuj@2&J z`Ela>802?lx1g}_Z?Pq0oqv(|XcTD_!<~RZ)>;uxJ1vV3_EHaamz$nl^XOP^{mf%) zL*DXdt~*FxfqDm zL3cD{KdyrG&9YuTp$VzWM5ilC=KtIX@{MhhYT#vKWBKQB*+lbjS}2@0R1on z#B8ARlZ705Z=4cu^H?#O+Nujmi9(oR{q&j0SoBm>$VPO~)@e(xY&%E8lf~DYW4Lh| zP4D47U)8GJRPo;kNLxJ*ZJPwxj1l51Jtaq~dELx!>Bzj>(9XL0Lo#>^o0oXMS?OmE z8?H?_g)(oODE_-5_)AX(^frNvAjxkHOr=v~sYssP-C(WhoF{==B&AUrhKVBuh)`Sc zML!0hdZJu}l3}~VO5#7ti^ixtB>A8+$*+e2!pA0ap5lZtVmE)y<)ICm%d6oPT!Y&N zjqoyzR%3X~6*ehPMskP){Wd%R{@N~S8F4_D6fcWCl4pR#;heEJVMM8SJhLS^R&y~{sTP;)-B z9US?#wn4a_k?ZlUcS(@y|qy{bqrLM%;(TijDfQJ)yc3ZRPIFCBrt<#1)b|pyR&d`-BB9N+Bc)~6(@F0+u1q} zins4~q2w%fYqD2`y}f?6w?FXxOq@f46@$B=i$N#G!`b2fuL-N#v!^TCs6HI~{SINI z8N1O?og%Y+PmKlW*VwJD;@blu{!)eqR^S(S3Z zCnN1;agK|~@9n{DeHfsY!L%ceu3@}4vq#GJj>g95EEiu>T3wm6X-`}hC(18CpuIH@ zexJyNMr_?duQo=6;Pp;qnU>U_#Z}#gf9Yyz7t!@BzP@rR2T_wYs|1F&Y1~>9o>L9p zn>)w|G)bZVT|(B-Ip+p0(S8?#_4V+lt^KlNDYwgd0$%v)pHXqb6O*uzzSw#q9tIv{ zZ6T!fHYD8^a?xr#Nb{g`dLdZSb zykppS{#N@QsR*z95p}Cm|Nj{n(H*E?QOr^*Vk9baOBAlZn)~= zQ$G!9!tHyF$x+?bj&M`@@~Zm8A9KpQ5*LIWVGgxNAKB;{&BkZfq}OyJ*$=MIr(-JT zn35Qea;E(*_MBe53hEU$^@p@gnbtnWGsyJEj>MlWm)w{xAg-P#^D4^k~nR9<$ zMNxz}cv7;fDfr^3W4AZiHKt#-9~W?|HE`Fr@1X1|_6rXOEo=RA{t@DbOtFdL^G%$m z0}=xrN548;xOALT)XcUK#&!0EkvJEr7x z;ih=AgM3c&0yN_`Crt}H5TmM@$WaCcV^hL$xM*Y z_U=Q4SYYn7V_>UT#rEKZGWYVkT7!RrJAGqjt51hUPAtKH`*-ktlVjiXkSffb;BuFF@kFVdUn%fLsO8P3pXN8?+1ezk z8&GUrdj4(pc^H<162lg^lWcaONQ;3bPiClPHxbG%7K*#}1Z}B649&V%eM@I4UU~>N z<;83p?3m*o70O&Q_xZBueueNp4|H{MkefpbDRPost4+vNSbjX25$m~-5mD3R#8B0Y z;|?~%iO$n7tXhsX)l-M~X?6$>eYXV@4&q!0#f?{?;eTkGlPUtODO)RD+VfSU#q84N z=MC~=#`6Yu<^Pqx)?FuNoLa1ZTLuqo>LRqor%yg*NmkOfP2y)}WMIP)LAx`*l356i zr+N8wwI30WbBb__`{L^d2MP6i@wQ*1*5dW7#m&&`D;G-$SD$J$`I07q&L8}fA+x5+ z?}{Tmk0X;7dy`{v-?{-}QQl$wVVMg7Ekz&N6+Kbl*!BHa>B-tJE8SUD|87D&uffDY zhZwo>k6D2F`SrblxZM|r*gJk4B4WSx-<@tao&MxZ<&^R}3SM1Lj{!eomrr;^D?i-4 zUEby&>nE(Xbxzxe6Gsz8Y2WhS43;?oO0!uTymiQt!_h~*5Ca?O8`YvZ^Lx;<&Zbfp ze|7!Lt(IaZ?;ZzR53MTqc6C!+z@Q!BXO{Iv80vE)2fR^R1>tub;lH|YSHqTAvGqiB zbAIvNLaE~GU_BadpYe$sQ z)8>}?LidZ`Pwg!CVVFvBLV|xg46n=ZcKr2k-5fa~z4pIEo7B_Z2|7d|)^FsvJsiU* z5m#$M`IlU}ew1#Lru-%`>bbh@Wl)T=dY-}KHSENIFq!e_Dks4|m$))cCisySMoxp& z(+b5$>7UP7vV~D& zN8Ta6>}b%GXi(#H{#VHAy9a!_3p5O>qfYw!xC8m%$e@Ar3#TIUY20#7i@^n3{#Z$` zE%RF24}0!J=t)r1ZsU)rCMyBTc>N4j46y2he1Mb9x#?05^4=!bc-;i%s&k2JsbRaD z;vxqUsaNS8>u`dy1@Q&b zlP=ZRxpy)hT_x{$1Rccl*3yB}gTEeln(lC!#1z0TpGQpPjGao*Dz(0!AB-EFwM2JK zwG|L_S^6_nU%<$pq#WJvJw1BzTB&8 zf7AKrm_zhViTFf+L`!AtL&7lajI8}_cz37w=}txMn-W92;Y8%O z(uOwH-VR;(t*T(sKFx?*>%+9oJE4L%(MG-Evl_mKRk;kaSv#%sX%@BMzV+fl>wl@{ zjn%Yx1cfCEM)Jd0n587ov`dX^-?K8CPc5s86s3A`qjcY>tVM!XOk%A;c5Z;`Zd;d! zjW6X;d~%TZwGoE-{oJ>XjPq>m2=0@;s8Z06fvrq9P%T{yS8#A7Psg#|uhT&mrWJz{dM8`wws^89 z6#0n@X1%iHxtY-wbqD&84|M56zFth_=VquVQ~J-}u)yp3c%Z!%_)9-gS;RW?l)qGA ziFoN5*Bw&zMzEkpj&lr~hIFF;N0779XlVq)k&RjVV7~YUseXj{Ge)QidrN&>h;~#n4b#E!d02VkcL}- z&>a+B>2X2!i7xtkYEXxE14~$dcE<6m@lVyzr8>YzHj@vz)AlR}iLv`P4>L$E{5-;Y zvYxtPPDeb~Sd{bLdX{g9nH}c|fh+&Mqq}RT<=>IA=sAnrv%D~TScUx}x5Jg*yn>Uz z_at0ldBt$Zl0amg)ZE%G=#PN!JL#>>Tn$7UmpYKI!dIJoLi#GurlqGcym^<~xw~I} zc$nZr3kydOWAsvmY|N_X<`0;_K?nQt$~uqhreJ`~j=%rto3eSoxMhzVk0W3el$(y}!`n{mfz-WCW z63Ow`s6SQxox-Q0x7E$Kn=vX}dUO6O73WRl?}5Y{G#`|#AVbV?HuY`z3gOd$^}1}# zoR~s3<9^I+`u-cEsk^teb<{578nfcDs32LPPwsW|;vkaBsBnsPHePiYb)X<;he0kbDuexmzzGk@0S9VFj97&!3@?5H+B z4kiyNo+=Koh82s>Hx26cVPWd@z0?FWn^v5K1jDO}BTr=~i*zCTf7}Um_r9!AQ3TLz zWsd?!o^fr=`D>UFddjlmlZOb6$~_G7-%n(oHck3IuVghk2tBFs$x}L7HWCt()(nsI z11Ei`qcX`bw{d$^T%2M#-alJtWs+k6=@Ktkl<|&<=-wZi=a-HtvKI{54kE8L-ULAa znIzoRHP>W4^zVC~WJSR(2+jC5W}F({nta}zmzH!Fbv5$0`lAx{tkao4cRMP+sZ@EH zJ-dd?I!zRua?7?>2jL>}_4uH33fGnMg8hzQ7GCQFtp#6vG)%^EXyd5xWU0OLpv4H2 z6o(IFEmphKYfkI#rxel~M>}`8Rx14bPrA^4y^dt$qLuZ+J)TM`NlLBuU%#W@zPPI; zCbP%bRGlPpE!eG+G?E*fPP@e%$s{a;hDUmQ{W8RaW@Lv^JHs`MSw9zM!c3eXN5u@i zV}g+s>8V!p@R=`aVAHL+nbN+IjZXvnKZ*9_K|L*&B%7h8QAax5CxC3WgBWR;o65Ho zS;TP*QQ_ZKHqv+R)FAPiEaz@*cUM5*#^BYMi7D3Oe5CQAMoZPV2MH8XvCa?6SS@|a z+bkTS3&IJx{1OaVvHodQB73{B+DlDoD-AAgQ;w%*-AjvG=VXLKJY7Cw$oTn4=37<% zNP#-;`qMdCvkReBmvIa!fASTJfEQqn7gvNzyn56mZ49d(mUuy2zWj9*>vag`+;5rS z`16LhZ-bR1em$T7Gu@hbVNa{K&zt-x(S`mP;{Z)ehNg z-`WX=jsIE@?=}&q;FOr@NouvqrEy8Gha7xNTdHD1jM(dafqEAP>mqLNp|i#b z2iF~J{-oC*Wmt>7L1#vJ-|5g0F3>LcxKO>ggj8>Qbl&pqv)}8I)|uQ<17ULc+JMAH zBZW@_ej4->Wl@(Uf_G;Y15t4Y0pjcnADv3Ry0g*WsM}|I=3IK`8G^0iRX7Q=-W<5V zJa3rZn$R@-sq@_Exp0Lr<6$_%gCF}di+LgDq{K$Vkzd{FTPmNhe7*c%*{bZyj=w1+ z8>h)q2c=;ZbSYh{#;CBquTM|P^v?rWZtH!Qx!$+{W^K~8yRog z-_eS;8xNwd<|gBm`~lfbFkgJobNku_e%#3|215tY-3_MDH)H z%TYGxt%37K>@Tm`^!T2ipZu&1bOR*SIujYEp8Jo7QHzGgDhPQowrD13`gJIX^MkiC zPsEqE(pPWoTzJjrMhnxD!#?ykZ9sEVs|}jsUKQr?yx>yKyE)>4bZt8NW_FoRi{A|Q z)Ep!lov)YqtMB-+(d-OubhIV2JUXsKSi$59h#Sagc6!U3+b*19{?Q*Qh1>#DfzYc;OeE35kMOOwc|r_dQO*y$j|)(@aD5B zQP8mRsFM0PnYa%unc)^InldNW*)VCc~<4R-sexs#DzqfS%-PgzJZzC|jQtC@yXF z?E%l(1&CM7i)wQki^ihzQVKUg!+hvv{@wd!B2e@u5a6$XoLF#A-qrN*z1AOs=0pPM z->8n-G5zGB#6DLa>4Uyx3g_A6+Z{{KFvjJy({0>Dk0mlfBe(N8JSK(rEuRE34=Rt^ zDeH`?>fHpS(%A>iXH-}8MJNdXD~iy^~czi!7n zHnNZ{DrRNo#Yg15^;;F>OR)ybFm0OybtjTPx z0cP)sVXP4`G?jzzmfKRcncbNu`S?_cYGI5EW5ZvJR;7_98H|2(EF&2CuBU+R`{6^{ z+SWF3esKGX1-y*lz>_@PSl2s551QcFbq?)IlLRo*y8(1vV^rWiiriJ&Z&41nkhL7F zb<Ga2%6ts2E&Z zxqfs_qLT*Arp)|8t0L*lAlC76|4uQEtjLI;_~S%SR3^eLjqCaotvhj+FK8TFkGGwW*#v3 zsEpFoaZUZM6!MSi`jff*7$4bm$u?l;eYtHUMq|O5@fmgP$Gl5Q*&p?SNH46&TX-GS zF5m1a+0y0o`VegH@kQzgGCEAUewtZJXSU>M`jw1Iu%|_7WgPW2T5Y0IcCqN9B}dz4 zAN&4;z^F@o>>sg+rVhh^=O;3!752GW=52!a==-T(e*UNz3>lw{aEJ+Gml5XJ!LF6+ zMB6Tlr~9KFo9E+wy;LOEHq+#VGfQ#5Ph9t7_qH#w+`0pK$+Oqr*`HV&(G_`gP9{Xx z*JIJ907||K2|Kcxk$k%L&#JMs09_TL%?z`OS%+|nNTZv7{3FZuFj{ZW8*Fy91f(~`Gou@mWIluO*1aT4$M8J(vDLJbnn z(Dk-&^=Zz_cBr>_%)0HTsSos`aqkyG-s!SAaTDQs%dCF)Dl|}`U zacgVOtk;-~PTVCWhWMrL$ZMDaZ$VApp{Dk2sNSC6^X=s_`mty*L#kmo^wiv%s_(Gr z=$(Jvo6nH87uHgSPP{HGEF2dICuW37X!p;m26p@jaNV%jyV3eh8#Jh_9M&3#yCA1$BaZ({e}KJ2P>Q5GGLn-U>@eKyj= zACr_VZ){a>H>BM*Yb!Fw0%=FyP-3%nUZ^Ozdv~JrNdGfq;5s^+KJeu$U_|eBgUy2q zUlECqz^$nHgfYs@A9Y!7AOrH0mp*KiQna08S`Rd7pKkku)%7Sl8O*h^p%D!u$P|BO z?ZYh*rwiJFmYvWT%12!uqLb5OyGR~f3=Xye`Mi$>FfN zST+Z$W3npZtq~iI#!NEQ;ebH#H$K%_KCqb*J^+Y2R6Ihioveifq_)G+BfVQtS|zjQ zc%ICA6m*fDRypA1#7i*6ljH-y6&G_jcDY4_WIxLUEP9-kG(4I2DYmDsng>TwNit71 zdtJdf)n$t6QDx=uk zL0m0dY_NL$Ba-Y5j)tt@g(`{f-z4@wjN0d92VK00PBcfEG~gkco7f%h88PRQ*o{ts zTXIijOehd%#GCfDRu8zo$mC34e>)MmP3)QfY&|#wAq85;WIykyu9cnvON}KRdFgY8s-$K-6zxeT37yFBe>MfA) zd#^#!@MW{n`3n?s>F{|nQIF2JL1I|+xkm^lwMpR^zKN-%50$2e@VUB~fK^&HRRiJr zQm^*UwK5WBwplqo2{bkZzXN5w%cpzrO#Wc5MftR7*65@uXFvP3A(z|8Q_kKm(1I&O!hcdZHMBfX|VUGIeJCfcK5{) zrNV3QM3sWiTMW_PgJ|VLjqeYntUurJ=rA~|8$eq{3kxOVFT$&LX^vG#X`U4&&Y~cE zSRmp$ecI92{Po=p3^Nb?aCYU_S!0nu`kcm=yy&vP4lqH(tQz4y_{pBVE8-5*6n6ex z@4axIzlp5ru;pfh+B)2R{FQUPfSLW(^j3Vqe(swpSibf{K3z~@3J+UX(jL6SaRCmX zO1>6$@$kDiBQyJU)H%<`lDU=D8z_i9BfI?4JCy>1t6dAd`T`@Y3J-wV>^T2Txpp)h zH!a}$qLuD^S1oKDJ?B&PEleoL{v5mfy?m?}9v)6>p#E$1rZzp~rBamu?-jvV?szCZ zYhH`m9!O)CzKhS#Pm3uZtl{MU2MC=Y^r-{1h3C_qUr9R`QzE(QnHUV*S_T=hdt4Tr zr3W7UXyr#s9fitb!`14v53{FHDx0*1K#n1$+#P)DA}hbYjDi%iD>LKz#&R0dG>=TiyW(832UJvRN()2sB)y0?3)XDPD2mlLwHUnT6mY&~4yFGfaQ(_J#51 zZEag{jTMm-K0xCyQqHvX$1=X_CYtKyZ9tYk z=pp&M7B1nU1x-9L>Z3GD9ByEWKmS2%BzTv6dT|Dgaqrze; zCVA!+y#ZE&=YVC}J2c^gwX2@hHr|$+p&0_`u;AOz)$@F%Vez2*8lyB6mo<9QhoUAP z%`--U3$Nu24@P$2PIBU}0Xrg1%6Y6zJB zXg&|UDkcQkxhxFW0bj{`gXRoCAzgq%E=4C3(V@Wa^Z)mE7hxJ~0Ua=T73ca@u=tJ_Q~o0dJuL9#sCn->-KAtf+1RrHH~3u%tBhey;+~8MVsiJ4FZpRDgcHz00uU*E3mOkOxtnO zwaNdQ=>bbPRC5kTshO&e#wQl2=U^}l2DDuogH8-|iL+=?(F~_1H zmm&e~jp4e#39W-ozZvsxe5oKNn*UrJ4zR)ju_NdUJKe$ddlHF2EZ?TveDbqI3Vjif zgO0N_-}Q8F2mEn7fajUE^F(UXr;DQkz{Z(gLRh+k!Mfa)V`hUXvQi&6Zo0?}V6?8a z2#~Qw`Rkr|qyP5Cokd#HUdb}FIvj&Ds383aMBvY&eyI3mAQ3uNR}LNaK@l$(rA!da z^=;WGhz~##^~;LsuV#3GY>waB0I}UbEJ0sYW~No%8O&=3KVhsOfyON3Juc&vKvwGA zcj{)Q{8UUZ%>M-!yW6z#EFh+}Ttt;0zcD^ozq;8dI$t}Y&;e@_JRzq!w*h1bf@MQ+qXH%4jL%x#bUzWaZ)n?~e+uAaXjnLI$0HZ#?ZZ=M~t{eJ@% zxi$Q@iK2!JL+yF-E5e z9AOP60j3vi)idNc$~>yAh#~7wkq1539)=qOL5tQS!G`2#jHenkENoI(08-tnYyWnZ zI7|?jlp}wVCS+#K z-GeXI6Vl+}K%S)jau43NQfm^524VB)18S&y-2>An!^s5d8SA1mn)g zXTF5M-v%s!{=F>%heZklOkP3Yw}4RpA7l?G0as3x!#e8Se*3J$SHq3}lSfHi(5SOu z^gA2fs{7)9^O6<|niRMJ)v0~5mq9xmPS#*fkM&H2U5xQz00}|>2?gaG+dD!aWBiZ5 z|0@Xi#?GJyj17j=OD1@(!HeOndni>ftoAYvq_Xs31p0 zN~jqxRFL?}r&RHB#A#s`fOoZ%;WkV}g~AzLRsiqq(5<(cb<#`u`4!9n_Y6S!LvJE) zE1~thZ2O%Zbf?q7qmO_>5SVb0C#L;V*#T^Wi*7WjcrFADnMWc4Cshr)lQH%4}LHK(Y*gr1&oqD^Oth5L@*)W7;432Y`XB0)>Q1 z$%~CE*BPKKX5Mwy2>|W?fV{qZ6aDe0Pk{)3VFmNm|AFXphqp%OFO_f8sDoi20K0tl zIQ>^Fwcc>*6zhWu(swwQ%as>D7>ECoH$%@w|X&H4&dBE@Y*67pQ$V z#ozkCbA|RjigXP~IT6ECt%8?5y*_#_|I7wrEiaJ8SXkkYOol~E3SA!t)yf#G{>%=& zeY7^^>Jhiw#|1PP!xEmTjOMZLMJQE$W6Vj)*%;5x08A?3NtNno(=6BWBS`?x0}y>C z*s<7G(tF!S5Ch<=F5YHGu>7j001$1WBLF3wfnrlt-=Eh$ybKg$H6ph!48MK-_Q^N% zDesT&HE4MJ4M5X3?vU<6-A$_1AF2tzz)foaiAJSRT_q30<781@*!BHk6i>#>M;@b- z+XYWglEa??<>$=;-=NQj_ijjCnFj;_6iyNEjfmcA(vO@J#M>FpA@G-hLM%aK=zC6! z&wX8TBVf`%D7pc#o^@zk<9R>GC8I*Y64)Q8-y@>(^Mtnxq_OK>_-tBbV4giNkJ=(m zCJypuIEe6*6E3OhL#+XZWdPno+i8sD?tTRfJPZV+K!w2bpZWTuFBgxMb_CC>dT-c0 z@_2!UGXp_7LP<8K86zkT009|~j#~0k1G=+cdGx3>7rve9<=k`;kRtz?w`PorTo}Gw z3Q!^M`g$UvWV~-Hku#;8_ZZ9L3V(CC=Gu!wxF)8+Y{hI zw+g8WAP2Tn2IzQeC4v@>1n8|R^1NQimbE9kOg;;7`PakR?yU>1XtJpKsMuZo4&+=7 zz;B+l$egevy5IcyJ8FrM0L(BfHn1Zg#aO3j$?pJ%C4K}ndIdL420kxj`DX7ccu!6E z5%3rRVEj=|R{tPaUJ}bMvs}=G;sr#`6druJvow+okBQ=!DFA?Uz!tqz7xDNcz9D`Y zlCm;A8qRwKNPceK&R<1dq_~u&Cfz%WZuRr;0duE1GmO%lHD4iMA7k7!Gw{VDwQ2Qc zT)2991nS&(mRx|$MMXeVIMxT;Udmh+GuG7wCnb1Hqmf@>@X&&(}@qnKiW~iREbv>^r@L|B;b z%nD=X0lXEdsvoI|(-Odj;px5Q-~w&5PrGjOg18%QS^}sWslT+uA@5e{>ZyaDZ{G03 zWV{Pp&Tk6749NI}z81TX`tA?8xxJsorp!}VuE8BZb}VdLJGud9je#LWv*#>K-6c}M z`w^wlYZ()8;}fV?L#rmsRTGg(=?p2LOHZrgOhUIcNWY)D=KZ%*9ZYEfBI38Pw>Qdz z47<3F^~Wp~fmwWyeROSa-39=o@U`*mI>1KX>ipVCJ5#0Mkn|ytW5)a-JJ|p{fEJdX zl3WEO%EpCH?*a>e0^uA$?4kbc4p5o&eLcbjl|oZ+>%p{V-xENmLB($_?W^QiEucJl zezez!9OZr`PO|}O5^%SBE4%#C25styX!;DW1$+xV@=|!iS;$0L1ZYO2F>e5|HuNmk zhF9HA&1E{b*UzN<;sI<6IGXZ39q;g2TzNh?ktK9IYEK;J1h)EWU%s8yC-v(+Ai_R$ z2@p|3UtCv^%*o7eLg2Mp+Gt<(t^E&LzPY2`mr%;2P?N0<{%Oa&an^WCvZn_S+oTjD z(}NYn5e(^mwZ27y0LXM)4in6en~u7hS3M)BdM3Z5jX+`?kY2bfw7a3NQ~A%f(j>Q& zyMbWxBzIs2ob~~zC%UxHZ!Abeph!y2>-{}-rbCuz^TrAvHfbzY&03Bi@W_b+vL1y< z_R~HO z58utcJ(^!v-1}p39HNMI&CJsS4$#q=ZjCcTJ*>eY;x9}SWEJWS6v*?6!W`8yw$ew( zi|D?-K|ik-042ZswtWk+-y#+{ExYyp91R?}TB3Y6>@4hkt#>*SF9AUfcTKM9-QzzJCnXc;Tq ze>iBB)1i+KP|U9V-ubqYnuw69o#~V2CY=y0qpQPvhGTJ&zV+Q;n85?U4_FkhxBu|C zJt7x!>gTvDMO;=S&tsDH79a~M1GqTz%x(&)9Ymkyj(IiGLTBFoql#0y6glL+mY00# zB(RnWoW3Px6`XkKP3K@yeDIgQNFvPYL3k_=ea^;b&%>WQ`^NnXLf6MDmiCloc~y{_ z<$L(PK29NlGi4@ERl2nOoBToN=Q_r$)qjrluhVTfUfz7R+G&f2KEu>S%b6$lK4V!prk82Lxq077a2;@?mv__^KV0S=2_nZ$6=P;xp~30{RqMdHx0GqY zf1)F3F^hYnlbs>a+>=ulk1m=Q>OS+m>Wh#hyzExn`reFiO$U%02uy_Bxei zSfSN)V2OhLoxQ9GjrA0gPFB>`Sv(Zp@gFDt{M7qgD+F8c|`x?#&78fW<&phQrfC@>Z7z1C(6Chx4uFfW>7v~Up|e@7OjTuP6{2mz8Z zcaE?lP4NuAC9eqw*>r;M&)A9W43K}AYHctoId7{7eIoIAE`2jk#^?08_PHQg{Dh)= z`d`(>>hu(w;Ip%nH+Ooz#?tPxoS4U2`l4uq+~Pn}#a)N=zn#bARqJ4*(+#O6tymzc zeYY~8l~?&USU`8nja`f%o3`12Y?@y`^7t)u{3@~2Vy8x9>dxMi^0{hZAVf`06qH1KsG*>76ewUM>>|F zp&Fyi-y>oAc3zvjRnUzk3X!QsuA|6mzE)^Lru@Nu zTj*|sF3UbPvO6l zz=kl)R=6)4iqY+6hk;-GKrUg{`-B}fK1%szEHOjv_wHL)+bRNIg(gIspUVZlN#d{J zn5Tyr-ud_~2=gwOu)C>SMP6wvQ$-nOOKHCf2xxkPF#Fjs-nYqyu+;@AGtLtEDTPe?Y$WK_6_X&@mrCLpwr)% zTT=VQ>vE9Y?Pf^{T#A8OFfvqQ|8{D>qk(elO2z+a;o1Y4?)vzcut%AaM=Gfy-j00rx=qh`%v%aT@qL7h8z{_Ty-HekIB~oH$$kr-s;t9ZCFT~l|1rDj=7t0 zU9$d(=|2wN>`6eHP7XzZ?xvNjBuZmRg|u(J$mEwqJ6igMk5j*8Vd6c-HFXGSKjO?E zhKYp1j3zm{?;XzY=o-qjWKvsyT{dv?#+ZHNRm+(f+9{mZp52lYLgQuPQ7&oB#=?Hd zR+CA-)FRsp{UqP1uKeI24!s@U1$q<|N|YTnNHj4u^_b|O2r&94li9~4hz(l{hUXa` z)WMe4>mx%mhdtl9dF~Y7y}mTk<4^`v@tCMkV=#}^`mES0FQWU2!ytq5Gm)O#IM;q7FysRI9BZr_)erhcG^a$~h0Yfep37G@H|72tzjoTnWz4qa3IXsKu$PapTE zVf_4YovCaR|5GGt$Mh@BfsK@0y|BQz!Sy*B=*X|UHeZt$BdbhD*l5gkZ0e<38N-bV z9r7Njd&iEC)u%&>RfkaqiNAQczRYK41wJoL5sMkU!_CwUO^-3vX&~A?i>a9=&zc_2iCKq_wAy*+ttmxd5aj9NH>v>+=4;UEuVC-miHi>c=;~jz z%c=f765&6-=kjZxaR$O|n==5{1ZC{*j~gy7r#GuV zD|KQ=rp~nFLhgMLtQy|><(v78@+p9&PVFa}>2N3hZhNPBZUb26vjD7v5AF$n((|a6 z61R2dNve8|w4>_(30;~Pu+-Oo8+7BH_M=Kk13i5vjnK|ET_>}r7GzcI=w}SWvaXPfK1vQ* zV`VwRSlkJ*`9}pNGNwz>cb~R|ELA{+hU*umaFN9UxL*B#%4VJe^_ceDYUjng{fKSn za-F;`9qWv04WC*_?F)2We#3v&quo4UN_1X%P3tu-uD){lAzFm`Wx$C_>+Q7tsE}Q1 z-Ei3FfOZC}`=41gEAsg!Q7z2TS>85n#VldgPz0SM)R%}3`MlwAN|jgdhY_^rlqfLP z5*ZDf?_|$8OCyP*@^^9!h{;xzr+|;=YglG8|*`fBH0P4N}P9OCbJul8(7$?$SCj480c2u z-*@l8qMvLP<5WWRGJ%&V_w|O;?t2 zGAt$f@brX7!;Lj39!`u%W|h7!#Qx+^QOxga3Si52Ue)@`L0UkbelY#ctPSx(^V~T< z|H>RdLX_cSJ*2ZDrDzCuk1No42_v-+-Ipn{wDk|~u3~?)chL4fdJg;+%jQR|y5B7{ z?FN8>sl2+`=X*BSQ%+*z8%s8!V9(?kwo4D$nJ}p!D>Sb_$*$g|?$5AGl^#!8%E0o^ zZXO(q8D){E5ZH5yz^;1_1EG-~X%{qp8KX=GPL20n6I0($>y^%>o-fYF;Ak>(_DU07 zJ+ySTwr9`EhvmVNPyxZL0jDC%$+36~t)vnOSoOl(34j+hdJ(?dyTR4(;eW0uU$b4) z<-JZ(4l^%@nJ86`9+`Ye(f`(VtL4DyQ0XOuyY-4<2SK*z!fnASM{vX0_PX;?AIH(r zmh|187Y0QH>{zi@Cx&1fOH(`jqkBEtpXa($wYO8WkPb~ji@{MX8+=VbE`wtPMxa$g4B}^GFcH;{`nS56gA2=(sdd)27hqH$TDm-RF2vQ$V^--!gK zZ3Aw};B78xsfVMZ8EQn-ueLcr4Ce|3-z0{OrK_DBJ@mOKmg(3CjEMTtid&WuFZbbH z0%}9YaQvEIuew&dY~No)_s)KYGt<_1H1K`Z$Rm~?_u&h}wU#Jl3$-xTCxw*fZ3NHZ zqn+Y-r1wT+PCn@A^`DK(Pp*3xMAV7IB}np%^4zfTp+TTH;GWEuk&|+}89iE)!L_5O zykO5pa%Fqxt5iF>S6T+Q{#uqlIw2(IUbc{VHeSN0ByySDfX}~S`IRfl(L6T98(>B^4L?)D?dR{iz8c z(Kn!o)eCVa66^f~<}MZ0F(Hq=wF%^`*$vS1qeROdYZKY@V)+a}r7nYY1F4$dQ$C== zHR=9UKYede)^|DXyDf19QZg5vrg2D+v>GAwUY4;{ueZ2lXwQ|F9o7O--aR#7Dc*FG zBdnXe3j28Gy7VuKDCSxST71a1`p7n_PA|iX<>pJc* zm<5OXzOuCk?18y4yd5N(pF9G{Ta0TyE_T^lXc_??^v~vpS+{Ap!UeFXtH8#k1#!lB&xa$RodlKMA$Jcl>-S&(hY7PN8 zT4(@B%qow!Q?q3&S`uIB7+7pec?LfI=EjF+NiGQwN!XtAri2&%8?`f94~YOeXdG~B zWOTVz`A|%5lSxS6*CWTj#015)C(&|u2_pl+k~dX;ZKII^rcwY%Z(mJp+dg<^Zks^2zA)*cUdykx|4`EDpAB>`r+^ZJK!y>rwmQ43fo@}dRYkn+j3k$*>w7-BYO37J>;G| z_`jgrvvfFeEl0%Q1Xx-)9s9kg{k)|PsehJf1-=?cd@s>t7Bz*Wwlg7QsYL?}h)_w! zolsbjh=C#<(0eIG#OfuT25KUZbp&rKy?8)83~9e8j7+Ycj>O`uF)kTfb96-R7gflf zxci6;$LUnXS2;EgV@93OcL34=OJ~N*YahT18rd@brCXOgFpwixE&}!pIQf$9tp(#Z zeZ*^B)mmwx;d+r)}m*_YI)=?Uc9A{U^=bfRXGS%yqmH33J4|O?ap$4Rz``{PO zruPj8pI^Rb<49Eqi6^{^g{{WH{zgWExFzj4{bZsiH6&X*!CWu6D>j@JyH3c`8s8G; z1R7+6J?KhfrHzoe4o0FNNV%=n^FImRXC EKOB9;y8r+H literal 0 HcmV?d00001 From 82de028e9c0ace046b28d0fe87dad1824483f51f Mon Sep 17 00:00:00 2001 From: joshslee Date: Fri, 11 Dec 2020 17:21:38 -0800 Subject: [PATCH 02/10] implement ui changes for search --- components/Search/Highlight.js | 95 +++++ components/Search/NewEntry.js | 603 +++++++++++++++++++++++++++++++ components/Search/Search.js | 122 ++----- components/Search/SearchEntry.js | 437 +++++++++------------- 4 files changed, 901 insertions(+), 356 deletions(-) create mode 100644 components/Search/Highlight.js create mode 100644 components/Search/NewEntry.js diff --git a/components/Search/Highlight.js b/components/Search/Highlight.js new file mode 100644 index 0000000000..da305bb661 --- /dev/null +++ b/components/Search/Highlight.js @@ -0,0 +1,95 @@ +import React, { Fragment } from "react"; +import { connect } from "react-redux"; +import { StyleSheet, css } from "aphrodite"; + +// Config +import colors from "~/config/themes/colors"; +import icons from "../../config/themes/icons"; +import API from "~/config/api"; +import { Helpers } from "@quantfive/js-web-config"; +import { doesNotExist } from "~/config/utils"; + +const Highlight = ({ result, attribute }) => { + const { meta } = result; + const { highlight } = meta; + + const highlightSpan = formatHighlightByAttribute(); + + function formatHighlightByAttribute() { + switch (attribute) { + case "authors": + return transformAuthors(); + case "first_name": + case "last_name": + case "title": + case "abstract": + default: + return parseHighlight(); + } + } + + function parseHighlight(_text) { + if ( + doesNotExist(_text) && + (doesNotExist(highlight) || doesNotExist(highlight[attribute])) + ) + return result[attribute]; + + const text = _text ? _text : highlight[attribute][0]; + const parts = text.split(/([^<]+<\/em>)/); + const parsedString = parts.map((part) => { + if (part.includes("")) { + let replaced = part.replace("", ""); + replaced = replaced.replace("", ""); + return {replaced}; + } + return {part}; + }); + + return parsedString; + } + + function transformAuthors() { + const authors = + highlight && highlight.authors ? highlight.authors : result.authors; + + return ( +
+ {"by "} + {authors.map((author, i) => { + let isLast = i === authors.length - 1; + let result = parseHighlight(author); + + if (isLast) { + return result; + } + + return ( + + {result} + {", "} + + ); + })} +
+ ); + } + + return highlightSpan ? highlightSpan : null; +}; + +const styles = StyleSheet.create({ + authors: { + fontSize: 12, + fontWeight: 400, + color: "#918F9B", + marginTop: 5, + }, + highlight: { + backgroundColor: "#f6e653", + padding: "2px 1px 2px 1px", + fontStyle: "italic", + }, +}); + +export default Highlight; diff --git a/components/Search/NewEntry.js b/components/Search/NewEntry.js new file mode 100644 index 0000000000..daf8c7bb1d --- /dev/null +++ b/components/Search/NewEntry.js @@ -0,0 +1,603 @@ +import React, { Fragment } from "react"; +import { StyleSheet, css } from "aphrodite"; +import { connect } from "react-redux"; +import Router from "next/router"; +import "./algolia.css"; + +// Redux +import { MessageActions } from "~/redux/message"; + +// Components +import University from "~/components/University"; +import AuthorAvatar from "~/components/AuthorAvatar"; +// import { Highlight } from "react-instantsearch-dom"; +import Highlight from "./AlgoliaHighlight"; +// Config +import colors, { bannerColor } from "~/config/themes/colors"; +import icons from "~/config/themes/icons"; +import { + formatDateStandard, + formatPaperSlug, + createUserSummary, +} from "~/config/utils"; +import { transformDate } from "~/redux/utils"; + +const search_fields = [ + "title", + "text", + "first_name", + "last_name", + "authors", + "name", + "summary", +]; + +class SearchEntry extends React.Component { + constructor(props) { + super(props); + this.state = { + indexName: false, + hidden: false, + activeFields: 1, + }; + } + + configureLink() { + // create link + } + + /** + * We want to take the user to the appropriate page when they click a search result + */ + handleClick = () => { + let { indexName, result, clearSearch, onClickCallBack } = this.props; + let { id, slug } = result; + let paperSlug = slug ? slug : formatPaperSlug(result.title); + clearSearch && clearSearch(); + if (indexName === "author") { + Router.push("/user/[authorId]/[tabName]", `/user/${id}/contributions`); + } else if (indexName === "paper") { + Router.push("/paper/[paperId]/[paperName]", `/paper/${id}/${paperSlug}`); + } else if (indexName === "discussion_thread") { + let { paper } = result; + Router.push( + "/paper/[paperId]/[paperName]/[discussionThreadId]", + `/paper/${paper}/${paperSlug}/${id}` + ); + } + setTimeout(() => onClickCallBack && onClickCallBack(), 400); + }; + + parseTitleHighlight = (highlight, key) => { + const text = highlight[key][0]; + const parts = text.split(/([^<]+<\/em>)/); + return parts.map((part) => { + if (part.includes("")) { + let replaced = part.replace("", ""); + replaced = replaced.replace("", ""); + return {replaced}; + } + return {part}; + }); + }; + + convertDate = (date) => { + return formatDateStandard(transformDate(date)); + }; + + transformAuthors = () => { + const { result } = this.props; + const { authors, meta } = result; + + if (result.meta.highlight && result.meta.highlight.authors) { + return ( +
+ {"by "} + {this.parseTitleHighlight(result.meta.highlight, "authors")} +
+ ); + } else { + return ( +
+ {"by "} + {authors.map((author, i) => { + if (i !== authors.length - 1) { + return ( + + + {", "} + + ); + } else { + return ( + + ); + } + })} +
+ ); + } + }; + + renderMainText = () => { + const { indexName, result } = this.props; + const { authors } = result; + + if (indexName === "author") { + return ( + + + + + + + ); + } else if (indexName === "paper") { + return ( + + + + + {authors && authors.length > 0 ? ( + this.transformAuthors() + ) : ( +
No attributed author
+ )} +
+ ); + } + }; + + renderMetaDataOne = () => { + const { indexName, result } = this.props; + + if (indexName === "author") { + const userSummary = createUserSummary(result); + + if (userSummary) { + return ( + + {createUserSummary(result)} + + ); + } + } else if (indexName === "paper") { + return ( + + + {/* {result.abstract} */} + + ); + } + }; + + renderCount = () => { + let { indexName, result } = this.props; + if (indexName === "paper" || indexName === "discussion_thread") { + let count = + indexName === "paper" ? result.discussion_count : result.commentCount; + return ( +
+ {icons.chat} + + {indexName === "paper" ? ( + + + {result.discussion_count}{" "} + + {count > 1 ? "comments" : count === 0 ? "comments" : "comment"} + + ) : ( + + + {result.commentCount}{" "} + + {count > 1 ? "comments" : count === 0 ? "comments" : "comment"} + + )} + +
+ ); + } else { + return; + } + }; + + renderBulletPoints = () => { + let { indexName, result } = this.props; + if (indexName === "paper") { + let { hubs, paper_publish_date, uploaded_date } = result; + return ( + +
{this.renderCount()}
+
+
+ {icons.hub} + + {hubs && ( + + {hubs.length} + hub{(hubs.length > 1 || hubs.length === 0) && "s"} + + )} + +
+
+
+
+ {icons.date} + + {uploaded_date + ? this.convertDate(uploaded_date) + : "No publish date"} + +
+
+
+ ); + } else if (indexName === "discussion_thread") { + let { createdBy, createdDate } = result; + let { firstName, lastName } = createdBy; + return ( + +
{this.renderCount()}
+
+
+ {icons.simpleUser} + + {`${firstName} ${lastName}`} + +
+
+
+
+ {icons.date} + + {createdDate && this.convertDate(createdDate)} + +
+
+
+ ); + } + }; + + renderHeader = () => { + const { indexName } = this.props; + return
{indexName + "s"}
; + }; + + renderScore = () => { + const { indexName, result, hideBullets, score } = this.props; + + switch (indexName) { + case "author": + return ( +
+ {result.profile_image ? ( + + ) : ( + + )} +
+ ); + case "paper": + return ( +
+ {(score && score) || 0} +
+ ); + default: + return; + } + }; + + render() { + const { indexName, result, hideBullets, firstOfItsType } = this.props; + const { score, tagline, plainText } = result; + let isPaper = indexName === "paper"; + let isDisc = indexName === "discussion_thread"; + + return ( + + {firstOfItsType && this.renderHeader()} +
+
+ {this.renderScore()} +
+
= 100 + ? styles.mobilePadding + : styles.spaced + : null, + isDisc && plainText + ? plainText.length >= 100 + ? styles.mobilePadding + : styles.spaced + : null, + hideBullets && styles.fullWidth + )} + > +
{this.renderMainText()}
+
+ {this.renderMetaDataOne()} +
+
+ {/*
+ {indexName === "discussion_thread" ? "disc." : indexName} +
*/} + {!hideBullets && ( +
+ {this.renderBulletPoints()} +
+ )} +
+
+ ); + } +} + +const styles = StyleSheet.create({ + searchEntryCard: { + display: "flex", + justifyContent: "flex-start", + alignItems: "center", + minHeight: 130, + width: "calc(100%)", + padding: "15px 20px", + position: "relative", + boxSizing: "border-box", + cursor: "pointer", + ":hover": { + backgroundColor: "#FAFAFA", + }, + }, + customStyles: { + border: "1px solid #EDEDED", + }, + column: { + display: "flex", + flexDirection: "column", + justifyContent: "center", + alignItems: "flex-start", + }, + left: { + marginRight: 20, + }, + fullWidth: { + width: "calc(100% - 50px)", + paddingBottom: 20, + }, + mid: { + justifyContent: "center", + width: "calc(100% * 0.7)", + marginRight: 20, + "@media only screen and (max-width: 1200px)": { + width: "calc(100% - 50px)", + margin: 0, + }, + }, + right: { + justifyContent: "space-between", + alignItems: "flex-start", + "@media only screen and (max-width: 1200px)": { + display: "none", + }, + }, + spaced: { + justifyContent: "space-between", + "@media only screen and (max-width: 1200px)": { + width: "calc(100% - 50px)", + margin: 0, + }, + }, + mobilePadding: { + justifyContent: "space-between", + "@media only screen and (max-width: 1200px)": { + width: "calc(100% - 50px)", + margin: 0, + paddingBottom: 25, + }, + }, + avatarDisplay: { + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + voteDisplay: { + color: "rgb(100, 196, 143)", + fontWeight: "bold", + background: "rgb(233, 250, 234)", + borderRadius: "50%", + height: 50, + width: 50, + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + smallVoteDisplay: { + height: 40, + width: 40, + borderRadius: "50%", + }, + highlight: { + backgroundColor: "#f6e653", + padding: "2px 1px 2px 1px", + }, + mainText: { + fontSize: 16, + color: "rgb(35, 32, 56)", + fontWeight: "500", + flexWrap: "wrap", + wordBreak: "break-word", + lineHeight: 1.2, + marginBottom: 8, + textOverflow: "ellipsis", + "@media only screen and (max-width: 1080px)": { + fontSize: 16, + }, + }, + metaDataOne: { + flexWrap: "wrap", + display: "flex", + "@media only screen and (max-width: 1200px)": { + width: "100%", + }, + }, + userHeadline: { + fontSize: 13, + fontWeight: 400, + color: "#918F9B", + }, + metaDataTwo: { + fontSize: 16, + flexWrap: "wrap", + display: "flex", + }, + avatar: { + height: 50, + width: 50, + borderRadius: 27.5, + objectFit: "contain", + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + defaultAvatar: { + color: "#aaa", + fontSize: 50, + }, + indexTag: { + position: "absolute", + textTransform: "uppercase", + right: 20, + bottom: 10, + color: colors.BLUE(1), + fontSize: 14, + "@media only screen and (max-width: 1080px)": { + fontSize: 12, + }, + }, + publishDate: { + fontSize: 14, + fontWeight: 400, + color: "#918F9B", + }, + authors: { + fontSize: 12, + fontWeight: 400, + color: "#918F9B", + marginTop: 5, + }, + abstract: { + fontSize: 13, + fontWeight: 400, + color: colors.BLACK(0.9), + }, + discText: { + fontSize: 12, + wordBreak: "break-word", + "@media only screen and (max-width: 1200px)": { + width: "calc(100% - 50px)", + textOverflow: "ellipsis", + whiteSpace: "nowrap", + overflow: "hidden", + }, + }, + tagline: { + fontSize: 12, + wordBreak: "break-word", + "@media only screen and (max-width: 1200px)": { + width: "calc(100% - 50px)", + textOverflow: "ellipsis", + whiteSpace: "nowrap", + overflow: "hidden", + }, + }, + icon: { + minWidth: 20, + maxWidth: 20, + // color: "#918F9B", + color: colors.YELLOW(), + fontSize: 14, + }, + paperIcon: { + color: colors.BLUE(), + marginRight: 5, + }, + bullet: {}, + discussion: { + display: "flex", + justifyContent: "flex-start", + alignItems: "center", + paddingTop: 5, + }, + discussionCount: { + color: colors.BLACK(1), + marginLeft: 7, + fontSize: 14, + paddingBottom: 2, + }, + count: { + color: colors.BLACK(1), + fontWeight: "bold", + }, + section: { + width: "100%", + textTransform: "uppercase", + fontSize: 13, + fontWeight: 500, + letterSpacing: 1.2, + borderBottom: "1px solid #DAE0E6", + padding: "10px 0", + }, + first_name: { + marginRight: 3, + }, +}); + +const mapStateToProps = (state) => ({}); + +const mapDispatchToProps = { + showMessage: MessageActions.showMessage, + setMessage: MessageActions.setMessage, +}; +export default connect( + mapStateToProps, + mapDispatchToProps +)(SearchEntry); diff --git a/components/Search/Search.js b/components/Search/Search.js index 1281b7858c..39279c4c34 100644 --- a/components/Search/Search.js +++ b/components/Search/Search.js @@ -35,7 +35,7 @@ export default class Search extends Component { componentDidUpdate(prevProps, prevState) { if (prevProps.showDropdown !== this.props.showDropdown) { this.setState({ - showDropdown: this.props.showDropdown, + // showDropdown: this.props.showDropdown, }); } } @@ -47,14 +47,14 @@ export default class Search extends Component { } onSearchChange = (e) => { - clearTimeout(this.searchTimeout); + // clearTimeout(this.searchTimeout); const value = e.target.value; if (!value) { this.setState({ showDropdown: false, - finished: true, + // finished: true, query: "", }); @@ -62,29 +62,25 @@ export default class Search extends Component { } else { this.setState({ showDropdown: true, - finished: false, + // finished: false, query: value, }); } - this.searchTimeout = setTimeout(() => { - const config = { - route: "all", - }; + const config = { route: "all" }; - // TODO: add pagination - // Params to the search for pagination would be page - fetch(API.SEARCH({ search: value, config }), API.GET_CONFIG()) - .then(Helpers.checkStatus) - .then(Helpers.parseJSON) - .then((resp) => { - this.setState({ - results: resp.results, - finished: true, - next: resp.next, - }); + // TODO: add pagination + // Params to the search for pagination would be page + fetch(API.SEARCH({ search: value, config }), API.GET_CONFIG()) + .then(Helpers.checkStatus) + .then(Helpers.parseJSON) + .then((resp) => { + this.setState({ + results: resp.results, + // finished: true, + next: resp.next, }); - }, 200); + }); }; fetchNextPage = () => { @@ -105,20 +101,29 @@ export default class Search extends Component { }; renderSearchResults = () => { - let universityCount = 0; + if (this.state.results.length === 0) { + return ( +
+

+ We can't find what you're looking for! Please try another search. +

+ +
+ ); + } + let prevType; const results = this.state.results.map((result, index) => { - result.meta.index === "university" && universityCount++; let firstOfItsType = prevType !== result.meta.index; prevType = result.meta.index; return (
{ this.dropdownTimeout = setTimeout( this.setState({ showDropdown: false }), @@ -131,63 +136,22 @@ export default class Search extends Component { ); }); - if (results.length === 0 || universityCount === results.length) { - return ( -
-

- We can't find what you're looking for! Please try another search. -

- -
- ); - } - return results; }; getResultComponent = (result, index, firstOfItsType) => { const indexName = result.meta.index; + const props = { + indexName, + result, + clearSearch: this.clearQuery, + firstOfItsType, + }; switch (indexName) { case "author": - return ( - - ); case "crossref_paper": case "paper": - const hit = { - ...result, - __highlightResult: result.meta._highlightResult, - }; - - return ( - - ); - // case "discussion_thread": - // let data = thread(result); - // if (data.isPublic) { - // data = this.populateThreadData(data, result); - // data.meta = result.meta; - // return ( - // - // ); - // } + return ; case "hub": return ( - - {this.renderSearchResults()} - + {this.renderSearchResults()}
)} diff --git a/components/Search/SearchEntry.js b/components/Search/SearchEntry.js index ba73787275..5d17f8200c 100644 --- a/components/Search/SearchEntry.js +++ b/components/Search/SearchEntry.js @@ -9,11 +9,16 @@ import { MessageActions } from "~/redux/message"; // Components import University from "~/components/University"; import AuthorAvatar from "~/components/AuthorAvatar"; +import Highlight from "~/components/Search/Highlight"; // Config import colors from "../../config/themes/colors"; import icons from "~/config/themes/icons"; -import { formatDateStandard, formatPaperSlug } from "~/config/utils"; +import { + formatDateStandard, + formatPaperSlug, + createUserSummary, +} from "~/config/utils"; import { transformDate } from "~/redux/utils"; const search_fields = [ @@ -44,22 +49,16 @@ class SearchEntry extends React.Component { * We want to take the user to the appropriate page when they click a search result */ handleClick = () => { - let { indexName, result, clearSearch, onClickCallBack } = this.props; - let { id, slug } = result; - let paperSlug = slug ? slug : formatPaperSlug(result.title); + const { indexName, result, clearSearch, onClickCallBack } = this.props; + const { id, slug, paper } = result; + const paperSlug = slug ? slug : formatPaperSlug(result.title); clearSearch && clearSearch(); if (indexName === "author") { Router.push("/user/[authorId]/[tabName]", `/user/${id}/contributions`); } else if (indexName === "paper") { Router.push("/paper/[paperId]/[paperName]", `/paper/${id}/${paperSlug}`); - } else if (indexName === "discussion_thread") { - let { paper } = result; - Router.push( - "/paper/[paperId]/[paperName]/[discussionThreadId]", - `/paper/${paper}/${paperSlug}/${id}` - ); } - setTimeout(() => onClickCallBack && onClickCallBack(), 400); + onClickCallBack && onClickCallBack(); }; parseTitleHighlight = (highlight, key) => { @@ -75,226 +74,128 @@ class SearchEntry extends React.Component { }); }; - // parseHighlightField = (highlight, key) => { - // let { indexName, result } = this.props; - // let textArr = highlight[key][0].split(" "); - // let highlightedIndex = {}; - - // textArr.forEach((text, i, arr) => { - // if (text[0] === "<") { - // if (text.split("
").length > 1) { - // let splitArr = text - // .slice(4) - // .split("
") - // .filter((el) => el !== ""); - // let highlighted = splitArr[0]; - // arr[i] = highlighted; - - // if (splitArr.length > 1) { - // let normal = splitArr[1].slice(4); - // textArr.splice(i + 1, 0, normal); - // highlightedIndex[i + 1] = true; - // } - // } else { - // arr[i] = text.slice(4, text.length - 5); - // } - // highlightedIndex[i] = true; - // } - // }); - - // let transformedText = textArr.map((text, i) => { - // if (highlightedIndex[i]) { - // return ( - // - // {highlightedIndex[i - 1] ? " " : ""} - // {text} - // - // ); - // } else { - // return `${highlightedIndex[i - 1] ? " " : ""}${text}${ - // i !== textArr.length - 1 ? " " : "" - // }`; - // } - // }); - - // if (key === "tagline") { - // transformedText.push("..."); - // } - // return transformedText; - // }; - convertDate = (date) => { return formatDateStandard(transformDate(date)); }; - transformAuthors = () => { - let { result } = this.props; - let { authors, meta } = result; - if (result.meta.highlight && result.meta.highlight.authors) { - return ( -
- {"by "} - {this.parseTitleHighlight(result.meta.highlight, "authors")} -
- ); - } else { - return ( -
- {"by "} - {authors.map((author, i) => { - if (i !== authors.length - 1) { - return `${author}, `; - } else { - return author; - } - })} -
- ); - } - }; + // transformAuthors = () => { + // const { result } = this.props; + // const { authors, meta } = result; + // if (result.meta.highlight && result.meta.highlight.authors) { + // return ( + //
+ // {"by "} + // {this.parseTitleHighlight(result.meta.highlight, "authors")} + //
+ // ); + // } else { + // return ( + //
+ // {"by "} + // {authors.map((author, i) => { + // if (i !== authors.length - 1) { + // return ( + // + // + // {", "} + // + // ); + // } else { + // return ( + // + // ); + // } + // })} + //
+ // ); + // } + // }; renderMainText = () => { - let { indexName, result } = this.props; - if (indexName === "author") { - let { first_name, last_name, meta } = result; - let highlight = meta.highlight; - return ( - - - {first_name && first_name} - - + + + + + + ); + case "paper": + return ( + + + + + {authors && authors.length > 0 ? ( + + ) : ( +
No attributed author
)} - > - {last_name && ` ${last_name}`}
- - ); - } else if (indexName === "paper") { - let { meta, title, authors } = result; - let highlight = meta.highlight; - return ( - - {highlight && highlight.title - ? this.parseTitleHighlight(highlight, "title") - : title} - {authors && authors.length > 0 ? ( - this.transformAuthors() - ) : ( -
No attributed author
- )} -
- ); - } else if (indexName === "discussion_thread") { - let { meta, title, paperTitle } = result; - let highlight = meta.highlight; - return ( - - {highlight && highlight.title - ? this.parseTitleHighlight(highlight, "title") - : title} - {paperTitle && ( -
- - {icons.file} - {" "} - {paperTitle} -
- )} -
- ); + ); + default: + return null; } }; renderMetaDataOne = () => { - let { indexName, result } = this.props; - if (indexName === "author") { - let { university } = result; - if (Object.keys(university).length) { + const { indexName, result } = this.props; + + switch (indexName) { + case "author": + const userSummary = createUserSummary(result); + + if (userSummary) { + return ( + + {userSummary} + + ); + } + break; + case "paper": return ( - - + + ); - } - } else if (indexName === "paper") { - let { tagline } = result; - let highlight = result.meta.highlight; - if (tagline) { - return ( -
- {highlight && highlight.tagline - ? this.parseTitleHighlight(highlight, "tagline") - : tagline} -
- ); - } - } else if (indexName === "discussion_thread") { - let highlight = result.meta.highlight; - let { plainText } = result; - return ( -
- {highlight && highlight.plain_text - ? this.parseTitleHighlight(highlight, "plain_text") - : plainText} -
- ); - } - }; - - renderMetaDataTwo = () => { - let { indexName, result } = this.props; - if (indexName === "author") { - return; - } else if (indexName === "paper") { - } else if (indexName === "discussion_thread") { + default: + return null; } }; renderCount = () => { - let { indexName, result } = this.props; - if (indexName === "paper" || indexName === "discussion_thread") { - let count = + const { indexName, result } = this.props; + if (indexName === "paper") { + const count = indexName === "paper" ? result.discussion_count : result.commentCount; return (
{icons.chat} - {indexName === "paper" ? ( - - - {result.discussion_count}{" "} - - {count > 1 ? "comments" : count === 0 ? "comments" : "comment"} - - ) : ( - - - {result.commentCount}{" "} - - {count > 1 ? "comments" : count === 0 ? "comments" : "comment"} - - )} + {count} + {count > 1 ? "comments" : count === 0 ? "comments" : "comment"}
); - } else { - return; } }; renderBulletPoints = () => { - let { indexName, result } = this.props; + const { indexName, result } = this.props; if (indexName === "paper") { - let { hubs, paper_publish_date } = result; + const { hubs, paper_publish_date } = result; return (
{this.renderCount()}
@@ -323,40 +224,52 @@ class SearchEntry extends React.Component {
); - } else if (indexName === "discussion_thread") { - let { createdBy, createdDate } = result; - let { firstName, lastName } = createdBy; - return ( - -
{this.renderCount()}
-
-
- {icons.simpleUser} - - {`${firstName} ${lastName}`} - -
-
-
-
- {icons.date} - - {createdDate && this.convertDate(createdDate)} - -
-
-
- ); } }; renderHeader = () => { - return
Papers
; + const { indexName } = this.props; + return
{indexName + "s"}
; + }; + + renderScore = () => { + const { indexName, result, hideBullets, score } = this.props; + + switch (indexName) { + case "author": + return ( +
+ {result.profile_image ? ( + + ) : ( + + )} +
+ ); + case "paper": + return ( +
+ {(score && score) || 0} +
+ ); + default: + return; + } }; render() { - let { indexName, result, hideBullets, firstOfItsType } = this.props; - let { score, tagline, plainText } = result; + const { indexName, result, hideBullets, firstOfItsType } = this.props; + const { tagline, plainText } = result; let isPaper = indexName === "paper"; let isDisc = indexName === "discussion_thread"; @@ -378,32 +291,7 @@ class SearchEntry extends React.Component { indexName === "author" && styles.isAuthor )} > - {indexName === "author" ? ( -
- {result.profile_image ? ( - - ) : ( - - )} -
- ) : ( -
- {(score && score) || 0} -
- )} + {this.renderScore()}
{this.renderMetaDataOne()}
-
- {this.renderMetaDataTwo()} -
- {/*
- {indexName === "discussion_thread" ? "disc." : indexName} -
*/} {!hideBullets && (
{this.renderBulletPoints()} @@ -477,7 +359,7 @@ const styles = StyleSheet.create({ }, mid: { justifyContent: "center", - width: "calc(calc(100% - 50px) * 0.7)", + width: "75%", marginRight: 20, "@media only screen and (max-width: 1200px)": { width: "calc(100% - 50px)", @@ -487,8 +369,7 @@ const styles = StyleSheet.create({ right: { justifyContent: "space-between", alignItems: "flex-start", - width: "calc(calc(100% - 50px) * 0.3)", - "@media only screen and (max-width: 1200px)": { + "@media only screen and (max-width: 1300px)": { display: "none", }, }, @@ -533,35 +414,38 @@ const styles = StyleSheet.create({ padding: "2px 1px 2px 1px", }, mainText: { - fontSize: 18, + fontSize: 16, color: "rgb(35, 32, 56)", fontWeight: "500", flexWrap: "wrap", wordBreak: "break-word", - lineHeight: 1.6, - marginBottom: 10, + lineHeight: 1.2, + marginBottom: 8, textOverflow: "ellipsis", "@media only screen and (max-width: 1080px)": { fontSize: 16, }, }, metaDataOne: { - fontSize: 16, flexWrap: "wrap", display: "flex", "@media only screen and (max-width: 1200px)": { width: "100%", }, }, - paddedContainer: {}, + userHeadline: { + fontSize: 13, + fontWeight: 400, + color: "#918F9B", + }, metaDataTwo: { fontSize: 16, flexWrap: "wrap", display: "flex", }, avatar: { - height: 55, - width: 55, + height: 50, + width: 50, borderRadius: 27.5, objectFit: "contain", display: "flex", @@ -589,13 +473,18 @@ const styles = StyleSheet.create({ color: "#918F9B", }, authors: { - fontSize: 13, + fontSize: 12, fontWeight: 400, color: "#918F9B", + marginTop: 5, + }, + abstract: { + fontSize: 13, + fontWeight: 400, + color: colors.BLACK(0.9), }, discText: { fontSize: 12, - // maxHeight: 49, wordBreak: "break-word", "@media only screen and (max-width: 1200px)": { width: "calc(100% - 50px)", @@ -621,7 +510,7 @@ const styles = StyleSheet.create({ fontSize: 14, }, paperIcon: { - color: colors.BLUE(1), + color: colors.BLUE(), marginRight: 5, }, bullet: {}, @@ -634,7 +523,7 @@ const styles = StyleSheet.create({ discussionCount: { color: colors.BLACK(1), marginLeft: 7, - fontSize: 14, + fontSize: 13, paddingBottom: 2, }, count: { @@ -649,7 +538,9 @@ const styles = StyleSheet.create({ letterSpacing: 1.2, borderBottom: "1px solid #DAE0E6", padding: "10px 0", - // color: 'rgb(167, 166, 176)' + }, + first_name: { + marginRight: 3, }, }); From 97c86aeb2aa7339df3ed071f54423ad1e0039a62 Mon Sep 17 00:00:00 2001 From: joshslee Date: Fri, 11 Dec 2020 18:49:24 -0800 Subject: [PATCH 03/10] update search ui --- components/Search/Highlight.js | 22 +++++++++++++++++---- components/Search/Search.js | 22 +++++++++++++-------- components/Search/SearchEntry.js | 33 ++++++++++++++------------------ 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/components/Search/Highlight.js b/components/Search/Highlight.js index da305bb661..acd9638fd2 100644 --- a/components/Search/Highlight.js +++ b/components/Search/Highlight.js @@ -9,9 +9,9 @@ import API from "~/config/api"; import { Helpers } from "@quantfive/js-web-config"; import { doesNotExist } from "~/config/utils"; -const Highlight = ({ result, attribute }) => { - const { meta } = result; - const { highlight } = meta; +const Highlight = (props) => { + const { result, attribute } = props; + const { highlight } = result.meta; const highlightSpan = formatHighlightByAttribute(); @@ -19,10 +19,11 @@ const Highlight = ({ result, attribute }) => { switch (attribute) { case "authors": return transformAuthors(); + case "abstract": + // return transformAbstract(); case "first_name": case "last_name": case "title": - case "abstract": default: return parseHighlight(); } @@ -35,6 +36,7 @@ const Highlight = ({ result, attribute }) => { ) return result[attribute]; + console.log("_text", _text); const text = _text ? _text : highlight[attribute][0]; const parts = text.split(/([^<]+<\/em>)/); const parsedString = parts.map((part) => { @@ -75,6 +77,18 @@ const Highlight = ({ result, attribute }) => { ); } + function transformAbstract() { + let regex = new RegExp(props.search, "ig"); + if (result.abstract) { + const abstract = result.abstract.replace( + regex, + `${props.search}` + ); + return abstract ? parseHighlight(abstract) : result[attribute]; + } + return result[attribute]; + } + return highlightSpan ? highlightSpan : null; }; diff --git a/components/Search/Search.js b/components/Search/Search.js index 39279c4c34..8d8a4a87be 100644 --- a/components/Search/Search.js +++ b/components/Search/Search.js @@ -146,6 +146,7 @@ export default class Search extends Component { result, clearSearch: this.clearQuery, firstOfItsType, + query: this.state.query, }; switch (indexName) { case "author": @@ -220,13 +221,15 @@ export default class Search extends Component { hasMore={this.state.next} loadMore={this.fetchNextPage} loader={ - +
+ +
} useWindow={false} getScrollParent={() => this.scrollParent} @@ -290,21 +293,24 @@ const styles = StyleSheet.create({ position: "absolute", zIndex: 10, top: 60, - maxHeight: 400, left: "50%", transform: "translateX(-50%)", background: "#fff", overflow: "scroll", + overflowX: "hidden", padding: 16, boxSizing: "border-box", boxShadow: "0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)", minWidth: 400, + maxHeight: 400, }, + searchResult: { borderBottom: "1px solid rgb(235, 235, 235)", }, emptyResults: { padding: "15px 0", + width: "100%", display: "flex", alignItems: "center", justifyContent: "center", diff --git a/components/Search/SearchEntry.js b/components/Search/SearchEntry.js index 5d17f8200c..c699c1e4a4 100644 --- a/components/Search/SearchEntry.js +++ b/components/Search/SearchEntry.js @@ -150,7 +150,7 @@ class SearchEntry extends React.Component { }; renderMetaDataOne = () => { - const { indexName, result } = this.props; + const { indexName, result, query } = this.props; switch (indexName) { case "author": @@ -167,7 +167,7 @@ class SearchEntry extends React.Component { case "paper": return ( - + ); default: @@ -269,9 +269,6 @@ class SearchEntry extends React.Component { render() { const { indexName, result, hideBullets, firstOfItsType } = this.props; - const { tagline, plainText } = result; - let isPaper = indexName === "paper"; - let isDisc = indexName === "discussion_thread"; return ( @@ -280,6 +277,7 @@ class SearchEntry extends React.Component { key={`${indexName}-${result.id}`} className={css( styles.searchEntryCard, + indexName === "author" && styles.authorEntryCard, hideBullets && styles.customStyles )} onClick={this.handleClick} @@ -297,16 +295,6 @@ class SearchEntry extends React.Component { className={css( styles.column, styles.mid, - isPaper && tagline - ? tagline.length >= 100 - ? styles.mobilePadding - : styles.spaced - : null, - isDisc && plainText - ? plainText.length >= 100 - ? styles.mobilePadding - : styles.spaced - : null, hideBullets && styles.fullWidth )} > @@ -341,6 +329,9 @@ const styles = StyleSheet.create({ backgroundColor: "#FAFAFA", }, }, + authorEntryCard: { + minHeight: 80, + }, customStyles: { border: "1px solid #EDEDED", }, @@ -444,17 +435,21 @@ const styles = StyleSheet.create({ display: "flex", }, avatar: { - height: 50, - width: 50, - borderRadius: 27.5, + height: 40, + width: 40, + borderRadius: "50%", objectFit: "contain", display: "flex", justifyContent: "center", alignItems: "center", + boxShadow: "0px 2px 4px rgba(185, 185, 185, 0.25)", }, defaultAvatar: { color: "#aaa", - fontSize: 50, + fontSize: 40, + borderRadius: "50%", + boxShadow: "unset", + border: "1px solid #FAFAFA", }, indexTag: { position: "absolute", From a65acb5b7728c35fbb1b30bfba5f922c066eac21 Mon Sep 17 00:00:00 2001 From: joshslee Date: Mon, 14 Dec 2020 14:27:05 -0800 Subject: [PATCH 04/10] update search ui --- components/Search/Highlight.js | 19 - components/Search/NewEntry.js | 603 ------------------------------- components/Search/Search.js | 19 +- components/Search/SearchEntry.js | 4 +- 4 files changed, 4 insertions(+), 641 deletions(-) delete mode 100644 components/Search/NewEntry.js diff --git a/components/Search/Highlight.js b/components/Search/Highlight.js index acd9638fd2..472eeb9d01 100644 --- a/components/Search/Highlight.js +++ b/components/Search/Highlight.js @@ -1,12 +1,7 @@ import React, { Fragment } from "react"; -import { connect } from "react-redux"; import { StyleSheet, css } from "aphrodite"; // Config -import colors from "~/config/themes/colors"; -import icons from "../../config/themes/icons"; -import API from "~/config/api"; -import { Helpers } from "@quantfive/js-web-config"; import { doesNotExist } from "~/config/utils"; const Highlight = (props) => { @@ -20,7 +15,6 @@ const Highlight = (props) => { case "authors": return transformAuthors(); case "abstract": - // return transformAbstract(); case "first_name": case "last_name": case "title": @@ -36,7 +30,6 @@ const Highlight = (props) => { ) return result[attribute]; - console.log("_text", _text); const text = _text ? _text : highlight[attribute][0]; const parts = text.split(/([^<]+<\/em>)/); const parsedString = parts.map((part) => { @@ -77,18 +70,6 @@ const Highlight = (props) => { ); } - function transformAbstract() { - let regex = new RegExp(props.search, "ig"); - if (result.abstract) { - const abstract = result.abstract.replace( - regex, - `${props.search}` - ); - return abstract ? parseHighlight(abstract) : result[attribute]; - } - return result[attribute]; - } - return highlightSpan ? highlightSpan : null; }; diff --git a/components/Search/NewEntry.js b/components/Search/NewEntry.js deleted file mode 100644 index daf8c7bb1d..0000000000 --- a/components/Search/NewEntry.js +++ /dev/null @@ -1,603 +0,0 @@ -import React, { Fragment } from "react"; -import { StyleSheet, css } from "aphrodite"; -import { connect } from "react-redux"; -import Router from "next/router"; -import "./algolia.css"; - -// Redux -import { MessageActions } from "~/redux/message"; - -// Components -import University from "~/components/University"; -import AuthorAvatar from "~/components/AuthorAvatar"; -// import { Highlight } from "react-instantsearch-dom"; -import Highlight from "./AlgoliaHighlight"; -// Config -import colors, { bannerColor } from "~/config/themes/colors"; -import icons from "~/config/themes/icons"; -import { - formatDateStandard, - formatPaperSlug, - createUserSummary, -} from "~/config/utils"; -import { transformDate } from "~/redux/utils"; - -const search_fields = [ - "title", - "text", - "first_name", - "last_name", - "authors", - "name", - "summary", -]; - -class SearchEntry extends React.Component { - constructor(props) { - super(props); - this.state = { - indexName: false, - hidden: false, - activeFields: 1, - }; - } - - configureLink() { - // create link - } - - /** - * We want to take the user to the appropriate page when they click a search result - */ - handleClick = () => { - let { indexName, result, clearSearch, onClickCallBack } = this.props; - let { id, slug } = result; - let paperSlug = slug ? slug : formatPaperSlug(result.title); - clearSearch && clearSearch(); - if (indexName === "author") { - Router.push("/user/[authorId]/[tabName]", `/user/${id}/contributions`); - } else if (indexName === "paper") { - Router.push("/paper/[paperId]/[paperName]", `/paper/${id}/${paperSlug}`); - } else if (indexName === "discussion_thread") { - let { paper } = result; - Router.push( - "/paper/[paperId]/[paperName]/[discussionThreadId]", - `/paper/${paper}/${paperSlug}/${id}` - ); - } - setTimeout(() => onClickCallBack && onClickCallBack(), 400); - }; - - parseTitleHighlight = (highlight, key) => { - const text = highlight[key][0]; - const parts = text.split(/([^<]+<\/em>)/); - return parts.map((part) => { - if (part.includes("")) { - let replaced = part.replace("", ""); - replaced = replaced.replace("", ""); - return {replaced}; - } - return {part}; - }); - }; - - convertDate = (date) => { - return formatDateStandard(transformDate(date)); - }; - - transformAuthors = () => { - const { result } = this.props; - const { authors, meta } = result; - - if (result.meta.highlight && result.meta.highlight.authors) { - return ( -
- {"by "} - {this.parseTitleHighlight(result.meta.highlight, "authors")} -
- ); - } else { - return ( -
- {"by "} - {authors.map((author, i) => { - if (i !== authors.length - 1) { - return ( - - - {", "} - - ); - } else { - return ( - - ); - } - })} -
- ); - } - }; - - renderMainText = () => { - const { indexName, result } = this.props; - const { authors } = result; - - if (indexName === "author") { - return ( - - - - - - - ); - } else if (indexName === "paper") { - return ( - - - - - {authors && authors.length > 0 ? ( - this.transformAuthors() - ) : ( -
No attributed author
- )} -
- ); - } - }; - - renderMetaDataOne = () => { - const { indexName, result } = this.props; - - if (indexName === "author") { - const userSummary = createUserSummary(result); - - if (userSummary) { - return ( - - {createUserSummary(result)} - - ); - } - } else if (indexName === "paper") { - return ( - - - {/* {result.abstract} */} - - ); - } - }; - - renderCount = () => { - let { indexName, result } = this.props; - if (indexName === "paper" || indexName === "discussion_thread") { - let count = - indexName === "paper" ? result.discussion_count : result.commentCount; - return ( -
- {icons.chat} - - {indexName === "paper" ? ( - - - {result.discussion_count}{" "} - - {count > 1 ? "comments" : count === 0 ? "comments" : "comment"} - - ) : ( - - - {result.commentCount}{" "} - - {count > 1 ? "comments" : count === 0 ? "comments" : "comment"} - - )} - -
- ); - } else { - return; - } - }; - - renderBulletPoints = () => { - let { indexName, result } = this.props; - if (indexName === "paper") { - let { hubs, paper_publish_date, uploaded_date } = result; - return ( - -
{this.renderCount()}
-
-
- {icons.hub} - - {hubs && ( - - {hubs.length} - hub{(hubs.length > 1 || hubs.length === 0) && "s"} - - )} - -
-
-
-
- {icons.date} - - {uploaded_date - ? this.convertDate(uploaded_date) - : "No publish date"} - -
-
-
- ); - } else if (indexName === "discussion_thread") { - let { createdBy, createdDate } = result; - let { firstName, lastName } = createdBy; - return ( - -
{this.renderCount()}
-
-
- {icons.simpleUser} - - {`${firstName} ${lastName}`} - -
-
-
-
- {icons.date} - - {createdDate && this.convertDate(createdDate)} - -
-
-
- ); - } - }; - - renderHeader = () => { - const { indexName } = this.props; - return
{indexName + "s"}
; - }; - - renderScore = () => { - const { indexName, result, hideBullets, score } = this.props; - - switch (indexName) { - case "author": - return ( -
- {result.profile_image ? ( - - ) : ( - - )} -
- ); - case "paper": - return ( -
- {(score && score) || 0} -
- ); - default: - return; - } - }; - - render() { - const { indexName, result, hideBullets, firstOfItsType } = this.props; - const { score, tagline, plainText } = result; - let isPaper = indexName === "paper"; - let isDisc = indexName === "discussion_thread"; - - return ( - - {firstOfItsType && this.renderHeader()} -
-
- {this.renderScore()} -
-
= 100 - ? styles.mobilePadding - : styles.spaced - : null, - isDisc && plainText - ? plainText.length >= 100 - ? styles.mobilePadding - : styles.spaced - : null, - hideBullets && styles.fullWidth - )} - > -
{this.renderMainText()}
-
- {this.renderMetaDataOne()} -
-
- {/*
- {indexName === "discussion_thread" ? "disc." : indexName} -
*/} - {!hideBullets && ( -
- {this.renderBulletPoints()} -
- )} -
-
- ); - } -} - -const styles = StyleSheet.create({ - searchEntryCard: { - display: "flex", - justifyContent: "flex-start", - alignItems: "center", - minHeight: 130, - width: "calc(100%)", - padding: "15px 20px", - position: "relative", - boxSizing: "border-box", - cursor: "pointer", - ":hover": { - backgroundColor: "#FAFAFA", - }, - }, - customStyles: { - border: "1px solid #EDEDED", - }, - column: { - display: "flex", - flexDirection: "column", - justifyContent: "center", - alignItems: "flex-start", - }, - left: { - marginRight: 20, - }, - fullWidth: { - width: "calc(100% - 50px)", - paddingBottom: 20, - }, - mid: { - justifyContent: "center", - width: "calc(100% * 0.7)", - marginRight: 20, - "@media only screen and (max-width: 1200px)": { - width: "calc(100% - 50px)", - margin: 0, - }, - }, - right: { - justifyContent: "space-between", - alignItems: "flex-start", - "@media only screen and (max-width: 1200px)": { - display: "none", - }, - }, - spaced: { - justifyContent: "space-between", - "@media only screen and (max-width: 1200px)": { - width: "calc(100% - 50px)", - margin: 0, - }, - }, - mobilePadding: { - justifyContent: "space-between", - "@media only screen and (max-width: 1200px)": { - width: "calc(100% - 50px)", - margin: 0, - paddingBottom: 25, - }, - }, - avatarDisplay: { - display: "flex", - justifyContent: "center", - alignItems: "center", - }, - voteDisplay: { - color: "rgb(100, 196, 143)", - fontWeight: "bold", - background: "rgb(233, 250, 234)", - borderRadius: "50%", - height: 50, - width: 50, - display: "flex", - justifyContent: "center", - alignItems: "center", - }, - smallVoteDisplay: { - height: 40, - width: 40, - borderRadius: "50%", - }, - highlight: { - backgroundColor: "#f6e653", - padding: "2px 1px 2px 1px", - }, - mainText: { - fontSize: 16, - color: "rgb(35, 32, 56)", - fontWeight: "500", - flexWrap: "wrap", - wordBreak: "break-word", - lineHeight: 1.2, - marginBottom: 8, - textOverflow: "ellipsis", - "@media only screen and (max-width: 1080px)": { - fontSize: 16, - }, - }, - metaDataOne: { - flexWrap: "wrap", - display: "flex", - "@media only screen and (max-width: 1200px)": { - width: "100%", - }, - }, - userHeadline: { - fontSize: 13, - fontWeight: 400, - color: "#918F9B", - }, - metaDataTwo: { - fontSize: 16, - flexWrap: "wrap", - display: "flex", - }, - avatar: { - height: 50, - width: 50, - borderRadius: 27.5, - objectFit: "contain", - display: "flex", - justifyContent: "center", - alignItems: "center", - }, - defaultAvatar: { - color: "#aaa", - fontSize: 50, - }, - indexTag: { - position: "absolute", - textTransform: "uppercase", - right: 20, - bottom: 10, - color: colors.BLUE(1), - fontSize: 14, - "@media only screen and (max-width: 1080px)": { - fontSize: 12, - }, - }, - publishDate: { - fontSize: 14, - fontWeight: 400, - color: "#918F9B", - }, - authors: { - fontSize: 12, - fontWeight: 400, - color: "#918F9B", - marginTop: 5, - }, - abstract: { - fontSize: 13, - fontWeight: 400, - color: colors.BLACK(0.9), - }, - discText: { - fontSize: 12, - wordBreak: "break-word", - "@media only screen and (max-width: 1200px)": { - width: "calc(100% - 50px)", - textOverflow: "ellipsis", - whiteSpace: "nowrap", - overflow: "hidden", - }, - }, - tagline: { - fontSize: 12, - wordBreak: "break-word", - "@media only screen and (max-width: 1200px)": { - width: "calc(100% - 50px)", - textOverflow: "ellipsis", - whiteSpace: "nowrap", - overflow: "hidden", - }, - }, - icon: { - minWidth: 20, - maxWidth: 20, - // color: "#918F9B", - color: colors.YELLOW(), - fontSize: 14, - }, - paperIcon: { - color: colors.BLUE(), - marginRight: 5, - }, - bullet: {}, - discussion: { - display: "flex", - justifyContent: "flex-start", - alignItems: "center", - paddingTop: 5, - }, - discussionCount: { - color: colors.BLACK(1), - marginLeft: 7, - fontSize: 14, - paddingBottom: 2, - }, - count: { - color: colors.BLACK(1), - fontWeight: "bold", - }, - section: { - width: "100%", - textTransform: "uppercase", - fontSize: 13, - fontWeight: 500, - letterSpacing: 1.2, - borderBottom: "1px solid #DAE0E6", - padding: "10px 0", - }, - first_name: { - marginRight: 3, - }, -}); - -const mapStateToProps = (state) => ({}); - -const mapDispatchToProps = { - showMessage: MessageActions.showMessage, - setMessage: MessageActions.setMessage, -}; -export default connect( - mapStateToProps, - mapDispatchToProps -)(SearchEntry); diff --git a/components/Search/Search.js b/components/Search/Search.js index 8d8a4a87be..c901596b1c 100644 --- a/components/Search/Search.js +++ b/components/Search/Search.js @@ -5,10 +5,9 @@ import InfiniteScroll from "react-infinite-scroller"; import SearchEntry from "./SearchEntry"; import HubSearchResult from "../HubSearchResult"; -import Loader from "~/components/Loader/Loader"; // Config -import { RHLogo } from "~/config/themes/icons"; +import colors from "../../config/themes/colors"; import API from "~/config/api"; import { Helpers } from "@quantfive/js-web-config"; @@ -32,14 +31,6 @@ export default class Search extends Component { document.addEventListener("click", this); } - componentDidUpdate(prevProps, prevState) { - if (prevProps.showDropdown !== this.props.showDropdown) { - this.setState({ - // showDropdown: this.props.showDropdown, - }); - } - } - componentWillUnmount() { clearTimeout(this.searchTimeout); clearTimeout(this.dropdownTimeout); @@ -47,14 +38,11 @@ export default class Search extends Component { } onSearchChange = (e) => { - // clearTimeout(this.searchTimeout); - const value = e.target.value; if (!value) { this.setState({ showDropdown: false, - // finished: true, query: "", }); @@ -62,7 +50,6 @@ export default class Search extends Component { } else { this.setState({ showDropdown: true, - // finished: false, query: value, }); } @@ -77,7 +64,6 @@ export default class Search extends Component { .then((resp) => { this.setState({ results: resp.results, - // finished: true, next: resp.next, }); }); @@ -163,7 +149,6 @@ export default class Search extends Component { /> ); case "university": - // return ; return null; default: break; @@ -303,6 +288,7 @@ const styles = StyleSheet.create({ boxShadow: "0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)", minWidth: 400, maxHeight: 400, + color: colors.BLACK(), }, searchResult: { @@ -314,6 +300,7 @@ const styles = StyleSheet.create({ display: "flex", alignItems: "center", justifyContent: "center", + color: colors.BLACK(), }, emptyTitle: { fontWeight: 400, diff --git a/components/Search/SearchEntry.js b/components/Search/SearchEntry.js index c699c1e4a4..d64b29990a 100644 --- a/components/Search/SearchEntry.js +++ b/components/Search/SearchEntry.js @@ -7,8 +7,6 @@ import Router from "next/router"; import { MessageActions } from "~/redux/message"; // Components -import University from "~/components/University"; -import AuthorAvatar from "~/components/AuthorAvatar"; import Highlight from "~/components/Search/Highlight"; // Config @@ -350,7 +348,7 @@ const styles = StyleSheet.create({ }, mid: { justifyContent: "center", - width: "75%", + width: "73%", marginRight: 20, "@media only screen and (max-width: 1200px)": { width: "calc(100% - 50px)", From 6e5d78ffbcf50daada777207f8cc4fcdea94cb1a Mon Sep 17 00:00:00 2001 From: joshslee Date: Tue, 15 Dec 2020 10:46:01 -0800 Subject: [PATCH 05/10] add timeout in search --- components/Search/Search.js | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/components/Search/Search.js b/components/Search/Search.js index c901596b1c..4791ebbd05 100644 --- a/components/Search/Search.js +++ b/components/Search/Search.js @@ -11,6 +11,8 @@ import colors from "../../config/themes/colors"; import API from "~/config/api"; import { Helpers } from "@quantfive/js-web-config"; +const SEARCH_TIMEOUT = 400; + export default class Search extends Component { searchTimeout = -1; dropdownTimeout = -1; @@ -38,6 +40,8 @@ export default class Search extends Component { } onSearchChange = (e) => { + clearTimeout(this.searchTimeout); + const value = e.target.value; if (!value) { @@ -54,19 +58,21 @@ export default class Search extends Component { }); } - const config = { route: "all" }; + this.searchTimeout = setTimeout(() => { + const config = { + route: "all", + }; - // TODO: add pagination - // Params to the search for pagination would be page - fetch(API.SEARCH({ search: value, config }), API.GET_CONFIG()) - .then(Helpers.checkStatus) - .then(Helpers.parseJSON) - .then((resp) => { - this.setState({ - results: resp.results, - next: resp.next, + fetch(API.SEARCH({ search: value, config }), API.GET_CONFIG()) + .then(Helpers.checkStatus) + .then(Helpers.parseJSON) + .then((resp) => { + this.setState({ + results: resp.results, + next: resp.next, + }); }); - }); + }, SEARCH_TIMEOUT); }; fetchNextPage = () => { @@ -91,7 +97,8 @@ export default class Search extends Component { return (

- We can't find what you're looking for! Please try another search. + We can't find what you're looking for!{"\n"}Please try another + search.

Date: Tue, 15 Dec 2020 11:48:49 -0800 Subject: [PATCH 06/10] call search on 7th keystroke and multiple of 7 even on debounce --- components/Search/Search.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/Search/Search.js b/components/Search/Search.js index 4791ebbd05..6bfb3935e8 100644 --- a/components/Search/Search.js +++ b/components/Search/Search.js @@ -40,17 +40,17 @@ export default class Search extends Component { } onSearchChange = (e) => { - clearTimeout(this.searchTimeout); + const { query } = this.state; + const ignoreTimeout = query.length >= 7 && query.length % 7 === 0; // call search at 7th keystroke and every multiple of 7 thereafter + + if (!ignoreTimeout) { + clearTimeout(this.searchTimeout); + } const value = e.target.value; if (!value) { - this.setState({ - showDropdown: false, - query: "", - }); - - return; + return this.setState({ showDropdown: false, query: "" }); } else { this.setState({ showDropdown: true, From 5ca4199692a421a3028511e6901157cf52eadfb4 Mon Sep 17 00:00:00 2001 From: joshslee Date: Tue, 15 Dec 2020 13:45:03 -0800 Subject: [PATCH 07/10] show empty result only when search returns empty --- components/Search/Search.js | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/components/Search/Search.js b/components/Search/Search.js index 6bfb3935e8..69d20308af 100644 --- a/components/Search/Search.js +++ b/components/Search/Search.js @@ -20,7 +20,7 @@ export default class Search extends Component { scrollParent; state = { showDropdown: this.props.showDropdown, - finished: true, + searchMade: false, results: [], query: "", next: null, @@ -50,7 +50,11 @@ export default class Search extends Component { const value = e.target.value; if (!value) { - return this.setState({ showDropdown: false, query: "" }); + return this.setState({ + searchMade: false, + showDropdown: false, + query: "", + }); } else { this.setState({ showDropdown: true, @@ -70,6 +74,7 @@ export default class Search extends Component { this.setState({ results: resp.results, next: resp.next, + searchMade: true, }); }); }, SEARCH_TIMEOUT); @@ -93,7 +98,21 @@ export default class Search extends Component { }; renderSearchResults = () => { - if (this.state.results.length === 0) { + const { results, searchMade } = this.state; + + if (!searchMade && results.length === 0) { + return ( + + ); + } + + if (searchMade && results.length === 0) { return (

@@ -108,8 +127,9 @@ export default class Search extends Component { ); } - let prevType; - const results = this.state.results.map((result, index) => { + let prevType; // used to add result type header + + return results.map((result, index) => { let firstOfItsType = prevType !== result.meta.index; prevType = result.meta.index; @@ -128,8 +148,6 @@ export default class Search extends Component {

); }); - - return results; }; getResultComponent = (result, index, firstOfItsType) => { From d334245f1873d367d21b4c7ae970298dee02d622 Mon Sep 17 00:00:00 2001 From: joshslee Date: Tue, 15 Dec 2020 14:34:11 -0800 Subject: [PATCH 08/10] add ui when user searches on empty result --- components/Search/Search.js | 42 +++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/components/Search/Search.js b/components/Search/Search.js index 69d20308af..1b17939f84 100644 --- a/components/Search/Search.js +++ b/components/Search/Search.js @@ -1,10 +1,11 @@ -import React, { Component } from "react"; +import React, { Component, Fragment } from "react"; import { css, StyleSheet } from "aphrodite"; import ReactPlaceholder from "react-placeholder"; import InfiniteScroll from "react-infinite-scroller"; import SearchEntry from "./SearchEntry"; import HubSearchResult from "../HubSearchResult"; +import Loader from "~/components/Loader/Loader"; // Config import colors from "../../config/themes/colors"; @@ -20,6 +21,7 @@ export default class Search extends Component { scrollParent; state = { showDropdown: this.props.showDropdown, + searching: false, searchMade: false, results: [], query: "", @@ -51,6 +53,7 @@ export default class Search extends Component { if (!value) { return this.setState({ + searching: false, searchMade: false, showDropdown: false, query: "", @@ -59,6 +62,7 @@ export default class Search extends Component { this.setState({ showDropdown: true, query: value, + searching: true, }); } @@ -75,6 +79,7 @@ export default class Search extends Component { results: resp.results, next: resp.next, searchMade: true, + searching: false, }); }); }, SEARCH_TIMEOUT); @@ -98,7 +103,7 @@ export default class Search extends Component { }; renderSearchResults = () => { - const { results, searchMade } = this.state; + const { results, searching, searchMade } = this.state; if (!searchMade && results.length === 0) { return ( @@ -115,14 +120,27 @@ export default class Search extends Component { if (searchMade && results.length === 0) { return (
-

- We can't find what you're looking for!{"\n"}Please try another - search. -

+

+ We can't find what you're looking for!{"\n"} + {searching ? ( +
+ Please try another search + +
+ ) : ( + "Please try another search." + )} +

); } @@ -326,13 +344,15 @@ const styles = StyleSheet.create({ alignItems: "center", justifyContent: "center", color: colors.BLACK(), + boxSizing: "border-box", }, emptyTitle: { - fontWeight: 400, + fontWeight: 500, fontSize: 18, whiteSpace: "pre-wrap", - marginRight: 10, - lineHeight: 1.3, + marginLeft: 15, + lineHeight: 1.5, + height: 55, }, logo: { height: 55, @@ -343,4 +363,8 @@ const styles = StyleSheet.create({ hide: { display: "none", }, + loaderStyle: { + paddingTop: 2, + paddingLeft: 1, + }, }); From 909bc7304e426cfe496249118d57e3661c9c65c7 Mon Sep 17 00:00:00 2001 From: joshslee Date: Tue, 15 Dec 2020 14:41:27 -0800 Subject: [PATCH 09/10] mobile styling retouch --- components/Search/Search.js | 7 +++++++ components/Search/SearchEntry.js | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/components/Search/Search.js b/components/Search/Search.js index 1b17939f84..f64b7f30dd 100644 --- a/components/Search/Search.js +++ b/components/Search/Search.js @@ -353,9 +353,16 @@ const styles = StyleSheet.create({ marginLeft: 15, lineHeight: 1.5, height: 55, + "@media only screen and (max-width: 415px)": { + height: 45, + fontSize: 16, + }, }, logo: { height: 55, + "@media only screen and (max-width: 415px)": { + height: 45, + }, }, searchResultPaper: { border: "none", diff --git a/components/Search/SearchEntry.js b/components/Search/SearchEntry.js index d64b29990a..5493c5087d 100644 --- a/components/Search/SearchEntry.js +++ b/components/Search/SearchEntry.js @@ -350,8 +350,8 @@ const styles = StyleSheet.create({ justifyContent: "center", width: "73%", marginRight: 20, - "@media only screen and (max-width: 1200px)": { - width: "calc(100% - 50px)", + "@media only screen and (max-width: 1300px)": { + width: "calc(100% - 40px)", margin: 0, }, }, @@ -392,6 +392,10 @@ const styles = StyleSheet.create({ display: "flex", justifyContent: "center", alignItems: "center", + "@media only screen and (max-width: 1300px)": { + height: 40, + width: 40, + }, }, smallVoteDisplay: { height: 40, From f22036c3044749a63d7e7f070c6f1ad2577b35cd Mon Sep 17 00:00:00 2001 From: joshslee Date: Tue, 15 Dec 2020 16:00:46 -0800 Subject: [PATCH 10/10] add numeral to searchEntry score --- components/Search/SearchEntry.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/Search/SearchEntry.js b/components/Search/SearchEntry.js index 5493c5087d..d79b78244c 100644 --- a/components/Search/SearchEntry.js +++ b/components/Search/SearchEntry.js @@ -2,6 +2,7 @@ import React, { Fragment } from "react"; import { StyleSheet, css } from "aphrodite"; import { connect } from "react-redux"; import Router from "next/router"; +import numeral from "numeral"; // Redux import { MessageActions } from "~/redux/message"; @@ -257,7 +258,7 @@ class SearchEntry extends React.Component { hideBullets && styles.smallVoteDisplay )} > - {(score && score) || 0} + {numeral(score || 0).format("0a")}
); default: