From ff4ee494b69d62eb2dcea86ab9074a187e50477c Mon Sep 17 00:00:00 2001 From: vivek12311 Date: Sat, 17 Feb 2024 16:03:28 -0600 Subject: [PATCH 01/20] Using React-icons. Probably need to take out later --- package-lock.json | 9 ++ package.json | 1 + pnpm-lock.yaml | 11 ++ src/assets/logo.png | Bin 0 -> 13866 bytes src/stories/components/PopupMain.stories.tsx | 23 +++ src/views/components/PopupMain.tsx | 146 ++++++++++++++++--- 6 files changed, 173 insertions(+), 17 deletions(-) create mode 100644 src/assets/logo.png diff --git a/package-lock.json b/package-lock.json index 1599b14b..686431a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "react": "^18.2.0", "react-devtools-core": "^5.0.0", "react-dom": "^18.2.0", + "react-icons": "^5.0.1", "react-window": "^1.8.10", "sass": "^1.70.0", "sql.js": "1.10.2", @@ -20112,6 +20113,14 @@ "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", "dev": true }, + "node_modules/react-icons": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz", + "integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index 4cda8c17..11366e9d 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "react": "^18.2.0", "react-devtools-core": "^5.0.0", "react-dom": "^18.2.0", + "react-icons": "^5.0.1", "react-window": "^1.8.10", "sass": "^1.70.0", "sql.js": "1.10.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7795c182..d94f93c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,6 +43,9 @@ dependencies: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + react-icons: + specifier: ^5.0.1 + version: 5.0.1(react@18.2.0) react-window: specifier: ^1.8.10 version: 1.8.10(react-dom@18.2.0)(react@18.2.0) @@ -11193,6 +11196,14 @@ packages: resolution: {integrity: sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==} dev: true + /react-icons@5.0.1(react@18.2.0): + resolution: {integrity: sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==} + peerDependencies: + react: '*' + dependencies: + react: 18.2.0 + dev: false + /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..294a3dc83445945b466b9f52c9e484a9015ff109 GIT binary patch literal 13866 zcmch7WmH_v(k^a6X3*fnAi-UNhJgtV!QFzpy9Wpv+})kv5Foe*2^QQnc#z=1@8mt_ zJKtIN{=a*zo~qqX)l=PFy?eU%+TqGd(l}UTSO^FRII=QORRjb?FudSnpuuZ&`WMI% z5U}4^OG+xsN=ky1T^uc}?aUDnWWtlR(6!ZuiF5Q4;>0B|K_L1|2AB*ch(459+~+GW z0U^KtB?hyHnMzM%o(Up(D|5kuwMYMW!NR=>1foOo!ed7fYrnO|@6>O7<$gVI{9$jj z#dQQBFCdtOcrT9(VLRfSo~!36s%V=K?K3$@oFEPX`A2iR2p0=8Gle+0$n)yjYS7w` zYN4Tqr^RO@#YB#wpNK(FNY=o_&m9Rr0784jtCVeI@uag|wTo}u*yKM_x>0Bh8T&}F z^y&MovD&px2uS+Enu!pI_}H})5D|{Kw@FdkvCAO8LKbBENg@!GEya%#GlkRfoSFOi ze@J83DdeVKhbRrK^G=8HwyZ?aRHj9)s3V1XZ&93FK7XNjUUqRU3gN0WRvSqQ?H}63 z{^h~q>yn0D0a;;@i-d)0zu3Z)=v<*TNlIYC3D^2l7}hSrUrGAo<3jiZ4o1iVU<;(8 z1Z_@uCr^Ur3<_gG$z~Yc>xWdLpGiOrjVq@t6U|(rxQTUh+24OjdJwFJQfU$Y`oJrk zQ#=!x&9uRI#ije+LLb~u2xG$v#RLMTK^~(cF*s^>QB0#|(%5%0MO^g{Y@iq*EclV= zP8-rn$0&7Rl#wa$+Q?3=B#t1z|NesKrv%|ukFK}A_mdO*g82s+(VH^bA$ct7tQSTA zKv|mb92?-TYN%PZQk?cH|4G54bxcZv?e< zzh+$_k@EP+s+az?k~u23;h8^#`Xp>B_6RC9+&2_pmYFL(b!1g7$y~4dtWEv4+FJ6; z0`Ka9BKJ}9>h?Fq^_N#o0O6qQZ%QV6b+p>Z#>RtnQk6Ku%zcs-zry|8aik*S_Y!g3 zL!V&+UY6#`qps!dht78e`y(U@i5-QAzV%+M(6spU3F97);GiDh8HF@wR(6&FLY%)5 zVNH#|<}*6N+8{a_8gAg8L@aXc1f|%M;<_L?!-HEHl2di~t7JmP*ZLly z?ysRjep8npxH!@Ioy5kwal8=U05BvVbTH&$WALaLLA5Jp8kR+{cOFX82XkX0ZFK%% zHe>V!oa+!YCzLD{%kH;Mr26Qdn}-KT9OBeo=wh@O5)x$?l#|j50Qr6@XQ?z89zHCT zmP>{^A;Js(&aSYpZE>s8N4zzgjRNH*#nBSE7)XDiIs(!>X z5}4<|x1tb291}0i`)I}0ieeC=S=jc&=aS9`*b(DV!0{sh+qgW9-6BHJSRpFL*L+Hof`O@gqY4@))%?IWu zz-eC>una{qShOdxn}!a^jiH7~ABxq>-%HbL{fE^ZxCRV|8WiwNQi??m_p@$cZ<%cQ zY*B4tnxLO?)#XCL2Z=|rYeh2nsY&mcX{zXt!IZBIXx!t)%F4>q%3fEXd@d@3sYj?Y zt9z7FsI?TFE9~&-gxJYm(@7`XZXawHZ&z(woYT9I-159lG*LV&=~t;|ykN9tbWfU2 z@=X#bFE6(!rz)Q;mzZrSw^hF>&r$O)yHin=A5)61;x|+*Z-UylEnzk;+c=h~mlMs# zW=M>cvggk!zf+-Be)D6WSDNh8Ks9#S$3vn+^cjxNH#Tv6 zmAngN`q7JI$z+OT0(^IT2N{LDw0y37B(^6rA~lOuZ>Q>~ux7SwiEQmBg^I7zVkXB9 z?1W;)ayyd)GS-R}XPV}Att_omtxxA1=1-<4r<^Bcf25bFeRfqZRU?^hoZ8vn-DjU& zt?`w-ndU5fU->@xePq}yP8;`8$C{Jq8_^GjpVz25e);5HlHPr|Tf7^&BELK(-$3&~ zn?zH?;eVOMzfV~$x?=m<(d*#%W8dk^f-sLTt}q_#uP>WOugOWtQOU!j=g6|T5BcW! zu6f3}4Xyn~n+HQ3woJjiI@T^L+k%pxdQ7%C=Qwpq{Y%11Xi8M4$4ZV%a>pviw#Fhx zuhUiqO4E48rpL50zNX#iq-jSrrdg}lIu9n;4L6K7=-YeGop&TRY81>ORiITk*oxZ5 zxaYf9U5S#HN7sxIX4+)hHbM1D?3<2#mPb6wvMUTq42oCjeP`Cj46VA>I!#gDhYn&) z!VZA~lrt3CxTv^|xOkNAlzo(u6yy{}F%2)%xm|9DzR-3Fwg~OKws&t8ma|pgFDp

M{d7QDz}$*zemiNPfkwRHQruf=}Nj+BbS{#E~=+SGugxv4q8-PJR(dA8-MS+BXY zRjXy)%!a2hEi!#i1cT~{%2g!B%kR?dV)SO^^fom$M5}3Dspf=h&J@M8DaQNAes}C@ z?P&F&@3-vL;`a1`?cvB()wTb&<;md9^6pKP`N(&ZW0Q_c&-2tj)aQW{*JcwYxftC@ z!N_vROUR8#KauBA#W1*Ee8(uqIeg)PlLPbvhXU}4>qWL124Q_aXPoXNRwXSzHidou z_${pJg)gB42|K1ERb&hfWt+)S2gV473RIE~whgU@wNsl@^3fkU@p1_^sh?{tuSWXQU>By2K;v{?=j%F%K z3Qe+Sdi;qrSVcC^x909Q{D+*N@|8lSQ$Rsae^$8ktIzMYl!W5sWE2%v)9*f#4_ED8 zmpV_CPu+Rht=X)-=%fy$?~>kNVchzzZHV%n0@=0tq*>)n{OWU}09nH`c!EdhL%bENWIER}==o}>s zO*{D?;vEy0WCG*GSbsB>vHs!Ydw=-BI%66-y;QQSXvF)d^Imz=k>@vQJ1HBFqUCtz ztrM~B-0tGgQNtpe>*yZg#6bqRi07cl_x2<2E)qeaWRi~T+}B+#3uRsoXFrXC13$Cn zC(Fn=u>aPrb*AZ5Zm#v8+<$9J;?J^^YRKryT)}u>pZ4`nZ%tuQT@TZi({sw5jGd1=v070EDqRV6^=>=M8i|_OHBO%wnltKkTU%Wf|6~j_65FO$ zJ=U|ku3pJKe;3sV(}*lztJ$mRs_$`>T$L(}HYa~$kMGdhDCp(t->BjKjd&|1nC;zH z20PJv@{6w-_GruBoBUVVm)2TnEu?LueHF))`m*J1Cv~muC#uid*iUg6R<-w(zk0`> zgkQmp*}(81TcYksj+~Ht6<=%PquauPt7Y(b zme7ch??cv23+Mm*`8rqdD!ycw{lTUvPF{X zEB`d}@a3?0Y$PP`_HlMDb!Prb?%ZbMYD?hGv8l`5dwGg__IbnLq;29<{>^^i!dd+7 z*->f#y9u#(j}mwFyA{XtyN>VIPjI$zv0*Lv)el+-AvlWf&^N9;5Xy!Ter!HPaVyn5 zCz2N|eEAOi^G>@?Iw_MJ!TtBMXe-In>I#bSsb=$I@ZI50L|6e5U=Q)fWZ|c!4MWAw znj})-2{QjTKgAJ6nv52?61gH3G`NZIs~h?-d6xe|`QXkrToY(BXIZ z@Zyz+^gq^!;5_92=zlQ;h?=CVEL^IYx|o|gxLP^7Jy~RL!7DJGWOQ5+5Qypj7DQQ9 zy5DgAIcs%oH*G})AyY?t_V;FvCg$v3_D+9!5JbF$;Htg3+k23gy`6)rke4X<9}6M4 z{Eai7^oCl9-$izNq_pr9ZJCpQN-Hyhl7&DGn%?Y$S9gDdU7NdAWhYVK<4V(sK+?dSmd z%lqEM(cMiH4E`JFKi9w7Y3^nHzmXhV|J^Nk2RZ&C99-<29RJ~lyNdj+6;ihLGPl!# zTHC|N3?4&_TYy*OAN&6Y`QM2D<*EH&o`RhJ?fGBG|Lv*aYVIQGXb%tRCicJS`nU6c zga39E;rQG0{~C#Z4f8*>@NpKy65;qy&cv{yti1kCFA8huJ9W5(PqKfmaQH7Hy!@5$ zg1;#^E_Mi)RkBcsx)lz0+9x2Tf`OeH|?HT^^m1G;wZ%m z+pdC!h&pWrwRx+|@(*ORa%AB|ic4r*pQ9I4S@7-E0XSG?7zH?=Pi*3XN+O-DgJp&H zHiv#5kNWaBKJ5jJJ_szf-|YSz&wg&X5!lPQ=R$wvxZ`;!L{bmJdab?z3LeV8Yv(1( zLvlyO028Ayi=$?-hyw%#5P8H=%Mc*_+;9=(3di;sjM2&vh(Ivyzrv{+0kXYH~R4^9m-`763xkWk`X2{@7Au>erkzv8u45Xi*=$s!0#88H}U{#We5 zv2jI!1KM>Ac4i0l^Q$woR@~gQ=4|rM;t5D7DhbR)E5wrKUcVbL*!wKZ=9M3fiWa{7 zTHO!yHAwEDrQJ=8f8JHKQkZDIJ2Uke2)y%7Iyg)>#yugkZN*KUkQ`eGe>EGpCzpnv zDuoza##=J#L5q~N>1i1GB=9zml-Jh-H+@yo@onBMryf#-w14%li;_0}VG5C5z_jQY zblUadQYZ^W^?~IpyfNX&%NW_4J@aFq^o-7tUVGEWBF-8J(*#fR@-%sd~*Kc>m+~K#pcPwyhoo+86aaXu`T-6_%K`ZCJTeXvLr}94W5O4 z_W1bh)0c=7_vD%>WFp6e#GI6Kz9poAO9Eid?9~&elN$xZ;31w6v*Gb-0nPc%FQ$Fd z5dOyc71MarA|}uNB-g{WsXxrB13d~(9iFtrI@ zg1b%r%#M*YgR>lFD#V%J18 zQHeP}`2l*NX3eZrE);UirW%TFe3sif5x$}i|t#nzE@l8Vf zAQcR75X>20BLaEYuR5fybxV)>YH=9JrVt;~82P94OIjfGCFL*YydQ%|-<%F|oU%v> zs9R!UipvnXd}VtG+_Oc^fb`F+pf%YF9z*qSJHvdJt0|9pf7U2s`i zz|}0S0Q;?ulWWhmEc-?Ez#M}#ZG`PO2|0oGv7X?0;~joueU7S?nm)?*;8=Upnm&tm zC9|gxM7?`^iu}4}kcu%bI9shacnH6;-Y~XumSF1c2hywX7XRM^x{fIg_Lh94`TmDT z>(1Y0g!9R+37|M8W{=EudG3(``;8=Y$q-G>q>sH4NbiKn`wge>f8}xt^LH+sI9cA4 z3V(kk3Q2lbb5~E{DC$v@N}z@+W|Zaf;q#S&N_tM#@h>fCWWVUkUv|8FI&65i`3}KxPJ3>Lm&|6uHgG6qW*l!9}3Io}2 z=Qf|)lIR~EeQt47UdfWX^5aYIUV29zztDy)H;rt=8M;$b{h=Sk z54qHdr}jIc`Qp9k_v>c}M&5+N#zW-D%LJ6VE|+hP*|r zrF_moaCHzJN3h6MX(WpvUEw*%h091`Z92f@*(3`{GRB&x(;A5EDl?0JL-sYBQa^DDt0_pQ`d{rI`w-~c{E=+ z9n4OmtkN)!*I?<vb*oGrmu2dK8o=U(aYKS zNNZS^XkbD4Y1}TOs4XJ+gef!OR=LGGARB?E9Xf~*K z`oCy1AhcfGGrxd}Nb9}WmW^^=QVg{Ha8c{2fdu8&KAS}kD0X1_EYivM&5UjTn4^ZX zt*M$%m|w(pbr}-QPUPHsc{(S`ux|3MDZ_^Q#P0h$;zGJB=Ip5unG7m;=1U9_i<#zp zhZPM)T7G`qU)K*Poi}_}$_EL0E++lb5j@qDd?UqkPg0TkrCtf0i4SIX78}=0S1js4G(20rXltUj0 z)!zoyuV}|OFuOlJsSYY(*|)jsPizt_+dVu|%zlj;lKh>u{Ip5fdVCaT8OQ`FT2!R29pT=na|2DClz5`jATbIDWyHE+(j8MZ*1P>m#ez~w>Go}2I50k-#^em7;Fu{#SD)A zsk_?IX?#!U^ShN7wB+wH`fY%1uxvCMLOl6sxj^u(9n6TF#k;y*K-=d~j7hjfykbTMGjSE{OXo;L0D zba1d)0j#4*5_(K5aYXFCrRm<}srItOl~sk0Y$3jR^Sr!U*hAA??t-_s_Jl2BFoqI> z8qYhN)46HOyp$z&L&fvd5UDX0Ly-L7sPB?}xPSUb_hGa&$g8h()UZtKqr~^1xe*b2 zAJ5wvMKK|5fHmK+or1A@9mu!-wxux{iJ$q4MHEjFgKivX%4U2)TVrxIl0r}8^@+Sz z_dq0Gap~pG+xb$@VYh5~Q{rrJoiVX@8xZe41FmGfxRn1|_(A8v1X{|1R)3*XU9)P?JH!CKhFXB^_H8l4hn4q@t4P?i|z=Dz?+8l4Vl>ri7S$oUS6~(u`HAV1E1SWhlU%y+iXi+2fCk zVU}}zsFkA(t$1{RguCI9`#2pe;-I|F55wo~lh<34)vqlJ(ZS=_xX}Hy$br{*Zd8z_ zPzFf=QL370@w-b&UE0`e#yv{d59C!|i@CxVlCQ$1#XfWbhe( zTn#$Br~fh0{x)d{?*&Uu4$?@`ug0nlL?E|C-lSSsltGVNtce7CbEbbe6j1c3+WyqT z#s|5;(m{-*$&Jy6kPkoM7<+3Z;5b-TF;b6=Qq7&T;Tj3LZ$auq=sw#{^BIhy;;c+p z98`TYG&#pEt?P?epeXOi`*+b9c4+yU-zNXHN}r;N+E44mFEjuNQe+BgsFtZ2+L5v4 z5D&e49rrGa*?nF>OW5tBwNh7v;umdXGty+<+-4u{N*3zuuYYou{e{qhE>GC4BUFoT zm&O5|$FE?Qtl&hGiH=9o1=P45!qv9aD~9Y4j73(-CTG66pkW(A>KIy>TUF4dNF0~u zWuHhz#5g4Mh)ojhbH$2VT(2a+yh)~s8+`BPDgkn*g|Js3Qm!w*HkhKp-#58 z-H*jYb6AYoj{J-p<1Wfv=ANcHonem(eH8m?hd8~4_1g*)OnEhCNG`;V z-GVEqW)Q@u*eV@tmCHP20jT#bIl~VsasfEHqJg)?S|mYQ)6j-IgpfNUdgOFk#9+KgCJpN6j-j46Vm6F&uQC+#_p1_$QR{e9U6kK6nb>r4j)0cT;H$ zq_0ybwO?ZtAYavueSPNxW=z2{R*Ue79wkXJKRWll|fvz>9QI$h)w{#jt=pw zE!ct%EoiX3tqQ>)Et86-mT0N33dOajhM29J4COPHZF0%HZc?2Qf+<7ZZwIj?P3mG& zE{O#XMSoMy<|uRTj5E#BWwN1!ieZJinCkrp+eA~hL^%JjE~oMfB;ie6HXIy{*4(FbzO{>q-1-7UPY^tQ;=>D;Ndr>40A4J^GA--}Yr9uSQic#;kj6 zIh_n1o8pG@*Fs*Uwm|-|sU$A6oez1uO_LuTiJ+Z8vYmW-BBq0Dig{r^Yc0TXs}Dok znmpRfIr9=;b$~XTe{|@ZTd$W*13ncG`62-ITd5}Tsgq@9nDU4B>hm4DFdO?=@L1kT zb!iYA9+}3O%55W8$`Bmx;ZY}~{!8v3%qW{&`!%20LzqaJh`J?=uiTaKcp zN9o4U$?E^hW)UgAEVTSj+4xKKcZRx{WxOzDV+H(Fken+0kv%`;FSKK?d@IX>s0rE5 zWGq88lHK}y1`X{PV}L0md#IRGBOXN&faQ{Cvyf0Svvf@)i~?SBEQePxEUf*_0}V7FR+P0x6)UXa z1ra1kbGvu7+Q5P=84_JBTbiq{RqU&dl+1nM>-X!J+p7~{i5d~UiYzgS9`qWq2=l&yzkJJtXQv<=4+H&Yy{ zg>jA5w$K%XUpR9A++$aoW^%pFxvChg=JPZc>xw5xhLJ&7sP|gIV9oXS!y|M9yz;{I z;5p`r>0Q5N1sx~p45jpu8%N)%_Ng|yi`(cd7|{m7?(obijAAS&au{KtQc?H5Sq9DH zP42aO+>W+yldWQGv)wDjj_$1IpR;UVk^PKXAJN(7UF`-x?ZAr=7@E2^<>c;ozCB)=OsR+$4t^o{OiMY7RF-QSQAeB*KTtFT?mW z#xp2Pysa7m?sCx4y*BOXa8}b*9O>Pw}hT0q!(4O@{9FCX^}d)r&;B|w$=TUPcg z@>v8xSH^y<06KwHCoTzpjE1epwjdDRMyjUC7f(A_u~m+pq|hzh``UbMV8Cm$_0I`4=Xd%us@L zLsK%nAq+-TYaw;1!>!Sqx&BTL>R>9=rooVTLda zi8}2}?|pS=|VN$*N9(Bg;+ODXOlOrZxS2`w* zWK^c=R>Z`Isxln3n^D55c_sxN9TK}ZFs97G@g%1&U`@r_qnNA3o~osCGpDB>jfjKu z41}ja_$)x86+j7*ci}_P8fpHizOH*B7b!$<9ib?QI&0`9XO=hZGT!$r+a{|T%36j3 z^k9J$)3G}V-MI$QLlYnCvYNHsWSBPIE=0BjlI}9gBVM-70vy&0qx|%KReaIK95TfM zMVAE=?f}Tm0kDhI&gPu zqXb)rB4RwjCQ3hfatSTaroWKU7F{I4%&K}W!_p#OrpGGs1?RzW+=&GeybJben2N;f z)M)cYC38b*6i2Ip`Zwh5{Rwqkb(dVM$Y^Wf7!tK%mSvF#n%t+nacu80@#C`^$J0Ec z586!xs}MC$XfXQa-cFUdKmb5juYqw!EzKI4@UlsHrsZ2ZN0?y2Z$4J!zaY87Zbm`< zcpekboHj*j!ek)q2mgiCfvq;0XfOzj(MyrTl{@sw&O8gE1`gh7A@?nbq7*U?<0E^^ z{t|3rcw`rnI?196wz*U-4-{J_Hwoiim{;)UWuCwYgQfNHlnq&U?v6r>F?%11p#6<6 zTzlB)`o_){GcEtF(oDg36e*Ao#xRWD+8j|y1AG#EHL;({Xq34*S6q!N zU2WvA-p<0oU$_U_;OpLj7|J#qwC6k+239SHTay+FsgAXSidI=BK5&p5Uy`asfDV#0 z1|p#V_OR%7S?Th$(mhFS1@{7u7jpwUesGv2b+b8ut_?&DJsAh_CAqJog-{$ZuCZcZ zAVOirQ3d)Jx3$MQfi;VbC6<3A5uaIrjTY*d?~nz$NgTTp_|?#G=tY_=;$9@c7SwL{ z2}#zQ!c%%Ck;WJl^c*pK=?iwNf}RHa%4X$y_1{Jd`M+D#>!`&`fPr4#gDq>C!lI5E zDav?~6vNBBRPzp*??$#)pH9Z35c#jfmBV3BaBg6oML z>^OiV!6lEGJMdG> zdJ?QYQ#m3Ogm}@TS)pRJ2H3{Rfzh>tJeP@&>5EBtESZTAk!W#{trl@5u@#mD6w?o&HI zg~|XeBKcy?b4VZBxU<1!xj?E3ax=9P= zGH!ojlQMDGw?+~MLx^&tGNU#_2|m{IwM@EoMqa)yuE3K_btS%riIv2oFo&56&sP?` zskL8rAsuP3ufO>S1_#lSa!5R~n@U+tIDm>M@g9aKj+U(>-Ex75*nJG6dPl4;DM{qH z8A3hIDM%uIs=o#YyWo>j{>-}t(+&l_?i-)|dMGi}3{j1-r@;8~Ub?ZdG>cw~RZtl1 zbAE0=OZ_%Lwx%TxigNnl(PqsC!=Rd{+<`n7_#?pexMoID4q;FL5kfcYE}?0jDvxWI zsd_Jg5A06B#Vv>ite8a8^x*fA2mdG?e~39qYwRZWUX=fYo~OPRGCdo{#0rF{9Bl9{ zA&|$JU^tr#U*Re7FOfR+U>~j7;a+yoiTPQnHx*qtZ)WozPgxDQzrPe185z|| z&_ClQfmk&7Nh%xOZw7R1v-=@dHCbKf=){GO&BS_d{N&Q(%ooBhmtKX4^^hh z9vy5Oh+DUMFrVKGC_}=IY`^uYuBjBLP$h`(fa#BwEMC`2f6C-M9k7BJdbVrFB8wyR z+zDu|ANhq#>d0a+Xo2qn2R$42>+Xak_g-uQ<84~L|5+U59Np5lz(+!pgEqZ_`Wl&` z0ONFvF3xigo!Bh!v_64AMMr;b2BiD7q+cCu3nxk@C{)7_SLJ~9FHeSFY!%;Wd~S=C zlR2rqRuunnxt;Dh+VCsjm(qc_o+?<56Watu&$s5RbxIqPsfV+u0Dyr}PRN!l&9bWk zmV->pPR}rn1sY;Y95(MWpE9wFkuVOT=K}yGd#}cfc10akWlGe+>9g2Ur-X$h9!*EA3+Xy)tG?AGz2U+r2R4BTyC%!Kfk?8E6S+?Ro2Ivxi`Noe?7K; z^+&$aX{kJZmHp|fy~5*Wd4#la!Z?d*I=+fj#V2m{$jBF}y}CtQmg6&vO&BlZ@V0#O zz1}$M5ixbS>2u7%kG#k-!BGR)LK zgTC?_T2o3e>oGjxyE6g#!fjxZjdU8Ek~~=^?hb@%83`kc0>+|A{Z*&m^tU(BcK2A@ zY5(+l$v%G5g10|%=o8`4csW*>b6@yy33j~Nee;+4C-n!BxN+&n8tMLvV8MqTG1rYT zt&l6Pgzg_fZurbs@Z=qus^4Jii&RgA%@LIh6L4lps`3ETm(yZsg6oGz(ry!o^BSV2>aEF}kZfuV!gc$3Sp`vUR0Gco|pwVGhnI<4k&EYws^i z9GW1SlT?mpS@xd}I828dX7pg1IEaj%PYtdGS9V-RaV2qIE#?Jr=9#M_WAPKd91Bo3 zkF4U$P+wzOM)7MD#B8xrUszC@^B2`1EooW$0wILDPE83DnuAiRXyoCoYA9XgY1vY8 zoD>A#?L&#Fvndt)DDgVh<}Ic*AsvK>5wV5u6Mnp2yL4koC@&ViBPtp4IaXLytxs@@8Ks&k4H%N*Kc? zB^&&HxpOQ~mBX5ldyJ&)W?IA}p-UZ{08LdFXfJ~AXQE^dxC}sxC?%j=H46_Sel|IR zIFuU#`hpDwRXtFg>hpzdfxgIQk$4qbU9MxY-^0e5U4`M(uj_;#5Ii6*D%#W!fk!Wij5gKnTK5g&Xfr- zzS)JP8Da?)+h}fA4#Jm7@BQ!__!?*a_&JB?Z{f_3Llz_&P#%;pm`EM%ZQeGV>;EI| aGxDD$M2S^o?4iG(#mT-^f>uiy2mc>6iIWZh literal 0 HcmV?d00001 diff --git a/src/stories/components/PopupMain.stories.tsx b/src/stories/components/PopupMain.stories.tsx index e69de29b..dc452909 100644 --- a/src/stories/components/PopupMain.stories.tsx +++ b/src/stories/components/PopupMain.stories.tsx @@ -0,0 +1,23 @@ +import { Meta, StoryObj } from '@storybook/react'; +import PopupMain from 'src/views/components/PopupMain'; + +const meta = { + title: 'Components/Common/PopupMain', + component: PopupMain, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + + }, +} satisfies Meta; +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + + }, +}; \ No newline at end of file diff --git a/src/views/components/PopupMain.tsx b/src/views/components/PopupMain.tsx index fa97323d..bc437c96 100644 --- a/src/views/components/PopupMain.tsx +++ b/src/views/components/PopupMain.tsx @@ -1,24 +1,136 @@ -import { background } from '@shared/messages'; import React from 'react'; -import useSchedules from '../hooks/useSchedules'; -import { Button } from './common/Button/Button'; +import { FaCalendarAlt, FaCog, FaRedo } from 'react-icons/fa'; // Added FaRedo for the refresh icon +import { StatusIcon } from '@shared/util/icons'; import ExtensionRoot from './common/ExtensionRoot/ExtensionRoot'; +import PopupCourseBlock from './common/PopupCourseBlock/PopupCourseBlock'; +import Text from './common/Text/Text'; +import Divider from './common/Divider/Divider'; +import logoImage from '../../assets/logo.png'; // Adjust the path as necessary +import List from './common/List/List'; // Ensure this path is correctly pointing to your List component + + export default function PopupMain() { - const [activeSchedule, schedules] = useSchedules(); + const courses = [ + { + uniqueId: '47280', + department: 'BIO', + number: '311C', + instructors: [{ lastName: 'Fritz' }], + status: 'OPEN', + }, + { + uniqueId: '51180', + department: 'C S', + number: '374L', + instructors: [{ lastName: 'Baer' }], + status: 'CLOSED', + }, + { + uniqueId: '60020', + department: 'S W', + number: '310', + instructors: [{ lastName: 'Whalley' }], + status: 'WAITLISTED', + }, + { + uniqueId: '13190', + department: 'PED', + number: '106C', + instructors: [{ lastName: 'Rich' }], + status: 'CANCELLED', + }, + { + uniqueId: '44435', + department: 'WGS', + number: '301', + instructors: [{ lastName: 'RODRIGUEZ' }], + status: 'TEMP', + }, + ]; - // TODO: Add a button to to switch the active schedule - return ( - - - - ); + // Manually applying colors for the demonstration + const colors = { + OPEN: { primaryColor: '#34D399', secondaryColor: '#059669' }, + CLOSED: { primaryColor: '#818cf8', secondaryColor: '#4f46e5' }, + WAITLISTED: { primaryColor: '#F59E00', secondaryColor: '#B45309' }, + CANCELLED: { primaryColor: '#EF4444', secondaryColor: '#b91c1c' }, + TEMP: { primaryColor: '#fde047', secondaryColor: '#eab308' }, + }; + + const draggableElements = courses.map((course) => ( + +)); + + +return ( + +

+
+
+ Logo +
+ UT Registration + Plus +
+
+
+ + +
+
+ +
+ MAIN SCHEDULE: +
+ 22 HOURS + 8 Courses +
+
+ {/* Integrate the List component here */} + +
+
+
+ +
+ WAITLISTED +
+
+
+ +
+ CLOSED +
+
+
+ +
+ CANCELLED +
+
+
+
+ DATA UPDATED ON: 12:00 AM 02/01/2024 + +
+
+
+ +); } From ae32d0b645cbdb034baebca218b5b5ebb68d8752 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Sat, 17 Feb 2024 19:09:41 -0600 Subject: [PATCH 02/20] feat: Derek/export png (#95) * Attempting to use more lightweight version * Did not work. * This is not what I wanted * The image saves correctly. Needs padding * Padding !! * Removed downloadjs * Padding more --- package.json | 1 + pnpm-lock.yaml | 7 +++ .../common/CalendarGrid/CalendarGrid.tsx | 49 +++++++++++++++---- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 3a3cd1b5..c0ea5789 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "clsx": "^2.1.0", "highcharts": "^11.3.0", "highcharts-react-official": "^3.2.1", + "html-to-image": "^1.11.11", "html2canvas": "^1.4.1", "react": "^18.2.0", "react-devtools-core": "^5.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 452e870f..8aca9fe7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,9 @@ dependencies: highcharts-react-official: specifier: ^3.2.1 version: 3.2.1(highcharts@11.3.0)(react@18.2.0) + html-to-image: + specifier: ^1.11.11 + version: 1.11.11 html2canvas: specifier: ^1.4.1 version: 1.4.1 @@ -8663,6 +8666,10 @@ packages: engines: {node: '>=8'} dev: true + /html-to-image@1.11.11: + resolution: {integrity: sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==} + dev: false + /html2canvas@1.4.1: resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==} engines: {node: '>=8.0.0'} diff --git a/src/views/components/common/CalendarGrid/CalendarGrid.tsx b/src/views/components/common/CalendarGrid/CalendarGrid.tsx index 5d9742f6..73848a3c 100644 --- a/src/views/components/common/CalendarGrid/CalendarGrid.tsx +++ b/src/views/components/common/CalendarGrid/CalendarGrid.tsx @@ -1,5 +1,7 @@ import React, { useRef } from 'react'; -import html2canvas from 'html2canvas'; +// import html2canvas from 'html2canvas'; +import * as htmlToImage from 'html-to-image'; +import { toPng, toJpeg, toBlob, toPixelData, toSvg } from 'html-to-image'; import { DAY_MAP } from 'src/shared/types/CourseMeeting'; import { CalendarGridCourse } from 'src/views/hooks/useFlattenedCourseSchedule'; import calIcon from 'src/assets/icons/cal.svg'; @@ -38,15 +40,42 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren { - if (calendarRef.current) { - html2canvas(calendarRef.current).then(canvas => { - // Create an a element to trigger download - const a = document.createElement('a'); - a.href = canvas.toDataURL('image/png'); - a.download = 'calendar.png'; - a.click(); - }); - } + // if (calendarRef.current) { + // html2canvas(calendarRef.current).then(canvas => { + // // Create an a element to trigger download + // const a = document.createElement('a'); + // a.href = canvas.toDataURL('image/png'); + // a.download = 'calendar.png'; + // a.click(); + // }); + // } + htmlToImage.toPng(calendarRef.current, { + backgroundColor: "white", + style: { + background: "white", + marginTop: "20px", + marginBottom: "20px", + marginRight: "20px", + marginLeft: "20px",}}) + .then(function (dataUrl) { + var img = new Image(); + img.src = dataUrl; + fetch(dataUrl) + .then(response => response.blob()) + .then(blob => { + const href = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = href; + link.download = 'my-schedule.png'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }) + .catch(error => console.error('Error downloading file:', error)); + }) + .catch(function (error) { + console.error('oops, something went wrong!', error); + }); }; return ( From 0acd0b722ce9d8b6ef690295a713998071c6f745 Mon Sep 17 00:00:00 2001 From: Lukas Zenick Date: Sun, 18 Feb 2024 12:46:35 -0600 Subject: [PATCH 03/20] html2canvas -> htmlToImage also fixed derick's bugs --- package.json | 1 - pnpm-lock.yaml | 34 ---------- .../common/CalendarGrid/CalendarGrid.tsx | 66 ++++++++----------- 3 files changed, 29 insertions(+), 72 deletions(-) diff --git a/package.json b/package.json index c0ea5789..e70a900c 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "highcharts": "^11.3.0", "highcharts-react-official": "^3.2.1", "html-to-image": "^1.11.11", - "html2canvas": "^1.4.1", "react": "^18.2.0", "react-devtools-core": "^5.0.0", "react-dom": "^18.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8aca9fe7..fd49e39e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,9 +37,6 @@ dependencies: html-to-image: specifier: ^1.11.11 version: 1.11.11 - html2canvas: - specifier: ^1.4.1 - version: 1.4.1 react: specifier: ^18.2.0 version: 18.2.0 @@ -5859,11 +5856,6 @@ packages: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true - /base64-arraybuffer@1.0.2: - resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} - engines: {node: '>= 0.6.0'} - dev: false - /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: true @@ -6556,12 +6548,6 @@ packages: postcss: 8.4.35 dev: true - /css-line-break@2.1.0: - resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==} - dependencies: - utrie: 1.0.2 - dev: false - /css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} dependencies: @@ -8670,14 +8656,6 @@ packages: resolution: {integrity: sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==} dev: false - /html2canvas@1.4.1: - resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==} - engines: {node: '>=8.0.0'} - dependencies: - css-line-break: 2.1.0 - text-segmentation: 1.0.3 - dev: false - /htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} dependencies: @@ -12437,12 +12415,6 @@ packages: minimatch: 3.1.2 dev: true - /text-segmentation@1.0.3: - resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==} - dependencies: - utrie: 1.0.2 - dev: false - /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -12985,12 +12957,6 @@ packages: engines: {node: '>= 0.4.0'} dev: true - /utrie@1.0.2: - resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==} - dependencies: - base64-arraybuffer: 1.0.2 - dev: false - /uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true diff --git a/src/views/components/common/CalendarGrid/CalendarGrid.tsx b/src/views/components/common/CalendarGrid/CalendarGrid.tsx index 73848a3c..9afa2465 100644 --- a/src/views/components/common/CalendarGrid/CalendarGrid.tsx +++ b/src/views/components/common/CalendarGrid/CalendarGrid.tsx @@ -1,7 +1,5 @@ import React, { useRef } from 'react'; -// import html2canvas from 'html2canvas'; import * as htmlToImage from 'html-to-image'; -import { toPng, toJpeg, toBlob, toPixelData, toSvg } from 'html-to-image'; import { DAY_MAP } from 'src/shared/types/CourseMeeting'; import { CalendarGridCourse } from 'src/views/hooks/useFlattenedCourseSchedule'; import calIcon from 'src/assets/icons/cal.svg'; @@ -40,42 +38,36 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren { - // if (calendarRef.current) { - // html2canvas(calendarRef.current).then(canvas => { - // // Create an a element to trigger download - // const a = document.createElement('a'); - // a.href = canvas.toDataURL('image/png'); - // a.download = 'calendar.png'; - // a.click(); - // }); - // } - htmlToImage.toPng(calendarRef.current, { - backgroundColor: "white", - style: { - background: "white", - marginTop: "20px", - marginBottom: "20px", - marginRight: "20px", - marginLeft: "20px",}}) - .then(function (dataUrl) { - var img = new Image(); - img.src = dataUrl; - fetch(dataUrl) - .then(response => response.blob()) - .then(blob => { - const href = window.URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = href; - link.download = 'my-schedule.png'; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); + htmlToImage + .toPng(calendarRef.current, { + backgroundColor: 'white', + style: { + background: 'white', + marginTop: '20px', + marginBottom: '20px', + marginRight: '20px', + marginLeft: '20px', + }, }) - .catch(error => console.error('Error downloading file:', error)); - }) - .catch(function (error) { - console.error('oops, something went wrong!', error); - }); + .then(dataUrl => { + let img = new Image(); + img.src = dataUrl; + fetch(dataUrl) + .then(response => response.blob()) + .then(blob => { + const href = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = href; + link.download = 'my-schedule.png'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }) + .catch(error => console.error('Error downloading file:', error)); + }) + .catch(error => { + console.error('oops, something went wrong!', error); + }); }; return ( From 7f76af7ab37a4325bf816832739af635bcd7c619 Mon Sep 17 00:00:00 2001 From: DhruvArora-03 Date: Mon, 19 Feb 2024 11:28:33 -0600 Subject: [PATCH 04/20] fix ConflictsWithWarning --- .../ConflictsWithWarning.stories.tsx | 102 +++++++++++++++++- .../ConflictsWithWarning.tsx | 38 +++---- 2 files changed, 113 insertions(+), 27 deletions(-) diff --git a/src/stories/components/ConflictsWithWarning.stories.tsx b/src/stories/components/ConflictsWithWarning.stories.tsx index f1f9855a..d81706a7 100644 --- a/src/stories/components/ConflictsWithWarning.stories.tsx +++ b/src/stories/components/ConflictsWithWarning.stories.tsx @@ -1,5 +1,96 @@ import { Meta, StoryObj } from '@storybook/react'; import ConflictsWithWarning from '@views/components/common/ConflictsWithWarning/ConflictsWithWarning'; +import { Course, Status } from 'src/shared/types/Course'; +import { CourseMeeting } from 'src/shared/types/CourseMeeting'; +import Instructor from 'src/shared/types/Instructor'; + +export const ExampleCourse: Course = new Course({ + courseName: 'ELEMS OF COMPTRS/PROGRAMMNG-WB', + creditHours: 3, + department: 'C S', + description: [ + 'Problem solving and fundamental algorithms for various applications in science, business, and on the World Wide Web, and introductory programming in a modern object-oriented programming language.', + 'Only one of the following may be counted: Computer Science 303E, 312, 312H. Credit for Computer Science 303E may not be earned after a student has received credit for Computer Science 314, or 314H. May not be counted toward a degree in computer science.', + 'May be counted toward the Quantitative Reasoning flag requirement.', + 'Designed to accommodate 100 or more students.', + 'Taught as a Web-based course.', + ], + flags: ['Quantitative Reasoning'], + fullName: 'C S 303E ELEMS OF COMPTRS/PROGRAMMNG-WB', + instructionMode: 'Online', + instructors: [ + new Instructor({ + firstName: 'Bevo', + lastName: 'Bevo', + fullName: 'Bevo Bevo', + }), + ], + isReserved: false, + number: '303E', + schedule: { + meetings: [ + new CourseMeeting({ + days: ['Tuesday', 'Thursday'], + endTime: 660, + startTime: 570, + }), + ], + }, + semester: { + code: '12345', + season: 'Spring', + year: 2024, + }, + status: Status.WAITLISTED, + uniqueId: 12345, + url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', +}); +export const ExampleCourse2: Course = new Course({ + courseName: 'PRINCIPLES OF COMPUTER SYSTEMS', + creditHours: 3, + department: 'C S', + description: [ + 'Restricted to computer science majors.', + 'An introduction to computer systems software abstractions with an emphasis on the connection of these abstractions to underlying computer hardware. Key abstractions include threads, virtual memory, protection, and I/O. Requires writing of synchronized multithreaded programs and pieces of an operating system.', + 'Computer Science 439 and 439H may not both be counted.', + 'Prerequisite: Computer Science 429, or 429H with a grade of at least C-.', + 'May be counted toward the Independent Inquiry flag requirement.', + ], + flags: ['Independent Inquiry'], + fullName: 'C S 439 PRINCIPLES OF COMPUTER SYSTEMS', + instructionMode: 'In Person', + instructors: [ + new Instructor({ + firstName: 'Allison', + lastName: 'Norman', + fullName: 'Allison Norman', + }), + ], + isReserved: false, + number: '439', + schedule: { + meetings: [ + new CourseMeeting({ + days: ['Tuesday', 'Thursday'], + startTime: 930, + endTime: 1050, + }), + new CourseMeeting({ + days: ['Friday'], + startTime: 600, + endTime: 720, + }), + ], + }, + semester: { + code: '12345', + season: 'Spring', + year: 2024, + }, + status: Status.WAITLISTED, + uniqueId: 67890, + url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', +}); const meta = { title: 'Components/Common/ConflictsWithWarning', @@ -9,8 +100,10 @@ const meta = { }, tags: ['autodocs'], argTypes: { - ConflictingCourse: { control: 'string' }, - SectionNumber: { control: 'string' }, + conflicts: { control: 'object' }, + }, + args: { + conflicts: [ExampleCourse, ExampleCourse2], }, } satisfies Meta; export default meta; @@ -19,7 +112,6 @@ type Story = StoryObj; export const Default: Story = { args: { - ConflictingCourse: 'BVO 311C', - SectionNumber: '47280', + conflicts: [ExampleCourse, ExampleCourse2], }, -}; \ No newline at end of file +}; diff --git a/src/views/components/common/ConflictsWithWarning/ConflictsWithWarning.tsx b/src/views/components/common/ConflictsWithWarning/ConflictsWithWarning.tsx index ca1cc9bf..30d08e77 100644 --- a/src/views/components/common/ConflictsWithWarning/ConflictsWithWarning.tsx +++ b/src/views/components/common/ConflictsWithWarning/ConflictsWithWarning.tsx @@ -1,43 +1,37 @@ import React from 'react'; +import { Course } from 'src/shared/types/Course'; +import clsx from 'clsx'; import Text from '../Text/Text'; /** * Props for ConflictWithWarningProps */ export interface ConflictsWithWarningProps { - ConflictingCourse: string; - SectionNumber: string; + className?: string; + conflicts: Course[]; } /** - * The ConflictsWithWarning component is used to display a warning message when a course conflicts + * The ConflictsWithWarning component is used to display a warning message when a course conflicts * with another course as part of the labels and details section * * @param props ConflictsWithWarningProps */ -export default function ConflictsWithWarning( { ConflictingCourse, SectionNumber }: ConflictsWithWarningProps): JSX.Element { - const UniqueCourseConflictText = `${ConflictingCourse} (${SectionNumber})`; - - return ( -
- - Conflicts With: - - - {UniqueCourseConflictText} - -
- ); -} - -function ConflictsWithoutWarningText( {children}: {children: string} ) { +export default function ConflictsWithWarning({ className, conflicts }: ConflictsWithWarningProps): JSX.Element { return ( - {children} +
Conflicts With:
+ {conflicts.map(course => ( +
+ {`${course.department} ${course.number} (${course.uniqueId})`} +
+ ))}
); } From 70c75ff481ff243b613bbcc42136996c46b3a901 Mon Sep 17 00:00:00 2001 From: DhruvArora-03 Date: Mon, 19 Feb 2024 11:29:24 -0600 Subject: [PATCH 05/20] add button to the rows, use new ConflictsWithWarning component --- .../components/injected/TableRow/TableRow.tsx | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/views/components/injected/TableRow/TableRow.tsx b/src/views/components/injected/TableRow/TableRow.tsx index e9c6796e..a6e82cb1 100644 --- a/src/views/components/injected/TableRow/TableRow.tsx +++ b/src/views/components/injected/TableRow/TableRow.tsx @@ -3,9 +3,9 @@ import { UserSchedule } from '@shared/types/UserSchedule'; import React, { useEffect, useState } from 'react'; import ReactDOM from 'react-dom'; import { Button } from '../../common/Button/Button'; -import Icon from '../../common/Icon/Icon'; -import Text from '../../common/Text/Text'; import styles from './TableRow.module.scss'; +import ConflictsWithWarning from '../../common/ConflictsWithWarning/ConflictsWithWarning'; +import AddIcon from '~icons/material-symbols/add-circle'; interface Props { isSelected: boolean; @@ -54,7 +54,7 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P return () => { element.classList.remove(styles.inActiveSchedule); }; - }, [activeSchedule, element.classList]); + }, [activeSchedule, course, element.classList]); useEffect(() => { if (!activeSchedule || !course) { @@ -84,20 +84,14 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P return ReactDOM.createPortal( <> - - {conflicts.length > 0 && ( -
-
- {conflicts.map(c => ( - - {c.department} {c.number} ({c.uniqueId}) - - ))} -
-
- )} + From c676be4765a49d2c382ac88dddf3933747c5dbcb Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:26:09 -0600 Subject: [PATCH 07/20] Fixed build errors and restructured Calendar page --- ....timestamp-1708365827408-19c5144af9dbf.mjs | 30 +++++++++++++++++++ .../components/CalendarBottomBar.stories.tsx | 2 +- .../components/CalendarCourse.stories.tsx | 2 +- .../components/CalendarCourseCell.stories.tsx | 4 +-- .../components/CalendarGrid.stories.tsx | 2 +- .../components/CalendarGridCell.stories.tsx | 18 +++++------ .../components/CalendarHeader.stories.tsx | 2 +- .../components/CalendarSchedules.stories.tsx | 4 +-- .../components/ImportantLinks.stories.tsx | 2 +- src/views/components/PopupMain.tsx | 15 +++++----- .../CalendarBottomBar/CalendarBottomBar.tsx | 4 +-- .../CalendarCourseMeeting.module.scss | 0 .../CalendarCourseMeeting.tsx | 0 .../CalendarCourseCell/CalendarCourseCell.tsx | 2 +- .../CalendarGrid/CalendarGrid.module.scss | 0 .../CalendarGrid/CalendarGrid.tsx | 0 .../CalendarGridCell.module.scss | 0 .../CalendarGridCell/CalendarGridCell.tsx | 0 .../CalendarHeader/CalenderHeader.tsx | 10 +++---- .../CalendarSchedules/CalendarSchedules.tsx | 8 ++--- .../{ => calendar}/ImportantLinks.tsx | 2 +- src/views/hooks/useFlattenedCourseSchedule.ts | 2 +- 22 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 .storybook/vite-storybook.config.ts.timestamp-1708365827408-19c5144af9dbf.mjs rename src/views/components/{common => calendar}/CalendarBottomBar/CalendarBottomBar.tsx (94%) rename src/views/components/{common => calendar}/CalendarCourseBlock/CalendarCourseMeeting.module.scss (100%) rename src/views/components/{common => calendar}/CalendarCourseBlock/CalendarCourseMeeting.tsx (100%) rename src/views/components/{common => calendar}/CalendarCourseCell/CalendarCourseCell.tsx (98%) rename src/views/components/{common => calendar}/CalendarGrid/CalendarGrid.module.scss (100%) rename src/views/components/{common => calendar}/CalendarGrid/CalendarGrid.tsx (100%) rename src/views/components/{common => calendar}/CalendarGridCell/CalendarGridCell.module.scss (100%) rename src/views/components/{common => calendar}/CalendarGridCell/CalendarGridCell.tsx (100%) rename src/views/components/{common => calendar}/CalendarHeader/CalenderHeader.tsx (87%) rename src/views/components/{common => calendar}/CalendarSchedules/CalendarSchedules.tsx (82%) rename src/views/components/{ => calendar}/ImportantLinks.tsx (98%) diff --git a/.storybook/vite-storybook.config.ts.timestamp-1708365827408-19c5144af9dbf.mjs b/.storybook/vite-storybook.config.ts.timestamp-1708365827408-19c5144af9dbf.mjs new file mode 100644 index 00000000..fa5cdaf3 --- /dev/null +++ b/.storybook/vite-storybook.config.ts.timestamp-1708365827408-19c5144af9dbf.mjs @@ -0,0 +1,30 @@ +// .storybook/vite-storybook.config.ts +import react from "file:///C:/Users/somgu/OneDrive/Desktop/UT-Registration-Plus/node_modules/.pnpm/@vitejs+plugin-react-swc@3.6.0_vite@5.1.2/node_modules/@vitejs/plugin-react-swc/index.mjs"; +import { resolve } from "path"; +import UnoCSS from "file:///C:/Users/somgu/OneDrive/Desktop/UT-Registration-Plus/node_modules/.pnpm/unocss@0.58.5_postcss@8.4.35_vite@5.1.2/node_modules/unocss/dist/vite.mjs"; +import Icons from "file:///C:/Users/somgu/OneDrive/Desktop/UT-Registration-Plus/node_modules/.pnpm/unplugin-icons@0.18.5_@svgr+core@8.1.0/node_modules/unplugin-icons/dist/vite.js"; +import { defineConfig } from "file:///C:/Users/somgu/OneDrive/Desktop/UT-Registration-Plus/node_modules/.pnpm/vite@5.1.2_@types+node@20.11.17_sass@1.70.0/node_modules/vite/dist/node/index.js"; +var __vite_injected_original_dirname = "C:\\Users\\somgu\\OneDrive\\Desktop\\UT-Registration-Plus\\.storybook"; +var root = resolve(__vite_injected_original_dirname, "../src"); +var pagesDir = resolve(root, "pages"); +var assetsDir = resolve(root, "assets"); +var publicDir = resolve(__vite_injected_original_dirname, "../public"); +console.log(root); +var vite_storybook_config_default = defineConfig({ + plugins: [react(), UnoCSS(), Icons({ compiler: "jsx", jsx: "react" })], + resolve: { + alias: { + src: root, + "@assets": assetsDir, + "@pages": pagesDir, + "@public": publicDir, + "@shared": resolve(root, "shared"), + "@background": resolve(pagesDir, "background"), + "@views": resolve(root, "views") + } + } +}); +export { + vite_storybook_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLnN0b3J5Ym9vay92aXRlLXN0b3J5Ym9vay5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxVc2Vyc1xcXFxzb21ndVxcXFxPbmVEcml2ZVxcXFxEZXNrdG9wXFxcXFVULVJlZ2lzdHJhdGlvbi1QbHVzXFxcXC5zdG9yeWJvb2tcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkM6XFxcXFVzZXJzXFxcXHNvbWd1XFxcXE9uZURyaXZlXFxcXERlc2t0b3BcXFxcVVQtUmVnaXN0cmF0aW9uLVBsdXNcXFxcLnN0b3J5Ym9va1xcXFx2aXRlLXN0b3J5Ym9vay5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0M6L1VzZXJzL3NvbWd1L09uZURyaXZlL0Rlc2t0b3AvVVQtUmVnaXN0cmF0aW9uLVBsdXMvLnN0b3J5Ym9vay92aXRlLXN0b3J5Ym9vay5jb25maWcudHNcIjtpbXBvcnQgcmVhY3QgZnJvbSAnQHZpdGVqcy9wbHVnaW4tcmVhY3Qtc3djJztcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tICdwYXRoJztcbmltcG9ydCBVbm9DU1MgZnJvbSAndW5vY3NzL3ZpdGUnO1xuaW1wb3J0IEljb25zIGZyb20gJ3VucGx1Z2luLWljb25zL3ZpdGUnO1xuaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSc7XG5cbmNvbnN0IHJvb3QgPSByZXNvbHZlKF9fZGlybmFtZSwgJy4uL3NyYycpO1xuY29uc3QgcGFnZXNEaXIgPSByZXNvbHZlKHJvb3QsICdwYWdlcycpO1xuY29uc3QgYXNzZXRzRGlyID0gcmVzb2x2ZShyb290LCAnYXNzZXRzJyk7XG5jb25zdCBwdWJsaWNEaXIgPSByZXNvbHZlKF9fZGlybmFtZSwgJy4uL3B1YmxpYycpO1xuXG5jb25zb2xlLmxvZyhyb290KTtcblxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XG4gICAgcGx1Z2luczogW3JlYWN0KCksIFVub0NTUygpLCBJY29ucyh7IGNvbXBpbGVyOiAnanN4JywganN4OiAncmVhY3QnIH0pXSxcbiAgICByZXNvbHZlOiB7XG4gICAgICAgIGFsaWFzOiB7XG4gICAgICAgICAgICBzcmM6IHJvb3QsXG4gICAgICAgICAgICAnQGFzc2V0cyc6IGFzc2V0c0RpcixcbiAgICAgICAgICAgICdAcGFnZXMnOiBwYWdlc0RpcixcbiAgICAgICAgICAgICdAcHVibGljJzogcHVibGljRGlyLFxuICAgICAgICAgICAgJ0BzaGFyZWQnOiByZXNvbHZlKHJvb3QsICdzaGFyZWQnKSxcbiAgICAgICAgICAgICdAYmFja2dyb3VuZCc6IHJlc29sdmUocGFnZXNEaXIsICdiYWNrZ3JvdW5kJyksXG4gICAgICAgICAgICAnQHZpZXdzJzogcmVzb2x2ZShyb290LCAndmlld3MnKSxcbiAgICAgICAgfSxcbiAgICB9LFxufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQWlaLE9BQU8sV0FBVztBQUNuYSxTQUFTLGVBQWU7QUFDeEIsT0FBTyxZQUFZO0FBQ25CLE9BQU8sV0FBVztBQUNsQixTQUFTLG9CQUFvQjtBQUo3QixJQUFNLG1DQUFtQztBQU16QyxJQUFNLE9BQU8sUUFBUSxrQ0FBVyxRQUFRO0FBQ3hDLElBQU0sV0FBVyxRQUFRLE1BQU0sT0FBTztBQUN0QyxJQUFNLFlBQVksUUFBUSxNQUFNLFFBQVE7QUFDeEMsSUFBTSxZQUFZLFFBQVEsa0NBQVcsV0FBVztBQUVoRCxRQUFRLElBQUksSUFBSTtBQUdoQixJQUFPLGdDQUFRLGFBQWE7QUFBQSxFQUN4QixTQUFTLENBQUMsTUFBTSxHQUFHLE9BQU8sR0FBRyxNQUFNLEVBQUUsVUFBVSxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUM7QUFBQSxFQUNyRSxTQUFTO0FBQUEsSUFDTCxPQUFPO0FBQUEsTUFDSCxLQUFLO0FBQUEsTUFDTCxXQUFXO0FBQUEsTUFDWCxVQUFVO0FBQUEsTUFDVixXQUFXO0FBQUEsTUFDWCxXQUFXLFFBQVEsTUFBTSxRQUFRO0FBQUEsTUFDakMsZUFBZSxRQUFRLFVBQVUsWUFBWTtBQUFBLE1BQzdDLFVBQVUsUUFBUSxNQUFNLE9BQU87QUFBQSxJQUNuQztBQUFBLEVBQ0o7QUFDSixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo= diff --git a/src/stories/components/CalendarBottomBar.stories.tsx b/src/stories/components/CalendarBottomBar.stories.tsx index a1f1c5c7..1ee78750 100644 --- a/src/stories/components/CalendarBottomBar.stories.tsx +++ b/src/stories/components/CalendarBottomBar.stories.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Meta, StoryObj } from '@storybook/react'; import { Course, Status } from '@shared/types/Course'; import Instructor from '@shared/types/Instructor'; -import { CalendarBottomBar } from '@views/components/common/CalendarBottomBar/CalendarBottomBar'; +import { CalendarBottomBar } from 'src/views/components/calendar/CalendarBottomBar/CalendarBottomBar'; import { getCourseColors } from '../../shared/util/colors'; const exampleGovCourse: Course = new Course({ diff --git a/src/stories/components/CalendarCourse.stories.tsx b/src/stories/components/CalendarCourse.stories.tsx index 77ed8a2e..43cd032e 100644 --- a/src/stories/components/CalendarCourse.stories.tsx +++ b/src/stories/components/CalendarCourse.stories.tsx @@ -3,7 +3,7 @@ import { Course, Status } from '@shared/types/Course'; import { CourseMeeting, DAY_MAP } from '@shared/types/CourseMeeting'; import { CourseSchedule } from '@shared/types/CourseSchedule'; import Instructor from '@shared/types/Instructor'; -import CalendarCourse from '@views/components/common/CalendarCourseBlock/CalendarCourseMeeting'; +import CalendarCourse from 'src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting'; const meta = { title: 'Components/Common/CalendarCourseMeeting', diff --git a/src/stories/components/CalendarCourseCell.stories.tsx b/src/stories/components/CalendarCourseCell.stories.tsx index 61cbdd33..cc3ae3aa 100644 --- a/src/stories/components/CalendarCourseCell.stories.tsx +++ b/src/stories/components/CalendarCourseCell.stories.tsx @@ -1,7 +1,7 @@ import { Course, Status } from '@shared/types/Course'; import { getCourseColors } from '@shared/util/colors'; import { Meta, StoryObj } from '@storybook/react'; -import CalendarCourseCell from '@views/components/common/CalendarCourseCell/CalendarCourseCell'; +import CalendarCourseCell from 'src/views/components/calendar/CalendarCourseCell/CalendarCourseCell'; import React from 'react'; import { exampleCourse } from './PopupCourseBlock.stories'; @@ -91,7 +91,7 @@ export const Variants: Story = { // uniqueId: 67890, // url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', // }); - + colors={getCourseColors('green', 500)} /> ; export default meta; type Story = StoryObj; -export const Default: Story = {}; \ No newline at end of file +export const Default: Story = {}; diff --git a/src/stories/components/CalendarHeader.stories.tsx b/src/stories/components/CalendarHeader.stories.tsx index 047d8694..cd715035 100644 --- a/src/stories/components/CalendarHeader.stories.tsx +++ b/src/stories/components/CalendarHeader.stories.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Meta, StoryObj } from '@storybook/react'; -import CalendarHeader from '@views/components/common/CalendarHeader/CalenderHeader'; +import CalendarHeader from 'src/views/components/calendar/CalendarHeader/CalenderHeader'; const meta = { title: 'Components/Common/CalendarHeader', diff --git a/src/stories/components/CalendarSchedules.stories.tsx b/src/stories/components/CalendarSchedules.stories.tsx index 0dd60e2f..ccd13b4c 100644 --- a/src/stories/components/CalendarSchedules.stories.tsx +++ b/src/stories/components/CalendarSchedules.stories.tsx @@ -5,7 +5,7 @@ import React from 'react'; import { CourseMeeting, DAY_MAP } from 'src/shared/types/CourseMeeting'; import { CourseSchedule } from 'src/shared/types/CourseSchedule'; import Instructor from 'src/shared/types/Instructor'; -import { CalendarSchedules } from 'src/views/components/common/CalendarSchedules/CalendarSchedules'; +import { CalendarSchedules } from 'src/views/components/calendar/CalendarSchedules/CalendarSchedules'; const meta = { title: 'Components/Common/CalendarSchedules', @@ -17,7 +17,6 @@ const meta = { argTypes: { dummySchedules: { control: 'object' }, dummyActiveIndex: { control: 'number' }, - }, render: (args: any) => (
@@ -141,6 +140,5 @@ export const Default: Story = { args: { dummySchedules: schedules, dummyActiveIndex: 0, - }, }; diff --git a/src/stories/components/ImportantLinks.stories.tsx b/src/stories/components/ImportantLinks.stories.tsx index 9f8a606d..95619fa9 100644 --- a/src/stories/components/ImportantLinks.stories.tsx +++ b/src/stories/components/ImportantLinks.stories.tsx @@ -1,5 +1,5 @@ import { Meta, StoryObj } from '@storybook/react'; -import ImportantLinks from 'src/views/components/ImportantLinks'; +import ImportantLinks from 'src/views/components/calendar/ImportantLinks'; const meta = { title: 'Components/Common/ImportantLinks', diff --git a/src/views/components/PopupMain.tsx b/src/views/components/PopupMain.tsx index f831ed77..82edd17c 100644 --- a/src/views/components/PopupMain.tsx +++ b/src/views/components/PopupMain.tsx @@ -1,13 +1,14 @@ import React from 'react'; import { FaCalendarAlt, FaCog, FaRedo } from 'react-icons/fa'; // Added FaRedo for the refresh icon import { StatusIcon } from '@shared/util/icons'; +import { generateCourses } from 'src/stories/components/List.stories'; +import { Status } from 'src/shared/types/Course'; import ExtensionRoot from './common/ExtensionRoot/ExtensionRoot'; import PopupCourseBlock from './common/PopupCourseBlock/PopupCourseBlock'; import Text from './common/Text/Text'; import Divider from './common/Divider/Divider'; import logoImage from '../../assets/logo.png'; // Adjust the path as necessary import List from './common/List/List'; // Ensure this path is correctly pointing to your List component -import { generateCourses } from 'src/stories/components/List.stories'; export default function PopupMain() { const courses = generateCourses(5); @@ -52,7 +53,7 @@ return (
-
+
MAIN SCHEDULE:
22 HOURS @@ -67,22 +68,22 @@ return ( listWidth={350} // Adjust based on your layout/design gap={12} // Spacing between items /> -
+
- +
WAITLISTED
- +
CLOSED
- +
CANCELLED
@@ -90,7 +91,7 @@ return (
DATA UPDATED ON: 12:00 AM 02/01/2024 - +
diff --git a/src/views/components/common/CalendarBottomBar/CalendarBottomBar.tsx b/src/views/components/calendar/CalendarBottomBar/CalendarBottomBar.tsx similarity index 94% rename from src/views/components/common/CalendarBottomBar/CalendarBottomBar.tsx rename to src/views/components/calendar/CalendarBottomBar/CalendarBottomBar.tsx index 5b99ab8d..8bf5962b 100644 --- a/src/views/components/common/CalendarBottomBar/CalendarBottomBar.tsx +++ b/src/views/components/calendar/CalendarBottomBar/CalendarBottomBar.tsx @@ -1,8 +1,8 @@ import React from 'react'; import clsx from 'clsx'; -import Text from '../Text/Text'; +import Text from '../../common/Text/Text'; import CalendarCourseBlock, { CalendarCourseCellProps } from '../CalendarCourseCell/CalendarCourseCell'; -import { Button } from '../Button/Button'; +import { Button } from '../../common/Button/Button'; import ImageIcon from '~icons/material-symbols/image'; import CalendarMonthIcon from '~icons/material-symbols/calendar-month'; diff --git a/src/views/components/common/CalendarCourseBlock/CalendarCourseMeeting.module.scss b/src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting.module.scss similarity index 100% rename from src/views/components/common/CalendarCourseBlock/CalendarCourseMeeting.module.scss rename to src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting.module.scss diff --git a/src/views/components/common/CalendarCourseBlock/CalendarCourseMeeting.tsx b/src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting.tsx similarity index 100% rename from src/views/components/common/CalendarCourseBlock/CalendarCourseMeeting.tsx rename to src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting.tsx diff --git a/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx b/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx similarity index 98% rename from src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx rename to src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx index 1ea60c25..da9db25f 100644 --- a/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx +++ b/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx @@ -5,7 +5,7 @@ import { CourseColors, pickFontColor } from 'src/shared/util/colors'; import ClosedIcon from '~icons/material-symbols/lock'; import WaitlistIcon from '~icons/material-symbols/timelapse'; import CancelledIcon from '~icons/material-symbols/warning'; -import Text from '../Text/Text'; +import Text from '../../common/Text/Text'; export interface CalendarCourseCellProps { courseDeptAndInstr: string; diff --git a/src/views/components/common/CalendarGrid/CalendarGrid.module.scss b/src/views/components/calendar/CalendarGrid/CalendarGrid.module.scss similarity index 100% rename from src/views/components/common/CalendarGrid/CalendarGrid.module.scss rename to src/views/components/calendar/CalendarGrid/CalendarGrid.module.scss diff --git a/src/views/components/common/CalendarGrid/CalendarGrid.tsx b/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx similarity index 100% rename from src/views/components/common/CalendarGrid/CalendarGrid.tsx rename to src/views/components/calendar/CalendarGrid/CalendarGrid.tsx diff --git a/src/views/components/common/CalendarGridCell/CalendarGridCell.module.scss b/src/views/components/calendar/CalendarGridCell/CalendarGridCell.module.scss similarity index 100% rename from src/views/components/common/CalendarGridCell/CalendarGridCell.module.scss rename to src/views/components/calendar/CalendarGridCell/CalendarGridCell.module.scss diff --git a/src/views/components/common/CalendarGridCell/CalendarGridCell.tsx b/src/views/components/calendar/CalendarGridCell/CalendarGridCell.tsx similarity index 100% rename from src/views/components/common/CalendarGridCell/CalendarGridCell.tsx rename to src/views/components/calendar/CalendarGridCell/CalendarGridCell.tsx diff --git a/src/views/components/common/CalendarHeader/CalenderHeader.tsx b/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx similarity index 87% rename from src/views/components/common/CalendarHeader/CalenderHeader.tsx rename to src/views/components/calendar/CalendarHeader/CalenderHeader.tsx index 7f11d348..29ba99c3 100644 --- a/src/views/components/common/CalendarHeader/CalenderHeader.tsx +++ b/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx @@ -1,15 +1,15 @@ import React from 'react'; import { Status } from '@shared/types/Course'; -import Divider from '../Divider/Divider'; -import { Button } from '../Button/Button'; -import Text from '../Text/Text'; +import Divider from '../../common/Divider/Divider'; +import { Button } from '../../common/Button/Button'; +import Text from '../../common/Text/Text'; import MenuIcon from '~icons/material-symbols/menu'; import LogoIcon from '~icons/material-symbols/add-circle-outline'; import UndoIcon from '~icons/material-symbols/undo'; import RedoIcon from '~icons/material-symbols/redo'; import SettingsIcon from '~icons/material-symbols/settings'; -import ScheduleTotalHoursAndCourses from '../ScheduleTotalHoursAndCourses/ScheduleTotalHoursAndCourses'; -import CourseStatus from '../CourseStatus/CourseStatus'; +import ScheduleTotalHoursAndCourses from '../../common/ScheduleTotalHoursAndCourses/ScheduleTotalHoursAndCourses'; +import CourseStatus from '../../common/CourseStatus/CourseStatus'; const CalendarHeader = () => (
diff --git a/src/views/components/common/CalendarSchedules/CalendarSchedules.tsx b/src/views/components/calendar/CalendarSchedules/CalendarSchedules.tsx similarity index 82% rename from src/views/components/common/CalendarSchedules/CalendarSchedules.tsx rename to src/views/components/calendar/CalendarSchedules/CalendarSchedules.tsx index f9a84e95..25b74ea7 100644 --- a/src/views/components/common/CalendarSchedules/CalendarSchedules.tsx +++ b/src/views/components/calendar/CalendarSchedules/CalendarSchedules.tsx @@ -1,9 +1,9 @@ import { UserSchedule } from '@shared/types/UserSchedule'; import React, { useState } from 'react'; import AddSchedule from '~icons/material-symbols/add'; -import List from '../List/List'; -import ScheduleListItem from '../ScheduleListItem/ScheduleListItem'; -import Text from '../Text/Text'; +import List from '../../common/List/List'; +import ScheduleListItem from '../../common/ScheduleListItem/ScheduleListItem'; +import Text from '../../common/Text/Text'; export type Props = { style?: React.CSSProperties; @@ -16,7 +16,7 @@ export function CalendarSchedules(props: Props) { const [schedules, setSchedules] = useState(props.dummySchedules || []); const scheduleComponents = schedules.map((schedule, index) => ( - + )); return ( diff --git a/src/views/components/ImportantLinks.tsx b/src/views/components/calendar/ImportantLinks.tsx similarity index 98% rename from src/views/components/ImportantLinks.tsx rename to src/views/components/calendar/ImportantLinks.tsx index f301a54d..a111ab08 100644 --- a/src/views/components/ImportantLinks.tsx +++ b/src/views/components/calendar/ImportantLinks.tsx @@ -1,6 +1,6 @@ import React from 'react'; import clsx from 'clsx'; -import Text from './common/Text/Text'; +import Text from '../common/Text/Text'; import OutwardArrowIcon from '~icons/material-symbols/arrow-outward'; type Props = { diff --git a/src/views/hooks/useFlattenedCourseSchedule.ts b/src/views/hooks/useFlattenedCourseSchedule.ts index da1a3bb3..5b4a6c4a 100644 --- a/src/views/hooks/useFlattenedCourseSchedule.ts +++ b/src/views/hooks/useFlattenedCourseSchedule.ts @@ -1,4 +1,4 @@ -import { CalendarCourseCellProps } from 'src/views/components/common/CalendarCourseCell/CalendarCourseCell'; +import { CalendarCourseCellProps } from 'src/views/components/calendar/CalendarCourseCell/CalendarCourseCell'; import useSchedules from './useSchedules'; const dayToNumber: { [day: string]: number } = { From 11fece0595fb8e54495a9983d2c4f12b683c5d0e Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:27:06 -0600 Subject: [PATCH 08/20] Merged in finished CalendarGrid --- .../components/CalendarGrid.stories.tsx | 126 +++++++++--- .../CalendarCourseCell/CalendarCourseCell.tsx | 4 +- .../CalendarGrid/CalendarGrid.module.scss | 19 +- .../calendar/CalendarGrid/CalendarGrid.tsx | 188 +++++++++++++----- .../CalendarGridCell.module.scss | 8 +- .../CalendarGridCell/CalendarGridCell.tsx | 16 +- src/views/hooks/useFlattenedCourseSchedule.ts | 3 + 7 files changed, 271 insertions(+), 93 deletions(-) diff --git a/src/stories/components/CalendarGrid.stories.tsx b/src/stories/components/CalendarGrid.stories.tsx index 1e01df74..de7e17f8 100644 --- a/src/stories/components/CalendarGrid.stories.tsx +++ b/src/stories/components/CalendarGrid.stories.tsx @@ -1,8 +1,8 @@ import { Meta, StoryObj } from '@storybook/react'; -import CalendarGrid from 'src/views/components/calendar/CalendarGrid/CalendarGrid'; -import { getCourseColors } from 'src/shared/util/colors'; -import { CalendarGridCourse } from 'src/views/hooks/useFlattenedCourseSchedule'; -import { Status } from 'src/shared/types/Course'; +import CalendarGrid from '@views/components/common/CalendarGrid/CalendarGrid'; +import { getCourseColors } from '@shared/util/colors'; +import { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule'; +import { Status } from '@shared/types/Course'; const meta = { title: 'Components/Common/CalendarGrid', @@ -18,33 +18,97 @@ const meta = { export default meta; const testData: CalendarGridCourse[] = [ - { - calendarGridPoint: { - dayIndex: 0, - startIndex: 1, - endIndex: 2, - }, - componentProps: { - courseDeptAndInstr: 'Course 1', - timeAndLocation: '9:00 AM - 10:00 AM, Room 101', - status: Status.OPEN, - colors: getCourseColors('emerald', 500), - }, - }, - { - calendarGridPoint: { - dayIndex: 1, - startIndex: 2, - endIndex: 3, - }, - componentProps: { - courseDeptAndInstr: 'Course 2', - timeAndLocation: '10:00 AM - 11:00 AM, Room 102', - status: Status.CLOSED, - colors: getCourseColors('emerald', 500), - }, - }, - // add more data as needed + { + calendarGridPoint: { + dayIndex: 4, + startIndex: 10, + endIndex: 11, + }, + componentProps: { + courseDeptAndInstr: 'Course 1', + timeAndLocation: '9:00 AM - 10:00 AM, Room 101', + status: Status.OPEN, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 2, + startIndex: 5, + endIndex: 6, + }, + componentProps: { + courseDeptAndInstr: 'Course 1', + timeAndLocation: '9:00 AM - 10:00 AM, Room 101', + status: Status.OPEN, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 2', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 4, + startIndex: 10, + endIndex: 11, + }, + componentProps: { + courseDeptAndInstr: 'Course 1', + timeAndLocation: '9:00 AM - 10:00 AM, Room 101', + status: Status.OPEN, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 2', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 3', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 4', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, + }, ]; type Story = StoryObj; diff --git a/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx b/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx index da9db25f..fc05fc03 100644 --- a/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx +++ b/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx @@ -36,12 +36,12 @@ const CalendarCourseCell: React.FC = ({ return (
-
+
!['S', 'SU'].includes(key)); +/* const daysOfWeek = Object.keys(DAY_MAP).filter(key => !['S', 'SU'].includes(key)); const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8); const grid = []; for (let i = 0; i < 13; i++) { @@ -23,7 +24,7 @@ for (let i = 0; i < 13; i++) { ); row.push(Array.from({ length: 5 }, (_, j) => )); grid.push(row); -} +} */ interface Props { courseCells: CalendarGridCourse[]; @@ -35,9 +36,13 @@ interface Props { * @param props */ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren): JSX.Element { + const [grid, setGrid] = useState([]); const calendarRef = useRef(null); // Create a ref for the calendar grid - const saveAsPNG = () => { + const daysOfWeek = Object.keys(DAY_MAP).filter(key => !['S', 'SU'].includes(key)); + const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8); + + /* const saveAsPNG = () => { htmlToImage .toPng(calendarRef.current, { backgroundColor: 'white', @@ -68,23 +73,47 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren { console.error('oops, something went wrong!', error); }); - }; + }; */ + + useEffect(() => { + const newGrid = []; + for (let i = 0; i < 13; i++) { + const row = []; + let hour = hoursOfDay[i]; + let styleProp = { + gridColumn: '1', + gridRow: `${2 * i + 2}`, + }; + row.push( +
+
+

{(hour % 12 === 0 ? 12 : hour % 12) + (hour < 12 ? ' AM' : ' PM')}

+
+
+ ); + for (let k = 0; k < 5; k++) { + // let shouldRender = false; + styleProp = { + gridColumn: `${k + 2}`, + gridRow: `${2 * i + 2} / ${2 * i + 4}`, + }; + /* let shouldRenderChild = courseCells[iterator]?.calendarGridPoint && + k === courseCells[iterator].calendarGridPoint.dayIndex && i === courseCells[iterator].calendarGridPoint.startIndex; + let childElement =
; */ + /* let completeGridCell = shouldRenderChild ? + : ; */ + row.push(); + } + newGrid.push(row); + } + setGrid(newGrid); + }, []); return (
{/* Displaying the rest of the calendar */} -
- {/*
-
- {hoursOfDay.map((hour) => ( -
-
-

{hour % 12 === 0 ? 12 : hour % 12} {hour < 12 ? 'AM' : 'PM'}

-
-
- ))} -
*/} +
{/* Displaying day labels */}
@@ -93,40 +122,103 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren ))} - {grid.map((row, index) => ( - {row} - ))} + {grid.map((row, rowIndex) => row)} + {accountForCourseConflicts(courseCells)} + {/* courseCells.map((block: CalendarGridCourse) => ( +
+ +
+ )) */}
- {courseCells.map((block: CalendarGridCourse) => ( -
- -
- ))} -
-
{/* First divider */} - -
{/* Second divider */} - -
); } export default CalendarGrid; + +function accountForCourseConflicts(courseCells: CalendarGridCourse[]): JSX.Element[] { + // Groups by dayIndex to identify overlaps + const days = courseCells.reduce((acc, cell: CalendarGridCourse) => { + const { dayIndex } = cell.calendarGridPoint; + if (!acc[dayIndex]) { + acc[dayIndex] = []; + } + acc[dayIndex].push(cell); + return acc; + }, {}); + + // Check for overlaps within each day and adjust gridColumnIndex and totalColumns + Object.values(days).forEach((dayCells: CalendarGridCourse[]) => { + // Sort by start time to ensure proper columnIndex assignment + dayCells.sort((a, b) => a.calendarGridPoint.startIndex - b.calendarGridPoint.startIndex); + + dayCells.forEach((cell, _, arr) => { + let columnIndex = 1; + cell.totalColumns = 1; + // Check for overlaps and adjust columnIndex as needed + for (let otherCell of arr) { + if (otherCell !== cell) { + const isOverlapping = + otherCell.calendarGridPoint.startIndex < cell.calendarGridPoint.endIndex && + otherCell.calendarGridPoint.endIndex > cell.calendarGridPoint.startIndex; + if (isOverlapping) { + console.log('Found overlapping element'); + // Adjust columnIndex to not overlap with the otherCell + if (otherCell.gridColumnStart && otherCell.gridColumnStart >= columnIndex) { + columnIndex = otherCell.gridColumnStart + 1; + console.log(columnIndex); + } + cell.totalColumns += 1; + } + } + } + cell.gridColumnStart = columnIndex; + cell.gridColumnEnd = columnIndex + 1; + }); + }); + + return courseCells.map(block => ( +
+ +
+ )); +} + +/*
+
+ +
+ +
*/ diff --git a/src/views/components/calendar/CalendarGridCell/CalendarGridCell.module.scss b/src/views/components/calendar/CalendarGridCell/CalendarGridCell.module.scss index b34ddb32..639c8fbb 100644 --- a/src/views/components/calendar/CalendarGridCell/CalendarGridCell.module.scss +++ b/src/views/components/calendar/CalendarGridCell/CalendarGridCell.module.scss @@ -1,7 +1,7 @@ .calendarCell { display: flex; - width: 213.8px; - height: 44.769px; + width: 100%; + height: 100%; min-width: 45px; min-height: 40px; flex-direction: column; @@ -11,8 +11,8 @@ } .hourLine { - width: 213.8px; + width: 100%; height: 1px; - border-radius: var(--border-radius-none, 0px); + border-radius: 0px; background: rgba(218, 220, 224, 0.25); } diff --git a/src/views/components/calendar/CalendarGridCell/CalendarGridCell.tsx b/src/views/components/calendar/CalendarGridCell/CalendarGridCell.tsx index 600a5712..77c35553 100644 --- a/src/views/components/calendar/CalendarGridCell/CalendarGridCell.tsx +++ b/src/views/components/calendar/CalendarGridCell/CalendarGridCell.tsx @@ -1,14 +1,20 @@ import React from 'react'; import styles from './CalendarGridCell.module.scss'; +interface Props { + styleProp: any; +} + /** * Component representing each 1 hour time block of a calendar * @param props */ -const CalendarCell: React.FC = props => ( -
-
-
-); +function CalendarCell({ styleProp }: Props): JSX.Element { + return ( +
+
+
+ ); +} export default CalendarCell; diff --git a/src/views/hooks/useFlattenedCourseSchedule.ts b/src/views/hooks/useFlattenedCourseSchedule.ts index 5b4a6c4a..fea3d400 100644 --- a/src/views/hooks/useFlattenedCourseSchedule.ts +++ b/src/views/hooks/useFlattenedCourseSchedule.ts @@ -21,6 +21,9 @@ interface CalendarGridPoint { export interface CalendarGridCourse { calendarGridPoint: CalendarGridPoint; componentProps: CalendarCourseCellProps; + gridColumnStart?: number; + gridColumnEnd?: number; + totalColumns?: number; } const convertMinutesToIndex = (minutes: number): number => Math.floor(minutes - 420 / 30); From 41e6d77d026d2e13342febe8ac5b4c9828af1c56 Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:34:42 -0600 Subject: [PATCH 09/20] Fixed import error --- src/stories/components/CalendarGrid.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stories/components/CalendarGrid.stories.tsx b/src/stories/components/CalendarGrid.stories.tsx index de7e17f8..761c4dbc 100644 --- a/src/stories/components/CalendarGrid.stories.tsx +++ b/src/stories/components/CalendarGrid.stories.tsx @@ -1,5 +1,5 @@ import { Meta, StoryObj } from '@storybook/react'; -import CalendarGrid from '@views/components/common/CalendarGrid/CalendarGrid'; +import CalendarGrid from 'src/views/components/calendar/CalendarGrid/CalendarGrid'; import { getCourseColors } from '@shared/util/colors'; import { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule'; import { Status } from '@shared/types/Course'; From d69707b8e821c1fa65356c228cd539fa9fd8e54d Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Mon, 19 Feb 2024 20:48:00 -0600 Subject: [PATCH 10/20] Squashed commit of the following: commit f6896e37e25d655e250a97cc4be826ddcf13e7b0 Author: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Mon Feb 19 20:46:57 2024 -0600 Calendar Page mostly styled commit a28422e6b05fe3c594ea131863e75d65eeee978d Merge: 297601e 41e6d77 Author: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Mon Feb 19 18:46:59 2024 -0600 Merge branch 'hackathon' into Som commit 297601e715ff589ee862ca673e8273223b7d27f0 Author: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Sun Feb 18 16:28:29 2024 -0600 Grid works cleanly with up to two course conflicts. Prob needs refactoring commit 313a9648c97dd2600948deb4f205e731ed9974de Merge: b0a95a6 0acd0b7 Author: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Sun Feb 18 15:45:57 2024 -0600 Merge branch 'hackathon' into Som commit b0a95a6153defb077d39ab0012ad32503cbee703 Author: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Sun Feb 18 14:10:13 2024 -0600 Made CourseCells and CalendarGridCells more responsive. CourseCells now rendering onto grid. Still, need to make course cells more responsive, and add edge cases commit a1a0f005145f934f77a11b2cbbbc03611638088d Merge: 7479004 ac71b83 Author: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Sat Feb 17 17:07:06 2024 -0600 Merge branch 'hackathon' into Som commit 7479004a65c4220937d4ca1f70d6b68ece14f642 Author: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Sat Feb 17 16:59:34 2024 -0600 Need to add sorting --- .../components/calendar/Calendar.stories.tsx | 23 +++++++++++ .../CalendarBottomBar.stories.tsx | 4 +- .../{ => calendar}/CalendarCourse.stories.tsx | 2 +- .../CalendarCourseCell.stories.tsx | 4 +- .../{ => calendar}/CalendarGrid.stories.tsx | 2 +- .../CalendarGridCell.stories.tsx | 2 +- .../{ => calendar}/CalendarHeader.stories.tsx | 2 +- .../CalendarSchedules.stories.tsx | 2 +- .../components/calendar/Calendar/Calendar.tsx | 40 +++++++++++++++++++ .../CalendarBottomBar/CalendarBottomBar.tsx | 6 +-- .../CalendarGrid/CalendarGrid.module.scss | 12 +++--- .../calendar/CalendarGrid/CalendarGrid.tsx | 36 +++++++---------- 12 files changed, 96 insertions(+), 39 deletions(-) create mode 100644 src/stories/components/calendar/Calendar.stories.tsx rename src/stories/components/{ => calendar}/CalendarBottomBar.stories.tsx (96%) rename src/stories/components/{ => calendar}/CalendarCourse.stories.tsx (97%) rename src/stories/components/{ => calendar}/CalendarCourseCell.stories.tsx (97%) rename src/stories/components/{ => calendar}/CalendarGrid.stories.tsx (98%) rename src/stories/components/{ => calendar}/CalendarGridCell.stories.tsx (92%) rename src/stories/components/{ => calendar}/CalendarHeader.stories.tsx (89%) rename src/stories/components/{ => calendar}/CalendarSchedules.stories.tsx (98%) create mode 100644 src/views/components/calendar/Calendar/Calendar.tsx diff --git a/src/stories/components/calendar/Calendar.stories.tsx b/src/stories/components/calendar/Calendar.stories.tsx new file mode 100644 index 00000000..beda65e2 --- /dev/null +++ b/src/stories/components/calendar/Calendar.stories.tsx @@ -0,0 +1,23 @@ +import { Meta, StoryObj } from '@storybook/react'; +import { Calendar } from 'src/views/components/calendar/Calendar/Calendar'; + +const meta = { + title: 'Components/Calendar/Calendar', + component: Calendar, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + + }, +} satisfies Meta; +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + + }, +}; \ No newline at end of file diff --git a/src/stories/components/CalendarBottomBar.stories.tsx b/src/stories/components/calendar/CalendarBottomBar.stories.tsx similarity index 96% rename from src/stories/components/CalendarBottomBar.stories.tsx rename to src/stories/components/calendar/CalendarBottomBar.stories.tsx index 1ee78750..e75f941d 100644 --- a/src/stories/components/CalendarBottomBar.stories.tsx +++ b/src/stories/components/calendar/CalendarBottomBar.stories.tsx @@ -3,7 +3,7 @@ import { Meta, StoryObj } from '@storybook/react'; import { Course, Status } from '@shared/types/Course'; import Instructor from '@shared/types/Instructor'; import { CalendarBottomBar } from 'src/views/components/calendar/CalendarBottomBar/CalendarBottomBar'; -import { getCourseColors } from '../../shared/util/colors'; +import { getCourseColors } from '../../../shared/util/colors'; const exampleGovCourse: Course = new Course({ courseName: 'Nope', @@ -66,7 +66,7 @@ const examplePsyCourse: Course = new Course({ }); const meta = { - title: 'Components/Common/CalendarBottomBar', + title: 'Components/Calendar/CalendarBottomBar', component: CalendarBottomBar, parameters: { layout: 'centered', diff --git a/src/stories/components/CalendarCourse.stories.tsx b/src/stories/components/calendar/CalendarCourse.stories.tsx similarity index 97% rename from src/stories/components/CalendarCourse.stories.tsx rename to src/stories/components/calendar/CalendarCourse.stories.tsx index 43cd032e..43066303 100644 --- a/src/stories/components/CalendarCourse.stories.tsx +++ b/src/stories/components/calendar/CalendarCourse.stories.tsx @@ -6,7 +6,7 @@ import Instructor from '@shared/types/Instructor'; import CalendarCourse from 'src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting'; const meta = { - title: 'Components/Common/CalendarCourseMeeting', + title: 'Components/Calendar/CalendarCourseMeeting', component: CalendarCourse, parameters: { layout: 'centered', diff --git a/src/stories/components/CalendarCourseCell.stories.tsx b/src/stories/components/calendar/CalendarCourseCell.stories.tsx similarity index 97% rename from src/stories/components/CalendarCourseCell.stories.tsx rename to src/stories/components/calendar/CalendarCourseCell.stories.tsx index cc3ae3aa..8df4d9fd 100644 --- a/src/stories/components/CalendarCourseCell.stories.tsx +++ b/src/stories/components/calendar/CalendarCourseCell.stories.tsx @@ -3,10 +3,10 @@ import { getCourseColors } from '@shared/util/colors'; import { Meta, StoryObj } from '@storybook/react'; import CalendarCourseCell from 'src/views/components/calendar/CalendarCourseCell/CalendarCourseCell'; import React from 'react'; -import { exampleCourse } from './PopupCourseBlock.stories'; +import { exampleCourse } from '../PopupCourseBlock.stories'; const meta = { - title: 'Components/Common/CalendarCourseCell', + title: 'Components/Calendar/CalendarCourseCell', component: CalendarCourseCell, parameters: { layout: 'centered', diff --git a/src/stories/components/CalendarGrid.stories.tsx b/src/stories/components/calendar/CalendarGrid.stories.tsx similarity index 98% rename from src/stories/components/CalendarGrid.stories.tsx rename to src/stories/components/calendar/CalendarGrid.stories.tsx index 761c4dbc..d22c27d9 100644 --- a/src/stories/components/CalendarGrid.stories.tsx +++ b/src/stories/components/calendar/CalendarGrid.stories.tsx @@ -5,7 +5,7 @@ import { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule'; import { Status } from '@shared/types/Course'; const meta = { - title: 'Components/Common/CalendarGrid', + title: 'Components/Calendar/CalendarGrid', component: CalendarGrid, parameters: { layout: 'centered', diff --git a/src/stories/components/CalendarGridCell.stories.tsx b/src/stories/components/calendar/CalendarGridCell.stories.tsx similarity index 92% rename from src/stories/components/CalendarGridCell.stories.tsx rename to src/stories/components/calendar/CalendarGridCell.stories.tsx index 1b1cbbfc..067e134e 100644 --- a/src/stories/components/CalendarGridCell.stories.tsx +++ b/src/stories/components/calendar/CalendarGridCell.stories.tsx @@ -4,7 +4,7 @@ import CalendarCell from 'src/views/components/calendar/CalendarGridCell/Calenda import type { Meta, StoryObj } from '@storybook/react'; const meta = { - title: 'Components/Common/CalendarGridCell', + title: 'Components/Calendar/CalendarGridCell', component: CalendarCell, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/src/stories/components/CalendarHeader.stories.tsx b/src/stories/components/calendar/CalendarHeader.stories.tsx similarity index 89% rename from src/stories/components/CalendarHeader.stories.tsx rename to src/stories/components/calendar/CalendarHeader.stories.tsx index cd715035..1a2a7131 100644 --- a/src/stories/components/CalendarHeader.stories.tsx +++ b/src/stories/components/calendar/CalendarHeader.stories.tsx @@ -3,7 +3,7 @@ import { Meta, StoryObj } from '@storybook/react'; import CalendarHeader from 'src/views/components/calendar/CalendarHeader/CalenderHeader'; const meta = { - title: 'Components/Common/CalendarHeader', + title: 'Components/Calendar/CalendarHeader', component: CalendarHeader, parameters: { layout: 'centered', diff --git a/src/stories/components/CalendarSchedules.stories.tsx b/src/stories/components/calendar/CalendarSchedules.stories.tsx similarity index 98% rename from src/stories/components/CalendarSchedules.stories.tsx rename to src/stories/components/calendar/CalendarSchedules.stories.tsx index ccd13b4c..86b01826 100644 --- a/src/stories/components/CalendarSchedules.stories.tsx +++ b/src/stories/components/calendar/CalendarSchedules.stories.tsx @@ -8,7 +8,7 @@ import Instructor from 'src/shared/types/Instructor'; import { CalendarSchedules } from 'src/views/components/calendar/CalendarSchedules/CalendarSchedules'; const meta = { - title: 'Components/Common/CalendarSchedules', + title: 'Components/Calendar/CalendarSchedules', component: CalendarSchedules, parameters: { layout: 'centered', diff --git a/src/views/components/calendar/Calendar/Calendar.tsx b/src/views/components/calendar/Calendar/Calendar.tsx new file mode 100644 index 00000000..bc641188 --- /dev/null +++ b/src/views/components/calendar/Calendar/Calendar.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import CalendarHeader from 'src/views/components/calendar/CalendarHeader/CalenderHeader'; +import { CalendarBottomBar } from '../CalendarBottomBar/CalendarBottomBar'; +import { CalendarSchedules } from '../CalendarSchedules/CalendarSchedules'; +import ImportantLinks from '../ImportantLinks'; +import CalendarGrid from '../CalendarGrid/CalendarGrid'; + +export const flags = ['WR', 'QR', 'GC', 'CD', 'E', 'II']; + +interface Props { + label: string; +} + +/** + * A reusable chip component that follows the design system of the extension. + * @returns + */ +export function Calendar(): JSX.Element { + return ( + <> + +
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+ + ); +} diff --git a/src/views/components/calendar/CalendarBottomBar/CalendarBottomBar.tsx b/src/views/components/calendar/CalendarBottomBar/CalendarBottomBar.tsx index 8bf5962b..d80aa3d7 100644 --- a/src/views/components/calendar/CalendarBottomBar/CalendarBottomBar.tsx +++ b/src/views/components/calendar/CalendarBottomBar/CalendarBottomBar.tsx @@ -7,20 +7,20 @@ import ImageIcon from '~icons/material-symbols/image'; import CalendarMonthIcon from '~icons/material-symbols/calendar-month'; type CalendarBottomBarProps = { - courses: CalendarCourseCellProps[]; + courses?: CalendarCourseCellProps[]; }; /** * */ export const CalendarBottomBar = ({ courses }: CalendarBottomBarProps): JSX.Element => { - if (courses.length === -1) console.log('foo'); // dumb line to make eslint happy + if (courses?.length === -1) console.log('foo'); // dumb line to make eslint happy return (
Async. and Other:
- {courses.map(course => ( + {courses?.map(course => ( -
- {/* Displaying the rest of the calendar */} -
-
- {/* Displaying day labels */} -
- {daysOfWeek.map(day => ( -
- {day} -
- ))} - {grid.map((row, rowIndex) => row)} - {accountForCourseConflicts(courseCells)} - {/* courseCells.map((block: CalendarGridCourse) => ( +
+ {/* Displaying day labels */} +
+ {daysOfWeek.map(day => ( +
+ {day} +
+ ))} + {grid.map((row, rowIndex) => row)} + {courseCells ? accountForCourseConflicts(courseCells) : null} + {/* courseCells.map((block: CalendarGridCourse) => (
)) */} -
-
); } @@ -195,8 +189,8 @@ function accountForCourseConflicts(courseCells: CalendarGridCourse[]): JSX.Eleme style={{ gridColumn: `${block.calendarGridPoint.dayIndex + 1}`, gridRow: `${block.calendarGridPoint.startIndex + 1} / ${block.calendarGridPoint.endIndex + 1}`, - width: `calc(100% / ${block.totalColumns})`, - marginLeft: `calc(100% * ${(block.gridColumnStart - 1) / block.totalColumns})`, + width: `calc(100% / ${block.totalColumns})`, + marginLeft: `calc(100% * ${(block.gridColumnStart - 1) / block.totalColumns})`, padding: '0px 10px 4px 0px', }} > From 70a3f14e0a7208afe7f4b8b5e3bd2eb94896445b Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Mon, 19 Feb 2024 22:39:26 -0600 Subject: [PATCH 11/20] Squashed commit of the following: commit c46e4a51c98fc183ef01ee1a579c2c013951d551 Author: Abhinav Chadaga Date: Mon Feb 19 21:37:46 2024 -0600 change from reducer pattern to state variables, remove chartData from state commit 36bcdd25224261e3efb54dc0cdd0f8d22502737d Author: Abhinav Chadaga Date: Mon Feb 19 21:15:41 2024 -0600 change grade distribution colors to match updated figma commit 11a50df88db28ba9d47c305debc779b1036df119 Merge: c16b301 b4c96a9 Author: Abhinav Chadaga Date: Mon Feb 19 17:57:13 2024 -0600 Merge branch 'hackathon' into abhinavchadaga/course-catalog-popup commit c16b301ff015af77faeb286ec79f4d67f74296af Author: Abhinav Chadaga Date: Mon Feb 19 17:47:21 2024 -0600 Kinda complete the handlers commit 1ac1d9095ae05cbe85df088d932006f230d1b227 Author: Abhinav Chadaga Date: Sun Feb 18 17:36:59 2024 -0600 Bunch of renaming commit 925829ad4114015845e1aa59cb9bad91ac0de534 Author: Abhinav Chadaga Date: Sun Feb 18 17:24:53 2024 -0600 Fix syllabi url Remove unused variable and unnecessary args to url commit f2e5d51eb3a87091d8a30d08d9de9e13d05a9098 Author: Abhinav Chadaga Date: Sun Feb 18 17:24:22 2024 -0600 Add TODO replace current grade colors with a tailwind palette commit 747ee44440360b325056455cce22e241bfaea698 Author: Abhinav Chadaga Date: Sun Feb 18 01:26:51 2024 -0600 Minor tweaks change style in header commit ddfe952a320af0de4189e84ad611ef8e7319d5cb Author: Abhinav Chadaga Date: Sun Feb 18 01:26:38 2024 -0600 Add Grade Distribution Stuff commit c27bf3c390930db584578e881b3cdc5152f462b0 Author: Abhinav Chadaga Date: Sun Feb 18 01:26:13 2024 -0600 Modify story to use proper course info commit 7afdbac1b8a621618a8f79d2dda361c4670c759e Author: Abhinav Chadaga Date: Sat Feb 17 16:37:01 2024 -0600 description stuff done commit 1a894322760ac4585fcb92a135dd043252eb104e Author: Abhinav Chadaga Date: Sat Feb 17 15:26:32 2024 -0600 Rename CoursePopup Old one to "Old", remove "2" from new one commit 4c2b31e61ac9b0eca518eab0412e435039f0b4bb Author: Abhinav Chadaga Date: Sat Feb 17 15:23:01 2024 -0600 add todo for calendar button commit 11b7a51deda96565479ed8063cdddce96e28d24f Author: Abhinav Chadaga Date: Sat Feb 17 15:22:18 2024 -0600 add course button onclick handlers commit f2dfcec838553a8cb7fb437620b3f8af4f4f0783 Author: Abhinav Chadaga Date: Sat Feb 17 14:52:38 2024 -0600 some unocss updates commit f9f375514b54a9a66e59ce151314859b0a9763fb Author: Abhinav Chadaga Date: Sat Feb 17 13:00:46 2024 -0600 Add rmp callback commit 122fc6dbdd84f8fce1c038b366d372d2cb3b405e Author: Abhinav Chadaga Date: Sat Feb 17 13:00:16 2024 -0600 Change test course to 314 commit 19b124b3bdac4cf4e7c3ac3aa633aaa78610b29c Author: Abhinav Chadaga Date: Sat Feb 17 12:19:21 2024 -0600 complete CourseHeaderAndActions Component added course buttons, using proper subcomponents now. commit 2eea01fc740bfa4db2dc45045c04033421a94297 Author: Abhinav Chadaga Date: Sat Feb 17 11:22:12 2024 -0600 use chip component in header commit 9cb13c8fd1a154ac1f982c7c49562664ed603732 Merge: a62b718 9392085 Author: Abhinav Chadaga Date: Sat Feb 17 11:21:12 2024 -0600 Merge branch 'hackathon' into abhinavchadaga/course-catalog-popup commit a62b718c43fac327be83b20420caba6f5ce9e0e9 Merge: 43d2675 7b7b858 Author: Abhinav Chadaga Date: Sat Feb 17 10:57:24 2024 -0600 Merge branch 'hackathon' into abhinavchadaga/course-catalog-popup commit 43d2675be5817225f4ba6164427b5345a702d4e5 Author: Abhinav Chadaga Date: Sat Feb 17 10:54:49 2024 -0600 some work on course popup update the stories and create the header component commit 31bcef3099a09f9460fb95a5e1aee8d19350101d Merge: 874f8d5 fa1d737 Author: Abhinav Chadaga Date: Wed Feb 14 14:33:16 2024 -0600 Merge branch 'main' into abhinavchadaga/course-catalog-popup pulling from main commit 874f8d56cbc7810b2894d6e0d5441a37efc31658 Author: Abhinav Chadaga Date: Wed Feb 14 14:30:24 2024 -0600 some work --- src/shared/util/themeColors.ts | 14 ++ .../CourseCatalogInjectedPopup.stories.ts | 69 +++++++ src/stories/injected/CoursePopup.stories.ts | 2 +- src/views/components/CourseCatalogMain.tsx | 2 +- src/views/components/common/Chip/Chip.tsx | 15 +- .../CourseCatalogInjectedPopup.tsx | 24 +++ .../Description.tsx | 30 ++++ .../GradeDistribution.tsx | 170 ++++++++++++++++++ .../HeadingAndActions.tsx | 136 ++++++++++++++ .../CourseDescription.module.scss | 0 .../CourseDescription/CourseDescription.tsx | 0 .../CourseButtons/CourseButtons.module.scss | 0 .../CourseButtons/CourseButtons.tsx | 0 .../CourseHeader/CourseHeader.module.scss | 0 .../CourseHeader/CourseHeader.tsx | 0 .../CoursePopup.module.scss | 0 .../CoursePopup.tsx | 0 .../GradeDistribution.module.scss | 0 .../GradeDistribution/GradeDistribution.tsx | 0 19 files changed, 458 insertions(+), 4 deletions(-) create mode 100644 src/stories/injected/CourseCatalogInjectedPopup.stories.ts create mode 100644 src/views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup.tsx create mode 100644 src/views/components/injected/CourseCatalogInjectedPopup/Description.tsx create mode 100644 src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx create mode 100644 src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx rename src/views/components/injected/{CoursePopup => CoursePopupOld}/CourseDescription/CourseDescription.module.scss (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/CourseDescription/CourseDescription.tsx (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/CourseHeader/CourseButtons/CourseButtons.module.scss (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/CourseHeader/CourseButtons/CourseButtons.tsx (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/CourseHeader/CourseHeader.module.scss (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/CourseHeader/CourseHeader.tsx (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/CoursePopup.module.scss (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/CoursePopup.tsx (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/GradeDistribution/GradeDistribution.module.scss (100%) rename src/views/components/injected/{CoursePopup => CoursePopupOld}/GradeDistribution/GradeDistribution.tsx (100%) diff --git a/src/shared/util/themeColors.ts b/src/shared/util/themeColors.ts index f52cba4c..17571b8f 100644 --- a/src/shared/util/themeColors.ts +++ b/src/shared/util/themeColors.ts @@ -16,6 +16,20 @@ export const colors = { red: '#af2e2d', black: '#1a2024', }, + gradeDistribution: { + a: '#22c55e', + aminus: '#a3e635', + bplus: '#84CC16', + b: '#FDE047', + bminus: '#FACC15', + cplus: '#F59E0B', + c: '#FB923C', + cminus: '#F97316', + dplus: '#EA580C', // TODO (achadaga): copilot generated, get actual color from Isaiah + d: '#DC2626', + dminus: '#B91C1C', + f: '#B91C1C', + }, } as const; type NestedKeys = { diff --git a/src/stories/injected/CourseCatalogInjectedPopup.stories.ts b/src/stories/injected/CourseCatalogInjectedPopup.stories.ts new file mode 100644 index 00000000..91faa2d7 --- /dev/null +++ b/src/stories/injected/CourseCatalogInjectedPopup.stories.ts @@ -0,0 +1,69 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Course, Status } from 'src/shared/types/Course'; +import { CourseMeeting, DAY_MAP } from 'src/shared/types/CourseMeeting'; +import { CourseSchedule } from 'src/shared/types/CourseSchedule'; +import Instructor from 'src/shared/types/Instructor'; + +import CourseCatalogInjectedPopup from 'src/views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup'; + +const exampleCourse: Course = new Course({ + uniqueId: 50805, + number: '314', + fullName: 'C S 314 DATA STRUCTURES', + courseName: 'DATA STRUCTURES', + department: 'C S', + creditHours: 3, + status: Status.OPEN, + instructors: [ + new Instructor({ fullName: 'SCOTT, MICHAEL', firstName: 'MICHAEL', lastName: 'SCOTT', middleInitial: 'D' }), + ], + isReserved: true, + description: [ + 'Second part of a two-part sequence in programming. Introduction to specifications, simple unit testing, and debugging; building and using canonical data structures; algorithm analysis and reasoning techniques such as assertions and invariants.', + 'Computer Science 314 and 314H may not both be counted.', + 'BVO 311C and 312H may not both be counted.', + 'Prerequisite: Computer Science 312 or 312H with a grade of at least C-.', + 'May be counted toward the Quantitative Reasoning flag requirement.', + ], + schedule: new CourseSchedule({ + meetings: [ + new CourseMeeting({ + days: [DAY_MAP.T, DAY_MAP.TH], + startTime: 480, + endTime: 570, + location: { building: 'UTC', room: '123' }, + }), + new CourseMeeting({ + days: [DAY_MAP.TH], + startTime: 570, + endTime: 630, + location: { building: 'JES', room: '123' }, + }), + ], + }), + url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', + flags: ['Writing', 'Independent Inquiry'], + instructionMode: 'In Person', + semester: { + code: '12345', + year: 2024, + season: 'Spring', + }, +}); + +const meta: Meta = { + title: 'Components/Injected/CourseCatalogInjectedPopup', + component: CourseCatalogInjectedPopup, + argTypes: { + onClose: { action: 'onClose' }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + course: exampleCourse, + }, +}; diff --git a/src/stories/injected/CoursePopup.stories.ts b/src/stories/injected/CoursePopup.stories.ts index 3f5b3665..83377319 100644 --- a/src/stories/injected/CoursePopup.stories.ts +++ b/src/stories/injected/CoursePopup.stories.ts @@ -1,7 +1,7 @@ import { Course, Status } from 'src/shared/types/Course'; import { CourseMeeting } from 'src/shared/types/CourseMeeting'; import { UserSchedule } from 'src/shared/types/UserSchedule'; -import CoursePopup from 'src/views/components/injected/CoursePopup/CoursePopup'; +import CoursePopup from 'src/views/components/injected/CoursePopupOld/CoursePopup'; import type { Meta, StoryObj } from '@storybook/react'; import Instructor from 'src/shared/types/Instructor'; diff --git a/src/views/components/CourseCatalogMain.tsx b/src/views/components/CourseCatalogMain.tsx index c5e7e5da..723f5e7b 100644 --- a/src/views/components/CourseCatalogMain.tsx +++ b/src/views/components/CourseCatalogMain.tsx @@ -8,7 +8,7 @@ import { SiteSupport } from '../lib/getSiteSupport'; import { populateSearchInputs } from '../lib/populateSearchInputs'; import ExtensionRoot from './common/ExtensionRoot/ExtensionRoot'; import AutoLoad from './injected/AutoLoad/AutoLoad'; -import CoursePopup from './injected/CoursePopup/CoursePopup'; +import CoursePopup from './injected/CoursePopupOld/CoursePopup'; import RecruitmentBanner from './injected/RecruitmentBanner/RecruitmentBanner'; import TableHead from './injected/TableHead'; import TableRow from './injected/TableRow/TableRow'; diff --git a/src/views/components/common/Chip/Chip.tsx b/src/views/components/common/Chip/Chip.tsx index 90a6009c..b6701517 100644 --- a/src/views/components/common/Chip/Chip.tsx +++ b/src/views/components/common/Chip/Chip.tsx @@ -1,10 +1,21 @@ import React from 'react'; import Text from '../Text/Text'; -export const flags = ['WR', 'QR', 'GC', 'CD', 'E', 'II']; +/** + * A type that represents the flags that a course can have. + */ +export type Flag = 'WR' | 'QR' | 'GC' | 'CD' | 'E' | 'II'; +export const flagMap: Record = { + Writing: 'WR', + 'Quantitative Reasoning': 'QR', + 'Global Cultures': 'GC', + 'Cultural Diversity in the United States': 'CD', + Ethics: 'E', + 'Independent Inquiry': 'II', +}; interface Props { - label: string; + label: Flag; } /** diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup.tsx new file mode 100644 index 00000000..0dfe7e26 --- /dev/null +++ b/src/views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup.tsx @@ -0,0 +1,24 @@ +import Popup from '@views/components/common/Popup/Popup'; +import React from 'react'; +import { Course } from 'src/shared/types/Course'; +import { UserSchedule } from 'src/shared/types/UserSchedule'; +import Description from './Description'; +import GradeDistribution from './GradeDistribution'; +import HeadingAndActions from './HeadingAndActions'; + +interface CourseCatalogInjectedPopupProps { + course: Course; + activeSchedule?: UserSchedule; + onClose: () => void; +} + +const CourseCatalogInjectedPopup: React.FC = ({ course, activeSchedule, onClose }) => ( + +
+ + + +
+
+); +export default CourseCatalogInjectedPopup; diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/Description.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/Description.tsx new file mode 100644 index 00000000..0d8bb118 --- /dev/null +++ b/src/views/components/injected/CourseCatalogInjectedPopup/Description.tsx @@ -0,0 +1,30 @@ +import clsx from 'clsx'; +import React from 'react'; +import Text from '../../common/Text/Text'; + +interface DescriptionProps { + lines: string[]; +} + +const Description: React.FC = ({ lines }: DescriptionProps) => { + const keywords = ['prerequisite', 'restricted']; + return ( +
    + {lines.map(line => { + const isKeywordPresent = keywords.some(keyword => line.toLowerCase().includes(keyword)); + return ( +
    + +
  • + + {line} + +
  • +
    + ); + })} +
+ ); +}; + +export default Description; diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx new file mode 100644 index 00000000..b1915d37 --- /dev/null +++ b/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx @@ -0,0 +1,170 @@ +import Spinner from '@views/components/common/Spinner/Spinner'; +import Text from '@views/components/common/Text/Text'; +import Highcharts from 'highcharts'; +import HighchartsReact from 'highcharts-react-official'; +import React from 'react'; +import { Course } from 'src/shared/types/Course'; +import { Distribution, LetterGrade } from 'src/shared/types/Distribution'; +import { colors } from 'src/shared/util/themeColors'; +import { + NoDataError, + queryAggregateDistribution, + querySemesterDistribution, +} from 'src/views/lib/database/queryDistribution'; + +interface GradeDistributionProps { + course: Course; +} + +enum DataStatus { + LOADING = 'LOADING', + FOUND = 'FOUND', + NOT_FOUND = 'NOT_FOUND', + ERROR = 'ERROR', +} + +const GRADE_COLORS: Record = { + A: colors.gradeDistribution.a, + 'A-': colors.gradeDistribution.aminus, + 'B+': colors.gradeDistribution.bplus, + B: colors.gradeDistribution.b, + 'B-': colors.gradeDistribution.bminus, + 'C+': colors.gradeDistribution.cplus, + C: colors.gradeDistribution.c, + 'C-': colors.gradeDistribution.cminus, + 'D+': colors.gradeDistribution.dplus, + D: colors.gradeDistribution.d, + 'D-': colors.gradeDistribution.dminus, + F: colors.gradeDistribution.f, +}; + +const GradeDistribution: React.FC = ({ course }) => { + const [semester, setSemester] = React.useState('Aggregate'); + const [distributions, setDistributions] = React.useState>({}); + const [status, setStatus] = React.useState(DataStatus.LOADING); + const ref = React.useRef(null); + + const chartData = React.useMemo(() => { + if (status === DataStatus.FOUND && distributions[semester]) { + return Object.entries(distributions[semester]).map(([grade, count]) => ({ + y: count, + color: GRADE_COLORS[grade as LetterGrade], + })); + } + return []; + }, [distributions, semester, status]); + + React.useEffect(() => { + const fetchInitialData = async () => { + try { + const [aggregateDist, semesters] = await queryAggregateDistribution(course); + const initialDistributions: Record = { Aggregate: aggregateDist }; + const semesterPromises = semesters.map(semester => querySemesterDistribution(course, semester)); + const semesterDistributions = await Promise.all(semesterPromises); + semesters.forEach((semester, i) => { + initialDistributions[`${semester.season} ${semester.year}`] = semesterDistributions[i]; + }); + setDistributions(initialDistributions); + setStatus(DataStatus.FOUND); + } catch (e) { + console.error(e); + if (e instanceof NoDataError) { + setStatus(DataStatus.NOT_FOUND); + } else { + setStatus(DataStatus.ERROR); + } + } + }; + + fetchInitialData(); + }, [course]); + + const handleSelectSemester = (event: React.ChangeEvent) => { + setSemester(event.target.value); + }; + + const chartOptions: Highcharts.Options = { + title: { text: undefined }, + subtitle: { text: undefined }, + legend: { enabled: false }, + xAxis: { + title: { text: 'Grade' }, + categories: ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'D-', 'F'], + crosshair: true, + }, + yAxis: { + min: 0, + title: { text: 'Number of Students' }, + }, + chart: { + style: { fontFamily: 'Roboto Flex', fontWeight: '600' }, + spacingBottom: 25, + spacingTop: 25, + height: 250, + }, + credits: { enabled: false }, + accessibility: { enabled: true }, + tooltip: { + headerFormat: '{point.key}', + pointFormat: + '', + footerFormat: '
{point.y:.0f} Students
', + shared: true, + useHTML: true, + }, + plotOptions: { + bar: { pointPadding: 0.2, borderWidth: 0 }, + series: { animation: { duration: 700 } }, + }, + series: [ + { + type: 'column', + name: 'Grades', + data: chartData, + }, + ], + }; + + return ( +
+ {status === DataStatus.LOADING && } + {status === DataStatus.NOT_FOUND && No grade distribution data found} + {status === DataStatus.ERROR && Error fetching grade distribution data} + {status === DataStatus.FOUND && ( + <> +
+ Grade distribution for {`${course.department} ${course.number}`} + +
+ + + )} +
+ ); +}; + +export default GradeDistribution; diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx new file mode 100644 index 00000000..117fcfbe --- /dev/null +++ b/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx @@ -0,0 +1,136 @@ +import { Button } from '@views/components/common/Button/Button'; +import { Chip, flagMap } from '@views/components/common/Chip/Chip'; +import Divider from '@views/components/common/Divider/Divider'; +import Text from '@views/components/common/Text/Text'; +import React from 'react'; +import addCourse from 'src/pages/background/lib/addCourse'; +import openNewTab from 'src/pages/background/util/openNewTab'; +import { Course } from 'src/shared/types/Course'; +import { UserSchedule } from 'src/shared/types/UserSchedule'; +import Add from '~icons/material-symbols/add'; +import CalendarMonth from '~icons/material-symbols/calendar-month'; +import CloseIcon from '~icons/material-symbols/close'; +import Copy from '~icons/material-symbols/content-copy'; +import Description from '~icons/material-symbols/description'; +import Mood from '~icons/material-symbols/mood'; +import Reviews from '~icons/material-symbols/reviews'; + +interface HeadingAndActionProps { + /* The course to display */ + course: Course; + /* The active schedule */ + activeSchedule: UserSchedule; + /* The function to call when the popup should be closed */ + onClose: () => void; +} + +/** + * Renders the heading component for the CoursePopup component. + * + * @param {HeadingAndActionProps} props - The component props. + * @returns {JSX.Element} The rendered component. + */ +const HeadingAndActions: React.FC = ({ course, onClose, activeSchedule }) => { + const { courseName, department, number: courseNumber, uniqueId, instructors, flags, schedule } = course; + const instructorString = instructors + .map(instructor => { + const { firstName, lastName } = instructor; + if (firstName === '') return lastName; + return `${firstName} ${lastName}`; + }) + .join(', '); + const handleCopy = () => { + navigator.clipboard.writeText(uniqueId.toString()); + }; + const handleOpenCalendar = async () => { + const url = chrome.runtime.getURL('calendar.html'); + await openNewTab(url); + }; + const handleOpenRateMyProf = async () => { + const openTabs = instructors.map(instructor => { + const { fullName } = instructor; + const url = `https://www.ratemyprofessors.com/search/professors/1255?q=${fullName}`; + return openNewTab(url); + }); + await Promise.all(openTabs); + }; + const handleOpenCES = async () => { + // TODO: does not look up the professor just takes you to the page + const cisUrl = 'https://utexas.bluera.com/utexas/rpvl.aspx?rid=d3db767b-049f-46c5-9a67-29c21c29c580®l=en-US'; + await openNewTab(cisUrl); + }; + const handleOpenPastSyllabi = async () => { + // not specific to professor + const url = `https://utdirect.utexas.edu/apps/student/coursedocs/nlogon/?year=&semester=&department=${department}&course_number=${courseNumber}&course_title=${courseName}&unique=&instructor_first=&instructor_last=&course_type=In+Residence&search=Search`; + await openNewTab(url); + }; + const handleAddCourse = async () => { + await addCourse(activeSchedule.name, course); + }; + return ( +
+
+
+ + {courseName} + + + {' '} + ({department} {courseNumber}) + + + +
+
+ + with {instructorString} + +
+ {flags.map(flag => ( + + ))} +
+
+
+ {schedule.meetings.map(meeting => ( + + {meeting.getDaysString({ format: 'long', separator: 'long' })}{' '} + {meeting.getTimeString({ separator: ' to ', capitalize: false })} + {meeting.location && ( + <> + {` in `} + + {meeting.location.building} + + + )} + + ))} +
+
+
+ + + + +
+ +
+ ); +}; + +export default HeadingAndActions; diff --git a/src/views/components/injected/CoursePopup/CourseDescription/CourseDescription.module.scss b/src/views/components/injected/CoursePopupOld/CourseDescription/CourseDescription.module.scss similarity index 100% rename from src/views/components/injected/CoursePopup/CourseDescription/CourseDescription.module.scss rename to src/views/components/injected/CoursePopupOld/CourseDescription/CourseDescription.module.scss diff --git a/src/views/components/injected/CoursePopup/CourseDescription/CourseDescription.tsx b/src/views/components/injected/CoursePopupOld/CourseDescription/CourseDescription.tsx similarity index 100% rename from src/views/components/injected/CoursePopup/CourseDescription/CourseDescription.tsx rename to src/views/components/injected/CoursePopupOld/CourseDescription/CourseDescription.tsx diff --git a/src/views/components/injected/CoursePopup/CourseHeader/CourseButtons/CourseButtons.module.scss b/src/views/components/injected/CoursePopupOld/CourseHeader/CourseButtons/CourseButtons.module.scss similarity index 100% rename from src/views/components/injected/CoursePopup/CourseHeader/CourseButtons/CourseButtons.module.scss rename to src/views/components/injected/CoursePopupOld/CourseHeader/CourseButtons/CourseButtons.module.scss diff --git a/src/views/components/injected/CoursePopup/CourseHeader/CourseButtons/CourseButtons.tsx b/src/views/components/injected/CoursePopupOld/CourseHeader/CourseButtons/CourseButtons.tsx similarity index 100% rename from src/views/components/injected/CoursePopup/CourseHeader/CourseButtons/CourseButtons.tsx rename to src/views/components/injected/CoursePopupOld/CourseHeader/CourseButtons/CourseButtons.tsx diff --git a/src/views/components/injected/CoursePopup/CourseHeader/CourseHeader.module.scss b/src/views/components/injected/CoursePopupOld/CourseHeader/CourseHeader.module.scss similarity index 100% rename from src/views/components/injected/CoursePopup/CourseHeader/CourseHeader.module.scss rename to src/views/components/injected/CoursePopupOld/CourseHeader/CourseHeader.module.scss diff --git a/src/views/components/injected/CoursePopup/CourseHeader/CourseHeader.tsx b/src/views/components/injected/CoursePopupOld/CourseHeader/CourseHeader.tsx similarity index 100% rename from src/views/components/injected/CoursePopup/CourseHeader/CourseHeader.tsx rename to src/views/components/injected/CoursePopupOld/CourseHeader/CourseHeader.tsx diff --git a/src/views/components/injected/CoursePopup/CoursePopup.module.scss b/src/views/components/injected/CoursePopupOld/CoursePopup.module.scss similarity index 100% rename from src/views/components/injected/CoursePopup/CoursePopup.module.scss rename to src/views/components/injected/CoursePopupOld/CoursePopup.module.scss diff --git a/src/views/components/injected/CoursePopup/CoursePopup.tsx b/src/views/components/injected/CoursePopupOld/CoursePopup.tsx similarity index 100% rename from src/views/components/injected/CoursePopup/CoursePopup.tsx rename to src/views/components/injected/CoursePopupOld/CoursePopup.tsx diff --git a/src/views/components/injected/CoursePopup/GradeDistribution/GradeDistribution.module.scss b/src/views/components/injected/CoursePopupOld/GradeDistribution/GradeDistribution.module.scss similarity index 100% rename from src/views/components/injected/CoursePopup/GradeDistribution/GradeDistribution.module.scss rename to src/views/components/injected/CoursePopupOld/GradeDistribution/GradeDistribution.module.scss diff --git a/src/views/components/injected/CoursePopup/GradeDistribution/GradeDistribution.tsx b/src/views/components/injected/CoursePopupOld/GradeDistribution/GradeDistribution.tsx similarity index 100% rename from src/views/components/injected/CoursePopup/GradeDistribution/GradeDistribution.tsx rename to src/views/components/injected/CoursePopupOld/GradeDistribution/GradeDistribution.tsx From 9ec0d106f5c8bcd1ccb94d955ecb5ed1964ce8b0 Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Mon, 19 Feb 2024 23:03:53 -0600 Subject: [PATCH 12/20] Chrome extension works --- src/views/components/CourseCatalogMain.tsx | 3 ++- src/views/components/PopupMain.tsx | 2 +- .../injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/views/components/CourseCatalogMain.tsx b/src/views/components/CourseCatalogMain.tsx index 723f5e7b..065d39bb 100644 --- a/src/views/components/CourseCatalogMain.tsx +++ b/src/views/components/CourseCatalogMain.tsx @@ -13,6 +13,7 @@ import RecruitmentBanner from './injected/RecruitmentBanner/RecruitmentBanner'; import TableHead from './injected/TableHead'; import TableRow from './injected/TableRow/TableRow'; import TableSubheading from './injected/TableSubheading/TableSubheading'; +import CourseCatalogInjectedPopup from './injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup'; interface Props { support: SiteSupport.COURSE_CATALOG_DETAILS | SiteSupport.COURSE_CATALOG_LIST; @@ -79,7 +80,7 @@ export default function CourseCatalogMain({ support }: Props) { ); })} {selectedCourse && ( - -
+
Logo diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx index 117fcfbe..ee1313e1 100644 --- a/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx +++ b/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx @@ -81,7 +81,7 @@ const HeadingAndActions: React.FC = ({ course, onClose, a -
From 5a2ee0d19a69e855891bc0c9e8fb9ef2504c2453 Mon Sep 17 00:00:00 2001 From: Samuel Gunter Date: Tue, 20 Feb 2024 17:20:28 -0600 Subject: [PATCH 13/20] fix: change Chromatic action to build current branch, not base branch (#100) --- .github/workflows/chromatic.yml | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index ae5482b6..bbe47456 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -1,26 +1,26 @@ -name: "Chromatic" +name: 'Chromatic' -on: [push, pull_request_target] +on: [push, pull_request] jobs: - chromatic: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup pnpm - uses: pnpm/action-setup@v3 - with: - version: 8 + chromatic: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup pnpm + uses: pnpm/action-setup@v3 + with: + version: 8 - - name: Install dependencies - run: pnpm install + - name: Install dependencies + run: pnpm install - - name: Publish to Chromatic - uses: chromaui/action@latest - with: - projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - exitZeroOnChanges: true - autoAcceptChanges: "main" + - name: Publish to Chromatic + uses: chromaui/action@latest + with: + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + exitZeroOnChanges: true + autoAcceptChanges: 'main' From a5fe6ec06b9388dd1e5b61461c0d51cc714a6089 Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Tue, 20 Feb 2024 21:20:37 -0600 Subject: [PATCH 14/20] Can open tabs, updated injected popup heading. basically done --- src/pages/calendar/CalendarMain.tsx | 3 +- src/shared/types/UserSchedule.ts | 2 +- src/shared/util/themeColors.ts | 1 + src/views/components/PopupMain.tsx | 150 +++++++++--------- .../HeadingAndActions.tsx | 39 +++-- src/views/lib/openNewTabFromContentScript.ts | 25 +++ 6 files changed, 130 insertions(+), 90 deletions(-) create mode 100644 src/views/lib/openNewTabFromContentScript.ts diff --git a/src/pages/calendar/CalendarMain.tsx b/src/pages/calendar/CalendarMain.tsx index 7be7e360..a9abf555 100644 --- a/src/pages/calendar/CalendarMain.tsx +++ b/src/pages/calendar/CalendarMain.tsx @@ -1,5 +1,6 @@ import React from 'react'; import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot'; +import { Calendar } from 'src/views/components/calendar/Calendar/Calendar'; /** * Calendar page @@ -8,7 +9,7 @@ import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot' export default function CalendarMain() { return ( -
Calendar Placeholder
+
); } diff --git a/src/shared/types/UserSchedule.ts b/src/shared/types/UserSchedule.ts index 1238cfb3..2806ebe2 100644 --- a/src/shared/types/UserSchedule.ts +++ b/src/shared/types/UserSchedule.ts @@ -21,4 +21,4 @@ export class UserSchedule { containsCourse(course: Course): boolean { return this.courses.some(c => c.uniqueId === course.uniqueId); } -} \ No newline at end of file +} diff --git a/src/shared/util/themeColors.ts b/src/shared/util/themeColors.ts index 17571b8f..6a9b6da5 100644 --- a/src/shared/util/themeColors.ts +++ b/src/shared/util/themeColors.ts @@ -11,6 +11,7 @@ export const colors = { gray: '#9cadb7', offwhite: '#d6d2c4', concrete: '#95a5a6', + red: '#B91C1C' // Not sure if this should be here, but it's used for remove course, and add course is ut-green }, theme: { red: '#af2e2d', diff --git a/src/views/components/PopupMain.tsx b/src/views/components/PopupMain.tsx index 58eb8273..f441ca85 100644 --- a/src/views/components/PopupMain.tsx +++ b/src/views/components/PopupMain.tsx @@ -1,100 +1,100 @@ import React from 'react'; import { FaCalendarAlt, FaCog, FaRedo } from 'react-icons/fa'; // Added FaRedo for the refresh icon import { StatusIcon } from '@shared/util/icons'; -import { generateCourses } from 'src/stories/components/List.stories'; import { Status } from 'src/shared/types/Course'; +import { test_colors } from 'src/stories/components/PopupCourseBlock.stories'; import ExtensionRoot from './common/ExtensionRoot/ExtensionRoot'; import PopupCourseBlock from './common/PopupCourseBlock/PopupCourseBlock'; import Text from './common/Text/Text'; import Divider from './common/Divider/Divider'; import logoImage from '../../assets/logo.png'; // Adjust the path as necessary import List from './common/List/List'; // Ensure this path is correctly pointing to your List component +import useSchedules from '../hooks/useSchedules'; +import { handleOpenCalendar } from './injected/CourseCatalogInjectedPopup/HeadingAndActions'; +import { openTabFromContentScript } from '../lib/openNewTabFromContentScript'; + export default function PopupMain() { - const courses = generateCourses(5); + const [activeSchedule] = useSchedules(); + + const draggableElements = activeSchedule?.courses.map((course, i) => ( + + )); - // Manually applying colors for the demonstration - const colors = { - OPEN: { primaryColor: '#34D399', secondaryColor: '#059669' }, - CLOSED: { primaryColor: '#818cf8', secondaryColor: '#4f46e5' }, - WAITLISTED: { primaryColor: '#F59E00', secondaryColor: '#B45309' }, - CANCELLED: { primaryColor: '#EF4444', secondaryColor: '#b91c1c' }, - TEMP: { primaryColor: '#fde047', secondaryColor: '#eab308' }, - }; + const handleOpenOptions = async () => { // Not sure if it's bad practice to export this + const url = chrome.runtime.getURL('/src/pages/options/index.html'); + await openTabFromContentScript(url); + }; - const draggableElements = courses.map((course) => ( - -)); - - -return ( - -
-
-
- Logo -
- UT Registration - Plus + return ( + +
+
+
+ Logo +
+ UT Registration + Plus +
+
+
+ +
-
- - -
-
- -
- MAIN SCHEDULE: -
- 22 HOURS - 8 Courses -
-
- {/* Integrate the List component here */} - -
-
-
- + +
+ MAIN SCHEDULE: +
+ 22 HOURS + 8 Courses
- WAITLISTED
-
-
- + {/* Integrate the List component here */} + {activeSchedule ? : null} +
+
+
+ +
+ WAITLISTED +
+
+
+ +
+ CLOSED +
+
+
+ +
+ CANCELLED
- CLOSED
-
-
- +
+
+ DATA UPDATED ON: 12:00 AM 02/01/2024 +
- CANCELLED
-
-
- DATA UPDATED ON: 12:00 AM 02/01/2024 - -
-
-
- -); + + ); } diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx index ee1313e1..571ea1ae 100644 --- a/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx +++ b/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx @@ -1,13 +1,15 @@ +import React, { useState } from 'react'; import { Button } from '@views/components/common/Button/Button'; import { Chip, flagMap } from '@views/components/common/Chip/Chip'; import Divider from '@views/components/common/Divider/Divider'; import Text from '@views/components/common/Text/Text'; -import React from 'react'; import addCourse from 'src/pages/background/lib/addCourse'; -import openNewTab from 'src/pages/background/util/openNewTab'; +import removeCourse from 'src/pages/background/lib/removeCourse'; +import { openTabFromContentScript } from 'src/views/lib/openNewTabFromContentScript'; import { Course } from 'src/shared/types/Course'; import { UserSchedule } from 'src/shared/types/UserSchedule'; import Add from '~icons/material-symbols/add'; +import Minus from '~icons/material-symbols/minus'; import CalendarMonth from '~icons/material-symbols/calendar-month'; import CloseIcon from '~icons/material-symbols/close'; import Copy from '~icons/material-symbols/content-copy'; @@ -24,6 +26,11 @@ interface HeadingAndActionProps { onClose: () => void; } +export const handleOpenCalendar = async () => { // Not sure if it's bad practice to export this + const url = chrome.runtime.getURL('calendar.html'); + await openTabFromContentScript(url); +}; + /** * Renders the heading component for the CoursePopup component. * @@ -32,6 +39,10 @@ interface HeadingAndActionProps { */ const HeadingAndActions: React.FC = ({ course, onClose, activeSchedule }) => { const { courseName, department, number: courseNumber, uniqueId, instructors, flags, schedule } = course; + const [courseAdded, setCourseAdded] = useState( + activeSchedule.courses.some(course => course.uniqueId === uniqueId) + ); + const instructorString = instructors .map(instructor => { const { firstName, lastName } = instructor; @@ -42,30 +53,32 @@ const HeadingAndActions: React.FC = ({ course, onClose, a const handleCopy = () => { navigator.clipboard.writeText(uniqueId.toString()); }; - const handleOpenCalendar = async () => { - const url = chrome.runtime.getURL('calendar.html'); - await openNewTab(url); - }; const handleOpenRateMyProf = async () => { const openTabs = instructors.map(instructor => { const { fullName } = instructor; const url = `https://www.ratemyprofessors.com/search/professors/1255?q=${fullName}`; - return openNewTab(url); + return openTabFromContentScript(url); }); await Promise.all(openTabs); }; const handleOpenCES = async () => { // TODO: does not look up the professor just takes you to the page const cisUrl = 'https://utexas.bluera.com/utexas/rpvl.aspx?rid=d3db767b-049f-46c5-9a67-29c21c29c580®l=en-US'; - await openNewTab(cisUrl); + await openTabFromContentScript(cisUrl); }; const handleOpenPastSyllabi = async () => { // not specific to professor const url = `https://utdirect.utexas.edu/apps/student/coursedocs/nlogon/?year=&semester=&department=${department}&course_number=${courseNumber}&course_title=${courseName}&unique=&instructor_first=&instructor_last=&course_type=In+Residence&search=Search`; - await openNewTab(url); + await openTabFromContentScript(url); }; - const handleAddCourse = async () => { - await addCourse(activeSchedule.name, course); + const handleAddOrRemoveCourse = async () => { + if (!courseAdded) { + await addCourse(activeSchedule.name, course); + } + else { + await removeCourse(activeSchedule.name, course); + } + setCourseAdded(!courseAdded); }; return (
@@ -124,8 +137,8 @@ const HeadingAndActions: React.FC = ({ course, onClose, a -
diff --git a/src/views/lib/openNewTabFromContentScript.ts b/src/views/lib/openNewTabFromContentScript.ts new file mode 100644 index 00000000..cf48d447 --- /dev/null +++ b/src/views/lib/openNewTabFromContentScript.ts @@ -0,0 +1,25 @@ +import { createMessenger } from "chrome-extension-toolkit"; + +type MyMessages = { + openNewTab: { + data: { url: string }; + }; + }; + +const messenger = createMessenger('background'); + +/** + * Content scripts and background scripts are isolated environments. + * Content scripts are where our code interacting with the webpage lives, + * whereas the background script is where we can open a tab from. + * This function allows us to open a new tab from the content script by communicating + * with the background script. + */ +export async function openTabFromContentScript(url: string) { + // @ts-ignore + messenger.openNewTab({ url }).then(() => { + console.log('New tab opened with URL:', url); + }).catch((error) => { + console.error('Error opening new tab:', error); + }); +} From 0a3c31ec09d4af12da265d8668f2f03abb225d9f Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Tue, 20 Feb 2024 21:39:11 -0600 Subject: [PATCH 15/20] Fixed some bugs --- .../calendar/CalendarGrid.stories.tsx | 90 +++++++++---------- .../calendar/CalendarGrid/CalendarGrid.tsx | 9 +- .../HeadingAndActions.tsx | 4 +- 3 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/stories/components/calendar/CalendarGrid.stories.tsx b/src/stories/components/calendar/CalendarGrid.stories.tsx index d22c27d9..43cf9d86 100644 --- a/src/stories/components/calendar/CalendarGrid.stories.tsx +++ b/src/stories/components/calendar/CalendarGrid.stories.tsx @@ -58,56 +58,56 @@ const testData: CalendarGridCourse[] = [ }, }, { - calendarGridPoint: { - dayIndex: 4, - startIndex: 10, - endIndex: 11, - }, - componentProps: { - courseDeptAndInstr: 'Course 1', - timeAndLocation: '9:00 AM - 10:00 AM, Room 101', - status: Status.OPEN, - colors: getCourseColors('emerald', 500), - }, + calendarGridPoint: { + dayIndex: 4, + startIndex: 10, + endIndex: 11, + }, + componentProps: { + courseDeptAndInstr: 'Course 1', + timeAndLocation: '9:00 AM - 10:00 AM, Room 101', + status: Status.OPEN, + colors: getCourseColors('emerald', 500), + }, }, { - calendarGridPoint: { - dayIndex: 1, - startIndex: 10, - endIndex: 12, - }, - componentProps: { - courseDeptAndInstr: 'Course 2', - timeAndLocation: '10:00 AM - 11:00 AM, Room 102', - status: Status.CLOSED, - colors: getCourseColors('emerald', 500), - }, + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 2', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, }, { - calendarGridPoint: { - dayIndex: 1, - startIndex: 10, - endIndex: 12, - }, - componentProps: { - courseDeptAndInstr: 'Course 3', - timeAndLocation: '10:00 AM - 11:00 AM, Room 102', - status: Status.CLOSED, - colors: getCourseColors('emerald', 500), - }, + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 3', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, }, { - calendarGridPoint: { - dayIndex: 1, - startIndex: 10, - endIndex: 12, - }, - componentProps: { - courseDeptAndInstr: 'Course 4', - timeAndLocation: '10:00 AM - 11:00 AM, Room 102', - status: Status.CLOSED, - colors: getCourseColors('emerald', 500), - }, + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 4', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, }, ]; @@ -118,4 +118,4 @@ export const Default: Story = { saturdayClass: true, courseCells: testData, }, -}; \ No newline at end of file +}; diff --git a/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx b/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx index 486ec138..735fff49 100644 --- a/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx +++ b/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx @@ -119,7 +119,7 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren ))} {grid.map((row, rowIndex) => row)} - {courseCells ? accountForCourseConflicts(courseCells) : null} + {courseCells ? : null} {/* courseCells.map((block: CalendarGridCourse) => (
{ const { dayIndex } = cell.calendarGridPoint; @@ -199,6 +203,7 @@ function accountForCourseConflicts(courseCells: CalendarGridCourse[]): JSX.Eleme timeAndLocation={block.componentProps.timeAndLocation} status={block.componentProps.status} colors={block.componentProps.colors} + onClick={} />
)); diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx index 571ea1ae..464d87d2 100644 --- a/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx +++ b/src/views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions.tsx @@ -9,7 +9,7 @@ import { openTabFromContentScript } from 'src/views/lib/openNewTabFromContentScr import { Course } from 'src/shared/types/Course'; import { UserSchedule } from 'src/shared/types/UserSchedule'; import Add from '~icons/material-symbols/add'; -import Minus from '~icons/material-symbols/minus'; +import Remove from '~icons/material-symbols/remove'; import CalendarMonth from '~icons/material-symbols/calendar-month'; import CloseIcon from '~icons/material-symbols/close'; import Copy from '~icons/material-symbols/content-copy'; @@ -137,7 +137,7 @@ const HeadingAndActions: React.FC = ({ course, onClose, a -
From 8c82282467855edd8fc9a7f6a65a8747befa941a Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Tue, 20 Feb 2024 21:51:42 -0600 Subject: [PATCH 16/20] Update CalendarGrid.tsx --- src/views/components/calendar/CalendarGrid/CalendarGrid.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx b/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx index 735fff49..3635bf9c 100644 --- a/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx +++ b/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx @@ -203,7 +203,6 @@ function AccountForCourseConflicts({ courseCells }: AccountForCourseConflictsPro timeAndLocation={block.componentProps.timeAndLocation} status={block.componentProps.status} colors={block.componentProps.colors} - onClick={} />
)); From 49c0d63f0b68a79d1ad234e8879c7f0bddfd8b03 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 20 Feb 2024 22:06:26 -0600 Subject: [PATCH 17/20] Icon added successfully --- .vscode/settings.json | 3 +++ .../components/calendar/CalendarHeader/CalenderHeader.tsx | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index a89cbd32..fdec09bf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -37,4 +37,7 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "typescript.tsdk": "node_modules/typescript/lib", + "tailwindCSS.includeLanguages": { + "plaintext": "javascript" + } } diff --git a/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx b/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx index 29ba99c3..e1f95e31 100644 --- a/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx +++ b/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx @@ -10,6 +10,7 @@ import RedoIcon from '~icons/material-symbols/redo'; import SettingsIcon from '~icons/material-symbols/settings'; import ScheduleTotalHoursAndCourses from '../../common/ScheduleTotalHoursAndCourses/ScheduleTotalHoursAndCourses'; import CourseStatus from '../../common/CourseStatus/CourseStatus'; +import calIcon from 'src/assets/logo.png'; const CalendarHeader = () => (
@@ -19,7 +20,8 @@ const CalendarHeader = () => (