From ed94f8019dbeb4f81e1d7300c5693bb23746a337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 14 Apr 2024 15:15:10 +0000 Subject: [PATCH 01/15] feat(home/grid): add github link --- src/app/_components/grid/cards/cat.jpg | Bin 0 -> 58572 bytes .../_components/grid/cards/github-link.tsx | 40 ++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/app/_components/grid/cards/cat.jpg create mode 100644 src/app/_components/grid/cards/github-link.tsx diff --git a/src/app/_components/grid/cards/cat.jpg b/src/app/_components/grid/cards/cat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4356c41a430cdce808247daca7bde121c0c758b0 GIT binary patch literal 58572 zcmb5VRa9I}8#UNiu;7imI|OJPf_osiy9H~kaY=A#+@W!IcTIvz8h1-@hu{f8hWDF) zt(m!;ea=m-r)rm-s`E(I%ks-F0IssUk~{zb0Rf=+`T$>sVrFGyC8g$k$I0@Jk%g7z zKN18~R8$N!3<3-c0v0kNGM4|}cjg=?F)Vi=4WNXkQn4z81(5}@ z05OQBqJoWG(jCvk$Paxt`q1PcUEkp32jj=4y$|HZ-_-%QI&!$`k_Z$*@lq(rKs-r2 zNfcylfRu(hKqMGN3V`cQAEvE=A~m{zB8ebN2vEn>py0sjn?j5$xt*d<{Q2?Vg8;b; zNzO_;_cwOd>Bc2_8GEsX(isDVz`DUtN!? zbndT}1#&_|9y)f^@@7kwqKFkd%ySO~M>4#QePjIvwfFcZ%Myzw&v}tKJuEm3ci2XT zMd!pOrY8d?=Rn?8y)I)Y(LVqP9z{dtQ~^=hY)XsPO+IV(USYTJi%q=#>Ww*cbJ;i1h26c-O?|qlRz6w&4ognT z<$4W5w19lNgZ<2)kU78?H* zk4*Rl0T2M%47h|d5&vjy6qT2!{TipSl#>V(_blVdwt&dGEq-q+@klUewg8kQun!BD z@Kw5i{`A0kp!SJX;)d#G+^k(HMOpM5!px zk>+VCwY4RVpc`j*FE?ZjqL*+*Y3BySxX07jqz$>B4cUoyW$00$8K}FcOWb7)OL_GZ^_YncpLPa-X zBW_8b^oprWdlyQ=Ea-Sp=~w`06)b>gR+56=9^FsmRNqmgD4?bXXUC|;`MC7yt%Oej zL*$uP?~pZ6oD*i=3OroCvHiCLyVQX=>i`gBfdF;F;^CkX8aCD?D+L~#Pq3gH90>@@ z?0#r_6aw&n>mLPhOU?PSHkYY?`bxyCK!{)>dy_rEZ7_<4Ss-l6EPGc#PfZCVA_UH!zOQoMN52M5NJLZuiuGMFAby z;?!T4#eV>S!Z5`P71d_>ln~^62|E+#_XWy2DN@S8We($$2TJ5vm0ens4&n|3BfjGH z99QqnAc?>0ep)*9DG|4}{Dzwq-%>QQ0T3q7?aik6$m%bCotv>$d@btv$$>=?wNqRi zY&qUxF}J2iDQ1T#(E3lgI2SD;v+)buED*zjCLHoQhgH$NuoAq+=DtL7FO+nTZ+f zi|wO-rc=x3SqC*AZ(ByL>!tykljp zw{Ow(^gIlml@GPx);H1q@AWYnVo?D`$cAPCfF&MpJhUK>z`N$!MG2NZTdTHQwNNW4 zr+uIAHozt~1z$3bh1gHI$l`fIbTVXl_v0-S!Y}x89!w2t9@gAi5|I0~?A!#&3|IR? z_CwyyFSs_eeUU);+_{IV9u0S8nU<2TDAq<+M@EoE0pMvnR7G`h9HJGC(4+cYB)Sl5 zE^*8Y;@#=T`8$&i{nS+2c-uPpjq%uNW^8N@Zir_EcW>;kLLB@P<@0Y#NJrC!Hu&ZP z<~xpfc?>*LEk?70^`Kqzt9OpeB_W8dhwp&)rITm{EKw}M>>EC|!LrFGUZ31VYlPw; z3JNpRu4j!zBjvZu{%W`#ct5CBT=d)Mq78R5kI%wqe?#tgCw%^nee(GQP|W*|Yu+Qk zVf+Slx)I;?t17H4_hUS>*GH4i6Sky^f*`bAjR6YrHUV1~os^r<^1LaKRWYtRU9MYq zfbZt~T%Hd6%tH>T+6C431yE)+cKuu$NonLetl{GN`Orh0=$nRi(&dl|B)93%k^*w2 zXw-#W=?i=IXFA+()Z;&TtI*G%^PNt-UkpbSei|@+s83<%=vd5cQ8As{wj4`|n+xsjc zNN_a@+0Ze@R|19<6`&OW=pr14KF5E{Jl!njzz~vih+{w-)F4FAsR9f0A*}tBrxY8I z8Z7_>Vap@7ZH4OtDv)E{8gE=UZjJC22g)4!T0e5!4kiF@z(cNyYRCIVO3Lxk@-cmxl4mf1LfGBd>yT_IR7gN<^(264H41lZvZ5I~+M6r{Q z+_2wQsQ#-ys15*NG0M-8xuUuaeq7dtJ-er@ij_|v&p^}h2UyuJ;TU}~zFfFc)H?f)w5*-4GtOMkpd1hZ6$@EgU4el( z)v(Jr;|l#5`bh5)<4Q%6>nO84t@BX2m!N2?uf6V=k?zo9) zqyXEwkRH(@=)U{|FZQN^c__}D?R6h|X=HvA+fGb9tk6a5lNkssw40~7J(cGaNgv6^ zLRY}^JM#s=a{B_H22${k0ty!72q{9j4?zda^vCeB>@ofkLKiXfu}{MOI}2%9wVOam z&CTa(V_*NAVnRcK{vL*w@)PkA|68)Cpr(G#aIFaiH!i#336n_CB3rz~>uWxxZFBcF zc=#8sZcIV+ROkZLJE}OlS~=cLnG;iW8e9SWBS7%X#7D;vR*g^(-zjyukR7aR?a$Bfi4PKgn=kTgw7F<#rb2EKBH-J z%|S)cACQI@9v)6v(~G2wD@O<qh%Q;cC$Nt$2rWsv_>_I!iv9<>!( zbaE3a?h8>UadA8n`RkJGU0fiCOt{08QfE-2AkFg|pMgbD9@{RMeAz=u+-LJ)bGvW6 zxFAKMa#VA;0%1mFg*;{QN>AIjc(v>&R{NkjGD`*dXDmtIucFcPu819RhanZAVd^vc z^BWdiT(LI2&%gHa6!eHbZ`YMkV0YAXQZ!Y`(5LH;PG1~WH8S9tLrvYHDgYscxXnxJ zNtd12pX1-BgbV*Y(NN5=Rm9Y*PiPb&do1#uw}2^;!zXdvA_1r#kO$Jho%>YDT1`1Q z!0Q}VAyyls%@Z#ldlvg%__D*4Mt|rY+TF++jGcD;BdEnDwWUq&W=QE`+iNf{p2cS+ zkq)9O5X>``Y0_JutPt8aC}1n_x9>U)ubdbug-8GVZt?N*>`UH2P>7wipg!e3cB(Y- zw7ZcOd;tNDaBdmz2*Z}egS*CgOW~AXSPHLkphA4R<6Y5M>pH6i=Op-5IS|ZUf6A12 zBr!Br(jq%9<~V!=a!V$u`P5Kp-`tB-{i#=+RQZCX!;V`McY9#Tv(PqT1{vaXdbWgw zd;^FlXN$eRM+T5bEUS|i0$=SJh_vkH2@WB+)R(wg=VB}~h+WFbu?E`>n2=GFm#=#m zoeON;fQ+mq_c7zUf51w^&7wu+u%HJ}jA0iEO@;_o4~L0~8%IU`D%@VMK0dw}3{)0_ zq$uS85VYoT_&?92o>E<)AtoJ@Y%rOZXrL(21OZSxk3WBI67+tr*H_ECFhN<_PlVzh z-xrTP7YBEv6yFO}S6yEX@xbJ&Q=%^j5y}<*sac|^`0R@>&9B$RA8i}=ri-8X3$hOQ zJJL2$Cx>^So^`YN-3tALKxS5g*3}oCtL=A4-eEs=QBKnZ^y8iZ04{;go@bF!{G+c1 z4;qrwA91IX!-TpnDRW6eIMUb1hP`BF{Hq(jy-vXgot--;;b%2fO?sHxXkn+M1@?; z9DwxXI0lY72@D+>;nfcV;zif+8xnG;wIpjOpoK=@BhPsLj?);}KpHp9mAB30U$FV9 zu^GQbo6*-FGQ+sNA5za))F`US7_Xw{=5K-u^wd#7L4%6Oi;MjAg}6U(QxTK76ntv| z;K*M07Ji4_O%eQ0X=Jp5`Q^EApO!l9S>42}Y``47g(?ssISvxBktRs9oG zC!87>*@FN8L_3*7Gwh9PD);|tL_S3Pi0gN5MCz)(e$lOVz-r|${18c(T*$11Y8_zR z&^n+)#ZOoiRfI^IS;q#_YXIOiMBCk|c@`gUkMMmu=ya<90B}geNSsm^{wmb}8AT2= zf3=t0PWlK>KgE-A9R63wH?;USG3ajRRN&@XX770T+IPu5xX69gL3_AWd}wsXqk9dPk3ki z_uzBVl%YMuGj-P{!$R8WNEuvbiZm-Wvi4}V_gXP}lH@H$F2b$~RqBmW7sD(uJA+nx zLETYq)Ae{SgXdye=>D$Tto)Yo0-lCq(kTGBrp0hn;JB=Kzh*dHr;^KvvsN!H0~GX1 z^@_43(wb39$YSB)Go*Eh*eEv6C+!rAC}A?s@7Xd?YP+Za03cY`J5zBqBe_W#f0AH5 zBJ>nT&`W#Fy|kDk*h%;rVM!Q8F-=M=ji)&67sUb?3A1OH$F?Vi-CD?ZsGsaMkPnVh#7L|0}r9#@~IuCjcPf!fIo(n{Xy8W@S5?yrj0(kd2rPjC} zd=OZ@(pG1MFQ)_R)9psNVe5*ph#@5CRmv+5ttddl04#wF*Qi-|o#g-kq`6xvg2Q2f z>cfvbJPgyXx&Ck94^ndPVCMB~L|3iN?y0;*0{~cr)hQHQ{l(>aO_REOFb%AnJb2%X zd^AQ=5)_n_LDe5MBl%z1sKXyGfcUiqjQ>(72_?So{1;W=EeDKx1@<_&;vuiiHZau) zE0G(tF<8T!)F0Q*czR>08aN|WJ!u;g+wfm8F+}kQ(OGtz8BNUw4%DLDo?adoYSPq; zJ!!Q(8jnOp#fty@E)^`kcO!#n6wv>Q{09UZ`z$O+_n<)j{l`cb^!mP9 zt2Eel|8?b6F9aYK08n2YMIc-N0umA;3K9|$G7x1Q5BMuL51XnDwJ=&8hUI42vfYtyb zsxY|PyIB8J0ex;maII?O+dyy&)6o}q(1LMk*w=yb7Xa=Hpc%%0jlJh`bG-?DQu3s( z4m2d$*1+Rzb&w7-I)OJ5M^NaLrb3IXwNyc4&0l0`*J(-oN+yveK z(Fr*8;1<$P;Q4d5goWs=Fj}8)u5qn=z0^OUS=`aIleh8$kV4m7VgqKj-c-ut)Ae-B zz_3R<p4ZlpK_fY2DJus=NBFD6Q=pNMmWIZYQEcW#vx+Uw`^&BT1XW2ZN;u zP99?H0JI2HoZ4cp4?-Fk`<2=A`0W=IQZyq(N^A60J9zy3cVwMZbh+v-E^K~Im%h(! z8=Pfazv*YPT-rxWelU&Sj%!^uL-YB^E@o3pb=iMuRK$p*QCVaqsrnCh1^{nUF- zEHViJdP7fT;aTYHhN;mH9O<1nzb`-pW7n_#ONLNNWNSn~|w%dn*Qlsw=(R5e&i$R3{ln89VN)adTqR3bdh zS8!=iPowJrw{12!cO=Vu_`5Wmk2(R--l(pQoa7w%Cf>Tmef47k-0j@M$B89r2wj?v zB!a3AJIKuLiY4h6%x;vEy5%|vc=mPoBzbgQhOWJ8>ndA$Nv5ni(Dwe%4jHMnAh`hB za5Az#wX1QcfntuZzmSXv|Egh$ZT1~g0_v;uGIDJkhzMVxtX=xZ=T4G4PVV%x@#mXi zjwwO1JvLb_(+1=<2qp+j%2bCX01r!b}unmK{2Wmw6%@{an zUd3Ft`opTXxwpup`eUiIjBZ}FblZvtmB$wKm0NKyjsK!3yVg#f2)J!B6F*j%*Hk;2 z@Mpowx@vu^Wk=v*@p_>k7T@W;&~FXjoBcq98Rt+;_SQCHH)jU+wEg*c$vHK#4&8Pw zYaaFN+Fxnwj~c?WA3haTOYOZk_WUalU+p`TE&F#a{L93eZX2E%)wZ#r0?v9#bOz|n zIi+oL?S}D$92xQ~*%x;(BtvQIAGA_TkgIIPESgHB?LC=2i^sSE!Xcdm-8A?^ttlPIhmmQVL3ZZT9Ev#5JNGq-r!hx7=O; z>^OEof#3J9ZDbYG22M-4ru^qskEwJHq% z=ps8kFlq8Nda%Iyyl1V7S)ic5bguH}r1|eJfCx~P95w#{^{$oN{^0v5SfouFUESTF zv~A5&81Fz*EsG##B)_gTHF@G>a!DirJIwFFv@R|2W>wugr16|)mOW|Ro8uf#eIF8z|f1ld8am9MZ2uou4B zv|DO+nHw^w;BvYZhW#;ECh8p_4?Yddag2|uk~R)?PQ6Yh_0ujZ?BqXbGIN+IK9)tF zqX3UQ&8c_d*G{e!j$&?&%&D!~g3xG9-m|{|#wFG$n zea>^&YcuHLcyMg5zYf7vSp;R^!1076b!k}uW24q&FoES#b^j`%Tx`Ci1DICVq zgSpZSit50)CG82$hWKzwsz-Y&t{w1X_PF-;_xNyP5->=a{1NV_*$lzSs3m^m=lK*u+W>t zi|NQqIjCGnPgf9(>Ii}QoxQhwheI=By;(F z=tiF0VhMFCC@jZI*o3wvk!MjaoO&-9CufAqXnPpF0HEb<-+q9;aP6lTvn^(hYXysa z-|nN8b$5K!YLT$Xp@DbMVSS>10v7kbuuauh_Viu{>5v9m*Lj1AqLGj+uBLq4Urp9xy$ll zwfx)S=j;acY=L|U;8%+G`-iZ1u?_)Rxr@{PSm!p13kd1Q#b&N$wDfBi{8#;w!Q1h= zxM2Q<#Wp>+Jn99|&Q`adEXq9Tcv)iO*dwo{>5f8`v{QOwI0HV3S^bFD-gHr#yW7ll ze&SW=V)(Q1=xR>Icf?X`Rn^d#B`54t^-#b}`B$OaIBL=|jSU4*zR;lvrLt5V3yG70 z8(3ODg7r>DhZ3to*#fI*)yV!J-;QTq%)^M&-ZS*bsNsp1g13j&Z#e$6+|>RfRjQ;Z%>!0bA1`Wip4pO_%e))=i*ez99wwh! zK_c3Yu0@ST;Yj5~91zYcvZzXO-yb4v3vRGh@i&51N#aVFII=~%Z2HQZusm&YO#|b~ z2$5Y!SkP!1@1J>j22Cq*NaF~!zhJ6EK9}Ib5#<4i-^JSx+vr5HjGc6t@O4`0%#PEQ z5`M?Fhh4Tc#{^y3A-PS2sI_aeFnI0Xw-US_=lb~g=IKb}ksS9qK_gwrY z*%2(f8VqO9lqaZ)BgR5z)j3))&0H$4Q$C4a_Ehzn#+YQuIb01YUJ zRTK%Zw;oyO2tDf=Zu^lQ(eZgp!>O4>LfVG@$ZK%E!mBNFYrbuVB~Xc2aygs7{c|e< zErnuFlprbRkk6F;8e<@~q1EsHMxPu3HRB9p%dqm9BB z*DNUQ58q$r$!hUQC2-Obq@|fh5Ywr`1bz63pg5f@3(wt}9rENg7n6X`4Bit&x3})O zx;d*;oQc#PxaPWMjL7$F?Y#e;Dz*_f^FCrtLvy!Nw;XlJC2GZM@~aq^M6Pt->SUz} zMnK>O+G*972k>Y4kP}d;2Bh0+#ZY?As{uuGR=wVR0&7LfCpuuFw{7~St@h_Y3en=t zpX=I-exeg6-wplz3=*n3O0AElOTOPSV|O3Xa1?9cKUX!gA3-;pU3xBB<%u zyW-nDhdZNSwZO`_b?C1zr%r5vPaxd@dp&w@6W2ABtf0SDb8u+Q6&WfopQO# zaJ<=YJUQ7VSQ2AY^yi0mlXkgXI>YBt85)1v4j8`feB_!83_E2GL#|}V{r7$ChxQcw z4ajFi?SIuIhZl2sjmCmc`=R}y9E$c{6R=#BX!=s5rswY-y{WV99d+bw zb^JnI$^KHmK~!^Rk%oaq6AuA6;=XsHdJbo0o^6s|0Wmom7~VS3nDDbKsh@xja?m=9J`e?yB^rdjxhv}&V_}GW2E@!dJ$*eYc2Ox z<7H|_6c%<=t3&AN)Ebw)q}LkO^|T5*F=PV78CBPRF<}`RSaSC9UDXlAlnzaJn9?L) zl!jzsL=1W|ZGhfb{{EL0UFAn01$vAqn#l(uL7>P6oMWn-{7@Yy9g=ghn~7pdA0t@} zDd5_PoMfO{$v=!b7Sgs`EbJaGH@}?RlnU>XhO0_}&T*E8bs!GTxT0z!=?6>)#|#T8 z?QDFMCYR!LpWra2Ef$re1C_vjUfR0HR3_u4GRBye2>M>0``phQu_g%@uGg8~Bl3=* zyqlzwG6Kf(6=QGnVO~=(I+%=_4Y(bL?=e}SXt;u|jMF@rzun~~9Zu=QzPE9~iry`s zOd?TH!iW`U^XJ0&9AW53a@V?AgEbT1QcEX%aS2^(U#U&TOzKi&PXsR1w0*{Pb#REQ z$|^JmMlmnhwP$VHa3Hs{sa0k5DHRDdA~)d-hl;nxOL)HjF5*TzR9&Gr+@{ancRM3B z5s^r)W$#m~qO1&^E?XetYs&k~_d{Z!ZHXdlFmB{$ZQ+QV5odyY^e;O<`iAQXFskiY zYX^+Vl|Whd3~}6^Yriw1yQ)X`;io}4j!nrlSf?#yF=cXeucb@d6B@Fq-0g4tp~eVp z{sxDd9|~R~o1FsRRwZGq-+n#mCd=SlQEoMyesH-wJ2b)(nuuqJ;u3lG)83x<6p@cT zO``*$rLkS@zkWjImThFiGc73-pos3wn=-|s(y~x!;dF}CYZJwEzvGvN)AW41NSFYo;?&ejH_xlLr?$BIQ@q)F{EOc^?I59!H)kT;aj)tr>6YcKif5jCg zFDt(8jW9i{LVD!g6jN5Vl4|?yA=`JCstMgtf8|4}&z_i?z*fSl#%a)SXu+|4#6%sR zv$S?h`dPG4TGTiH!72`9 zDNEVlIOd0*(q7?|6HZ=}OFW5nBMh2L)4}U{1l9K~3I{_H8~E(5^S&Q*7I`i8bByd# zT-u2LKs9G?hplc*U8fC$9jwz+7akl~1s54u|A`sIsYE?0@DE{t5YsCJk|L8+Z{BU* zBE+|_qoC4%SUhH{UFa??+0PXM{=7L#vmp>gVHfAT=O3(k_KJG^Q%_Z1pc$}w#;wNP z{boEm!`?lDy)Cj#ERtUI%`F+k+X!)`wkt)$s+ZH1^Gr^8NOZ&84uv;2EK)q$sg3Z&*a0KXuUg>$~Vg3X(;p)Ljz(r5baoZ~HUp&iA zUbfA~AEt|=@R@I~uloh$846Vzovgl|Ene%6d6W_c-HLoMUvwbIrcPbr?=`&C`zx3EP=2-D zAlqxzQoac*(XT~Lqx^CLN#&7u}2nCqED;HF_kKT;9j&QzqN_FcbbL*qXDf zD1qARzqfyn#a=m}F?UyMNahn*Pras_#~RsLJE6dNM)s&(kh*T;*D2EcN~{-vR?L^q`AXeq>Lnn{(r{*d zE+15dtAnF0n1pKeoqvsmAy-Lr8isPUTkU@P1-cX?XRwhRgH=T(T})-|ziJGS0aL7T z%3Cr^L5?vSM<&stub#*f#y1$rEr~UsWOJ)X+}d%~_l#|$YHH;i4;4HwbpzGXm!GS= zNs{t{s)YFCRNv~#S!?4jXWh~EdD%O#&oHBWuj=VYtn#fpX-TU0B+@I zZN%=|3+G*)yNky{)6*ylkznIU%JaQX8XL9P3H6+zH6GS+_*I&}(cuU(tuD2zuYX7T z_k4L7UkJUYgJd&1%5pX|DE4~a5sqZgu3%#)@Q=G^gZ=+Bx5Np7KED9)syz>uoAgsy zGkiW{WceYd8*>U_C9fKA@=k1w!%ouv|0({(BKGh5Q8~!^mAh&z@jHy zsODzPm_Bl-g zk+EZ_OL5LhQH!oojeuinsBw~UifTFdliV|RIqRBK-*=Ki)jy~vuf7n2qN>Sajl0mz z;Ay*7Jfmv%zbU>w;@{$Ou9Nb`Q^>q_5>ebC*<%zm|J)^>WYUs>m zl;81lcf6Vd+X9#{Qp^+z1+I?It?6LwZ8yeg?TFtWUFX}h?B|Hza4mtBgmv=FM?A6U zr^ly&pszBjoT@^$jE5&`3nw1bk6y6ndSdEbd%G6^>+px%Z~xxZHWKpOl+bdI}{ZQI$S zT&yO)JLYi1bZi<#Jxt=ETb$z56-sjp8{~K6h_IF@R^jaQlI&O>F(@-Mnv{;stkHTe zlFVx+MA#Kv8XL}T=k~KBm;Tw$S{JgYHlK!Xg?+9*Ga_wQk?ip?^MLjRKx5t01k)T) zHO=Q`JnaALJQ@3z+gcAp8AqmLgoklyL>0zd9s@-$iS@A3CD<5p)_@F2Pu$k!1$jT1TPNc}CG50v6LJ;OY6J%GWufsoS?8@pu#{V+*`hU6 zxyZkG^Tm}bRair&ioNSsi#s3kvF=ZAfS zZ9p}lm1`X0vAVZ)`gN}i%bAmwg5wW5@}1pd^}z}&Uft*>p< z5A9!14Xx3d51Nl@{S68nk9mFHM_^4-wk=k?wTG$!;I<*aDjA_t5ft{mu$k$T{W#k) z{#1`#Bg$is;cYq*c&7+l$k5Y_} z+3HbwikG^r`QG(3uoj2re!~dv!W1l0&eR-Qc_*jnf-;!{CU8bfEfs0ou1u$M-I*-& zS8ZeiwikBojXQ>qu!%l(w*@=Z$fis6xW+ z^u;ohf7Zjv4y?bw>jU99iRi=WEd>c^aU zZ9ljxpG4Ad-aGScuWE@Lv02=m4=Dx_6-ujYr-*1e{NB!PUFeb-HSPotedw%L(o8MY z#w<>%pd*|S*k6wyA>jL2AGt-tG$E{qzTXiTceQ3Qf?DPk!^JGWQz}Ytti(X1b<8<876U@)$XN18hpRKmH&IOkVQDR=BayfTC?E5sU6J0y&?0ju|91dh# z@WiZ)Md$GgSm@h4txR$G@Xa0W?!2P_Ps;m%_A7nBp*i?nh zf~YhN9S$w=WU;MVq9fvmwzNGi2`7t>9<4v^^UfZ{|1Me`0_&K@A1?FbYq|aMG_Zb% z60CU6`y%VDL-_)jpM9sMTBK7(KtM0&zMUFYuG_;Zh34qOP3?bhe%}Y;|I#TuCE>P+ zIJ>@*ez#vF!yf+vXbT5&VJ-WmxJM{d#Ws}}?_{nNkMTE&zcDB#4V8cEj#VdIU)-i# z6ACWF-^!y+_z}L?wKaUr%A#34*BM9p=%MtTnR)Zi>=uJ;RFQUF9(iYY*@2_29~Z7^ z(8Yt)5cHs1TBSe9JrSn5v8DSjWtN&Uy#IVIscYdNvdB-=eV-#$Wpt)~&@N(lfyS!l z_R)Tj&-bb;(#mcdD|mLW;=0CBInRDr@41AfI(1jER-QN}+V%EP&Lx{^yS`iMAaMx! z9jg>T*S-#3$VyX)UMdhQ)g);zpI~)nX7ix`{)ce=pf>sLr`c<#4>r$KHac`OJTT)= zYg7;FrSnGmwCULv-KF1E%o+j=@VXAfky9CJKeiYex^;VeKp86c)mJJr+W08kmnpwT zb4_X3&f46Vyq$Jd5mvUxqh;f7XPBtpHv#6Uujy3s#MZjZ^vZ1+))BTVT{BU(Z=2ul z%Vx(2rsY2}Et&|5`j|)~rVOsGFP+m}45wuQ^K#jNHJQX-04-Hp!+m!pM2A00D=G~` zp;G@kkAUUDiV!T`maxut$Ou;G8OFA6sl*}n{QME;EH{qc!jLe;spMY3K5htdj2Guu z=9ss^rXs8bhidOj3BIZHmNL`y$9{j3w{>mlVoe?Q<;0}<6zLS69F>&k_EGc&kRCAb zJR#@!0?>X|eoT3eBqYdxtbdJlQ{lZvt&tJ`3v&M-AV>mm@!lcgy9OoxFRG1%fFOZz zbB(7wya^gnwXl8f)fnT+I=9+v%WAV|0M-0sMy>Sqe@pU&eF5YiPtc#j${bnlLSarH{p%-Ipq)%BW-+oY;x}5Pawp=MCV)Nd3GF$B{nO{O z@{Hr2?H!qHo~~o}`d7YYI7e`b993OTf0Gnt%?$ zEpzTIjU7*dYfvVI0Jzst#^2l-F|`aSDcOUEqwgY`ryHg_(2*%RA){#1-J^&3FyH;7obZ>JUn!M2yh`>_Om%j=(3Jaw^@H4l^ zqe0KQ6`tsl4KPT!!DQn{Mfk{eTwBKZY>{#V?cl`P-e zCVKH5`35W5<~ylE=dckY>l+~`NFCWac>}Lmw*{4q_ET##$!J2+m;T}==_TJ< zG{~rC``FSROiE>Px2Q?#voOLYeWqcwO)qr>TcM*3)|<194U*20gJwtE5q%R?tIG7@ z%4@~Lr`c12od`Xigh?2uY);WCZ6)D+(3Kdz<AXgWQkXG3)jtOUN$@#R2Da$ET%>mM;?$MOUd!fMcGYbwlBou@&T7 zvWpEmgVV_5!7XER*CV$fiv#$0sWS&Cy07WJ>zLh42Td?XI^QjV$F6mm79knBAFhJs|9HN5H_YLM(% zG(^9b`9AsGp9(t13pFDH(GJ@M$n@gb8CGCx*NGHym{=tAz3->%PybHG#N@XRPrCfV zBNo!<(H9ln)~?FL+H#)_o(MbSm}-+k?ge`5gkc88f|Z_C7Up3Y>M#g%-JI=PoN~H+ zj@)v}LML86Jio0;m;u9i*D9WWQD7N6q?RC}a}a3!XD{H2^4b`n`5w;In6Ozd(=zsW z8{f6sS?3HW|FStqFCIy4SB+^M9YIU77(CUhBx>D_S5}#o{KcA-TqVaBg&#I+gy&z6 zWH`r2nVTYDOWb1S(6W?r)G#B8i5b4N)ik{BT=wHwFKey+{!Ea}nQ+fg+7^t)g=~>e z73Uvx&L%`nUlR96V}w!EaQ3@@ldr4W+-^ILNBi?K~ zB#HTazS3~Giwx8%#_*UTKlzPHU|hNQA~GdPX^QEY39yLn$G0=bLsfr}u4s7UI+&qH zr)lW^1l?xPyUK|E(GOfQE*7QNVn)VcF3ZENBlOtcJPGBtRdU> zOpKj!fgP;9A{>Kxmi)42K!dD6%M-^ucoE%&;z7upjT*9p7MyQ-=?Q~AKUxfo51QBN zmlSd)65m{$mt~~nwh1^zuHxfLfG&ia9QW#w_v8)(vXLYXLe@hjeo_p(AfY+3$9&K60zk$j_xl*Qa@b;F@>2tlBAG=3>ao|%uWT38 z|7o+G(L+ElP|><;ISKVPQVDZ~CT=>Aisjc^XC*$H9OuOhZ#&J1oCeJkero+I*~UtH z_GqEX@u8DE9w{CHco0A6bYOVa{n|}}{9wbJy9GE2Rkp>*jKYQJosOf6(nYtN2T@Ku zT6^IwwbJxlN5SEW&UGE%UM zNp?e1?_&sd4!ZTlD0p%v(RUdtFH;H0vF|m4pZq!81hS^+wOp=OraVDW+O~SsEBcCe&TkqauPjkgT_2+ShYcbL3iGSan}5d0Rm(Nz z$>>Bi+^zpMwP6w+TzfuelCAJlqfO5ww%g~PwKc9Oa`DuyDdI#qXg$XC82w={=#l7# z=UqIQIyo*`MCIIbnr!}F`o2ry{ni(%2-pkQ(r{S>=fp{_X?%A6#r?t2E-`xbwd> zCuYS78~f_k9B*Bu`g6ROBwcqMUbW2wvXlZM7;fn5_EM~rVY{NUe=(r$gk{{Mi?;}Q zXFZ=i95YTE>8bTM|5I-{-Z zK`0{So-^8;ikdo6%H{eCv8zIb61EUhr7Wwv#2>!Of=3+qu2ix9qRT00IBo4dy(I z6`R~i4?(-te?ny|PRjGbR!PY0dm!Sd+RFg{+V>m0l;c9@B2`0iWRabCs9kLE}X!rkv|xPu{S|&Hn{?K!(2&(=pDt)i_H1OqDfrs+lY@ zhr-r|P@Uo877Ef{+3^i)=;7Cr!(SXU?s2O7TUYcC-4g*ChW4F1MJe8lFv8)zTkq%L z+>WQ#u^k9uvd@;3%+Oz!hv_0-OMFmb;NU6GW3j|)~fkAkJ>_G5D4rpE{xmRYbBp&70 z)kc=RxwOx$}VfG!Sr)2u8EAQ-Kr@2sQ$JE-vn~f9Wc5O7+4PY*D$OS0p9N(_ols=H0 zMv9!az}p;HPb>cbrp_7~0Oyxf=e8EI92vXU^j-W$+gmFnW)%aM0vu_+KB{kuj??{^ zS{~tcHlC|nX0x%jne%-x3(A4jbE|s2b}q&$Rb0#meu%?qy@wF#3cWbCa5|EmD;rib zGNfgt+Lw_~E>xQJ{goM)RTbxA_FtlNrIzDICW^V<3OOQkog9^=;X{Jf%vt`)@Y9#*0O&ceb#zb*Gvwwb|pe?_O>0OUi7e+tHT>^v^|_ z(%aYMIP_R%gmCVgyToQujGBYjN1VSmVBg<}cB{j)N6!~6X}sxj9mARNPowp?_WG;M z4gUaBYM&T%W;>u@(a~JK7~IJvMBU9(MiH^~pzl3aHdzn*-@^XQFz}oBRE4gg$Q(+J z{4AP$L*%)GIa37_Wnc!`2#v9$0cKQPV_Vxjh4O_7CWd+hW@VnRjm`_hSROKF}I9hVMXNkTUhtG z>jE%`MYRb4FFR%7|mi~CGM_WQ=DxPL>upBscG_+UGRUxrH;ibq>0etTshTA z=j@Tx!J)lXna0nof!}7s$wKJt;wZ%`2Q?#^9a!T~YK!ERw}-Nt1~oK6jTko#w_(d* zqr>i41(;o+yGsHTF4dCO_J~+4v|*-ZMFYJYclD<__wu6jEU3!41jo2OC+5;{MXh^- zPGB6><{A-^8&+ET>eEiYqQ49dEbEf?BmV$#IJVaWSA`BM()mgT)2IIcs~;+}SVm22R2oC z8dn;IOLbZzw^?5MERVj|4rYS|ZFClK1Wg*YfzG-$hg3P;y^4%=Ylq~m4e2AkswiCQ z#~);9x+ah}rB`}{a%sGHl^Z`Ty1QQ$Z6 zGG;b1F0c`Cz3M|-+s7USl+*jh{Z#$*Kay-sv`E%8PzIVU>7+mED;!o@a3pACtfl4} zilW&hy2I?V1YXG=*PO^IBmNxUsr}K8*==)VX!KXIDk~PTuaLU??wt%0Nb9Y{xyK+B zE?}b!xGPZ0db=|ok^a14w}Ph#hX6t9jFu`j+}LvYBG-b~48h{Y=-XCC_LrWD(SR{TxSnNgsvd&;<}|tdueB-fl`x_P1uy_XpR3imumq*$pRn)>KA zd;-5V^`YIOuwOnXwFd7pm;2hS6A4=+vVz7nnJ|C(#f)1l&eq47Z?v5~me5dlt3HlIi5-3(mIcI=MJaTr2CsjIWj+zCN}F^)vN5}Ylm@7j@l^fgXy1+ z*)B8#GK_W~oP>Q5bFVm_WgAVPQSKCLdIdqEoL9#F%Z1XP8?#}jt?J^S0~a{*Qa~Sk zHkj?Sd*be#G-Iclq=O!*t-X5arB(w+JteXO6hV4tK2H=iaWlr1SZN;bJ~N%~v^&(M zwrh9T>RqNB7Bo19KDUQl6!Lq|CvG=%HCScpy~wfMp_djH^<_OqNv$Nd%@=6(?orDX zny^bTA&)=vqKnE_h6rQT-g`QpNRTKimfxMrGZ@D(hU1ESZI!bD?YEwW%Oo#sZpe_D zT*m<6cwv}M5ef$8U4T#Xrwg>ew4mEOrNO^w<*bS1(MCr~dbjGX%5J-=uMP+E4kL*a zQsT@>9aCRnacq~%T^ZOmXkG)vm);LGjQJg5SKJbfU%@-jWjcxJzO%=BUX5sGg^jwMGEP3oG}7W6zEQ+0%j_bTg0 z$#%)`YA%Ynbs8|!fK|a})yW&dVTfCZeolB=kS zPriVT3p**%sj_*+o-5+5Z81f!v`E)9(15q?6FbG_VoB3|@UmB&!DFOw z-QM<&BvZz~_~VdX#}#OB_w=&aY%kR@r&KGS@QdWF=VE{Yq~MEQC_>dh%kRxD;^FGUXg*zb=OaN!x7w#d2s2~KIzIg?z?hOK?xd+1cG5uPiw@qbp?Xg9J zb2U#AIzfEiaLT7=1-$nYmM3bFHmR?+&8~m=Oh!8!8)uKZH3P3+H*qJfo!r(dHI6Hq z!FFn~VObp*u6i=ZP8u*G*6nY4&?D8tr9VDy=yK}kHn#@wPW1H z{i*)|(ifw&i@y_bLCo~c_y#JEX=(2i;of%Z71){we>0}@v3DS^KQ5biak10$&_P-4 z*~h|G8XMxFB>M;Iv)iBqp5z~BC4}VP-9F$CnYdwz{8b@rarfp|rL;&#aiaT2{{T@~ zIo0u3qn=iuytm6G9~)KMZJT$yd22kGD?#a6kKtUMg@^JxVXOqW^jgbV$J`&P0l$FQ z?)6%)6g2oN!+_TE4AS2apr^WiyJ7UZXRa>m;I1%L{@~2`lv?N9jQb43f+T_EuN=bE zc|nb9orXP=`z>XPvPbT7AG*h4r3k~Txzd_gop930ths#Tc0&j%f(mYf+dmpaQ zp3(?|koW%ph339a4HtKBjE926;a|oFYu%^4s-q`kv`<9moZM@rz9B)4cMsQRf9xaeclR$cvKmtdmh$*^G2yq)05Lmt z)#RIKvf~4@8QuO9Uu(-fU+#ctpd5yu9xZraa0f?VsqGB5glz3ehs$BUDhmGqhx+U? zD8*d!K!kRGwtfKhJjx`Rlj<6)R$jn4fT_!1aPnC3E7em-I~XAE#U6(pf?Q|uMcNn+1c87-aQ7(d_sfnpRT}d;@8eH@%}X9qdghyr2WVvxME1JQ&J4?2)c|_i=R_lcqBC%;%E#pK1AyT5cK^cYcxF7T{K@RYCi~8j_MD~f+w|?20OCR&%Iq^3mwV#ihCUdhUuk4O$won z;QiIFv{DcMs;RM>&t#NS zDarNxv^DJQG}Qv?+>trG4#kW8KSQCPcq>2Mch^mq{J^a8j?OLNUG@iPpw@~3fb}YI zG2wS1qa2F5z_*S7P!9brjMEH4@l7V%nB_!2@2QVEFYUDcl@w0$nYa$?Tu0=;w^RC5 zMk`2`uEcaum?Ue!X|3HYdwWea3D020=#{(>$i?Rr*xBBGa901`bUn7j7ThX9_4?47C&6gn}{ zQKYIYG-9yYd(ozCRp_tJAZto3Wm{&5R1ReIQWwoh4Sl|Q7c(t1qHWVy-_`@AV7cf~O$6_UdpQRFFn5M#j{hsI`p+fq)jT zK?rZ&HCN|(d%M=@Bg16G?4=a>r`;Rz?~WO=Ozc`WE6j9S*oXbQ&L0WsvLj|$xbz9J z#wgLVp3PmK03I0AK(RDDmuOyInns1_m|T7=77@m`;cv*T_PwX^UX7oMz@MVuc|SF2 ze|Tz}!M{!eBxh-+p+_@&FBMY7%C#OGCcZZoy{4dqW3&N(+h{+UqpIkSW%~wajp;J* z*vVzHS8#tmF_HKLOl0cD1BD~GI#1DBkH$v@)@L2&Z#Th1XlVEy`f$XMys_h$UTtb< z61Y&b9q#nuf_c5gNdEwN#PDK~ z-JFljO&)ifhZj`&3#0GEq2}f>ARVS=JVGGR&T*-8cJK`?5{_OnLt@u1wP3x|wT5uvKwB6J4M(<)x;l+ni z;=&C}heffJJo{Uxt0I}fXvsQL^C9(GUtMXz7CaA@iy`xtHFS&2N7X0d~EvlXk z!BCNChBxx|mhG4G3kx~^wD|P{dkkGv9MeKE1%GsZ(z1v8RvioYxU>)z z+s?bvtI>=(l-h5X8epq5ly^kSue= zokZB#*=_@Z185UVyIgZkioDg_nzyiTx-@I3ZVWFX7|{Dey_)?|*2qIW#^5-N2R9I~ zar{@?N&QO+o}r`njREh&Lt%{2J<9X3cObXjM*E>}5`0zH@3B?8vVLn*CO11Ls8LJ@ z!gvSD7P<&x#kK3zTO@W23<0e?hJzvO#y>Syj22&-#fL>s0bu1?g_5ZX^N}Z)FHpQQ z&_r9$M7Y%GYkHa?1%ZW*rO}6F5=}|s1ruAA#1;Plm}oCPz)}&A-5UYTBoWLlU8I2i zPU@tKsKdu=1sqOe*wS~2ZzODxS=#nSF6V_*ph2oE829LDJ*V$4x4Yc1w3S_Oc8U|a z5j>lMyn#8aRVuMQqWe4o?J#q;8tDaEoM_-V1I3M_n}Uk%Uw9RaZu}N3ci_7vK}>3E z`7DZXY4oPMY$Wfubf?p@{o%67Sxd|{6-KZ{URab##FP%P!f6{xDhiGtCb+sYnJ6{6 z3U-DiQz7h!V??F!tNc}Z8^YnHTjqWW-Tlih0FX(`6-DYaE!Qj$~1 zVd9B6le8?BgT6k^$DeZF+>~}+70H{2vf-1xPY1j4Uuf^eeWR9O{FW_gLNgFOC7u&2Q{MPI1rNrc_=PYWw zR4Som#5YYOlXP&a1cZD%iUQH-WbesQ!Ll)W30}j|*rVw0j;u9Rd@?k5x70UUN(OU} zMMev)MkpQV#$b(*3V-Gfw%ArQ&TJ z^?&+#ju>mJG(*smzxV<%#Bm8W0=gafo+Id3x^o3Nh2F1|9}?<5iDTaWIh$Wz24AU^ zBNkTv@97i~npkgEa^@~oNCLP0{ic$ytJ9v3q3Ysa{{RWEL5J`#{xIrcH6zAV0B;vX z(OK5z*{M0$&x`h(6rh!t7xM*Ucv}QRBo40zOZ)u7D4QEqM~HLgVf#a;x9YFbRziiw zrZp(F2ft2w8;<=<#JDX86dtgk7PttD3|WKTj|c5w{t`VJG{@39R7{?_>F?5@bgw3< zSCYC0BXTA^bm%c9TX2eS-+STWJIv>CK5-hh%MJ8BIrKd;NbjJ>KB1<}BzV#Uw7;}r zE!*X9qx>S?dWo;&N(CJ2%($ygj@5v^4GHxi$lN#isv(3HwJvHUF0H9jv56IST(mY^ zUGT@>=@MGJO?mFkdCJtzF{ynRcvj4VRziedK#1l40I(5j@pIerKC8^Ms?*EcFf!`dBZOz&{AMz5p<&0&xxHfObK}}5(VD*t>r$?yV`Z%W0Dfl4 zXz+MU{7cNZ{V$!%T1-YuqszRY03n9)&MGm0DI77(D|MeMDT+Y@R)5q+5nEjyp|)OD zJu>T8JKe|HaS6;Jhy$>x_Q@_qW$kfqx869RGkG`pmWAC+mPT$ZFHX>f3rrfi^Yb1U zL$_N!^#>g>(QhLX_7iIm_lvft63*mN8U6|;!&a8e)JI#=*0=6w$x0ohuGDC-Anq&U}W0;r#cT94)Pn4xX{9&E` z=4;c4EOx1gtztW@66)*B-@LfP!^O-k#COr+66d!o@eYNaEppGlQLzDstv4J#*XpY| z?U>94`{xb&$_(7mPZtn%8dy{}M!j`qca8H;`R^ZF4mwLdXZxoxTyPPym%#JWkW);&I`8dK`4-aWs?_ z#HPuZG0BK%m9|wg!7rn7*TaJY
  • K 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 gSY=)Lo4x-4nd{7T4SyDK82 { + return ( + + + + + GitHub + My experiments (aka projects) + + + ) +} From 6911b6d60bb03c28f26e48c8f1393ded3d2fd83d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 14 Apr 2024 15:15:54 +0000 Subject: [PATCH 02/15] feat(home/grid): create github stats --- .../_components/grid/cards/github-stats.tsx | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/app/_components/grid/cards/github-stats.tsx diff --git a/src/app/_components/grid/cards/github-stats.tsx b/src/app/_components/grid/cards/github-stats.tsx new file mode 100644 index 00000000..33062af0 --- /dev/null +++ b/src/app/_components/grid/cards/github-stats.tsx @@ -0,0 +1,62 @@ +import { getGithubRepositories, getGithubUserData } from '~/lib/github' + +export const GithubStats = async () => { + const { followers, public_repos } = await getGithubUserData() + const repositories = await getGithubRepositories() + const stars = repositories.reduce( + (acc, repo) => acc + repo.stargazers_count, + 0 + ) + return ( + + ) +} + +const GitHubStatsData = ({ + label, + value +}: { + label: React.ReactNode + value: number +}) => { + return ( +
    + + {label}: + + {value} +
    + ) +} + +const BackgroundPattern = () => { + let seed = 1 + function seededRandom() { + const x = Math.sin(seed++) * 10000 + return x - Math.floor(x) + } + const colours = ['#39d353', '#0e4429', '#0e4429', '#006d32', '#161b22'] + const days = new Array(62) + .fill(null) + .map(_ => colours[Math.floor(seededRandom() * colours.length)]) + return ( +
    + {days.map((c, i) => ( +
    + ))} +
    + ) +} From 2cb806a56e63d23089df6d1dc426949700aba6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 14 Apr 2024 15:16:46 +0000 Subject: [PATCH 03/15] feat(home/grid): create "latest post" card --- .../_components/grid/cards/latest-post.tsx | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/app/_components/grid/cards/latest-post.tsx diff --git a/src/app/_components/grid/cards/latest-post.tsx b/src/app/_components/grid/cards/latest-post.tsx new file mode 100644 index 00000000..6de529d0 --- /dev/null +++ b/src/app/_components/grid/cards/latest-post.tsx @@ -0,0 +1,37 @@ +import { posts } from '#content' +import Link from 'next/link' +import { Date } from '~/components/date' +import { getSortedPosts } from '~/lib/get-sorted-posts' + +export function LatestPost() { + const { title } = { + title: 'My latest post dsdsadsadasdsadsa' + } + + const latestPost = getSortedPosts(posts)[0] + + const Divider = () => ( + + ) + + return ( + + Latest post + + + + + {latestPost.title} + + + + + + + + + ) +} From d83f670d62deb59dc797b38a1e757e4967b58371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 14 Apr 2024 15:17:17 +0000 Subject: [PATCH 04/15] feat(home/grid): create letterboxed link card --- .../grid/cards/letterboxed-link.tsx | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/app/_components/grid/cards/letterboxed-link.tsx diff --git a/src/app/_components/grid/cards/letterboxed-link.tsx b/src/app/_components/grid/cards/letterboxed-link.tsx new file mode 100644 index 00000000..17d44d9c --- /dev/null +++ b/src/app/_components/grid/cards/letterboxed-link.tsx @@ -0,0 +1,45 @@ +import { ArrowUpRight } from '@phosphor-icons/react/dist/ssr' + +export function LetterboxedLink() { + return ( + + + + + +
    + Letter + boxed +
    + +
    + Letter + boxed +
    + +
    + Letter + boxed +
    + +
    + Letter + boxed +
    + +
    + Letter + boxed +
    + +
    + Letter + boxed +
    +
    + ) +} From 04474b07b2213705fc026a30cc92eb3ab406d1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 14 Apr 2024 15:17:41 +0000 Subject: [PATCH 05/15] feat(home/grid): create links card --- src/app/_components/grid/cards/links.tsx | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/app/_components/grid/cards/links.tsx diff --git a/src/app/_components/grid/cards/links.tsx b/src/app/_components/grid/cards/links.tsx new file mode 100644 index 00000000..c360a000 --- /dev/null +++ b/src/app/_components/grid/cards/links.tsx @@ -0,0 +1,26 @@ +import { LinkedinLogo, XLogo } from '@phosphor-icons/react/dist/ssr' + +export const LinksCard = () => { + return ( + + ) +} From b20cc06c2aad8b6cf69df3f0aff2ab28f385ec4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 14 Apr 2024 15:18:17 +0000 Subject: [PATCH 06/15] feat(home/grid): create initial stacks card --- .../_components/grid/cards/stacks-card.tsx | 113 ++++++++++++++++++ tailwind.config.ts | 12 +- 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/app/_components/grid/cards/stacks-card.tsx diff --git a/src/app/_components/grid/cards/stacks-card.tsx b/src/app/_components/grid/cards/stacks-card.tsx new file mode 100644 index 00000000..af0efbf5 --- /dev/null +++ b/src/app/_components/grid/cards/stacks-card.tsx @@ -0,0 +1,113 @@ +import React from 'react' + +type MarqueeProps = { + children: React.ReactNode + direction?: 'left' | 'up' + pauseOnHover?: boolean + reverse?: boolean + fade?: boolean + className?: string +} + +const range = (start: number, end: number): number[] => + Array.from({ length: end - start }, (_, k) => k + start) + +const Marquee = (props: MarqueeProps) => { + const { + children, + direction = 'left', + pauseOnHover = false, + reverse = false, + fade = false, + className + } = props + + const ifToRightOrToBottom = (direction: string) => { + if (direction === 'left') { + return 'to right' + } else { + return 'to bottom' + } + } + + return ( +
    + {range(0, 2).map(i => ( +
    + {children} +
    + ))} +
    + ) +} + +const Example = ({ label = 'EX' }: { label?: string }) => ( +
    + {label} +
    +) + +export const StacksCard = () => { + return ( +
    + {/*

    + fun things +

    */} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + ) +} diff --git a/tailwind.config.ts b/tailwind.config.ts index 66d582e5..9af4ba46 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -39,7 +39,9 @@ const config: Config = { shine: 'shine 4s linear 0s forwards', 'custom-fade-down': 'custom-fade-down 200ms linear', 'slide-left': 'slide-left 70ms linear', - 'slide-right': 'slide-right 70ms linear' + 'slide-right': 'slide-right 70ms linear', + 'marquee-left': 'marquee-left var(--duration, 30s) linear infinite', + 'marquee-up': 'marquee-up var(--duration, 30s) linear infinite' }, keyframes: { typing: { @@ -109,6 +111,14 @@ const config: Config = { transform: 'translate(0, var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))' } + }, + 'marquee-left': { + from: { transform: 'translateX(0)' }, + to: { transform: 'translateX(calc(-100% - var(--gap)))' } + }, + 'marquee-up': { + from: { transform: 'translateY(0)' }, + to: { transform: 'translateY(calc(-100% - var(--gap)))' } } } }, From 19f4a3195a7d8095d2fa53f56404f6e39142c6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 14 Apr 2024 15:19:39 +0000 Subject: [PATCH 07/15] feat(home): create initial grid --- src/app/_components/grid/index.tsx | 55 ++++++++++++++++++++++++++++++ src/app/page.tsx | 6 ++-- 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 src/app/_components/grid/index.tsx diff --git a/src/app/_components/grid/index.tsx b/src/app/_components/grid/index.tsx new file mode 100644 index 00000000..11233e5b --- /dev/null +++ b/src/app/_components/grid/index.tsx @@ -0,0 +1,55 @@ +import { GithubLink } from './cards/github-link' +import { GithubStats } from './cards/github-stats' +import { LatestPost } from './cards/latest-post' +import { LetterboxedLink } from './cards/letterboxed-link' +import { LinksCard } from './cards/links' +import { StacksCard } from './cards/stacks-card' + +const Example = ({ label = 'Example' }: { label?: string }) => ( +
    + {label} +
    +) + +export function Grid() { + return ( +
    +
    +
    + +
    +
    + +
    + +
    + +
    +
    +
    +
    + +
    +
    + + +
    +
    + +
    + +
    +
    + +
    +
    + + + +
    + +
    +
    +
    + ) +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 6062bf8c..9a736c48 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,13 +1,15 @@ +import { Grid } from './_components/grid' import { MainTitle } from './_components/main-title' import { StartButton } from './_components/start-button' export default function Page() { return ( -
    -
    +
    +
    +
    ) } From 5737f820e6d98594cb739a17899bf02d23fe6fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Fri, 19 Apr 2024 23:29:25 -0300 Subject: [PATCH 08/15] chore(deps): installl and setup tailwindcss-animate --- package.json | 1 + pnpm-lock.yaml | 11 +++++++++++ tailwind.config.ts | 1 + 3 files changed, 13 insertions(+) diff --git a/package.json b/package.json index 963e2e1a..fd5bd740 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "simple-git": "^3.18.0", "tailwind-scrollbar": "^3.1.0", "tailwindcss": "^3.3.3", + "tailwindcss-animate": "^1.0.7", "tsx": "^4.0.0", "typescript": "5.3.3", "velite": "0.1.0-beta.13", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32b01cbb..e02615e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -199,6 +199,9 @@ devDependencies: tailwindcss: specifier: ^3.3.3 version: 3.4.3 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.3) tsx: specifier: ^4.0.0 version: 4.7.2 @@ -7423,6 +7426,14 @@ packages: tailwindcss: 3.4.3 dev: true + /tailwindcss-animate@1.0.7(tailwindcss@3.4.3): + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + tailwindcss: 3.4.3 + dev: true + /tailwindcss-animated@1.0.1(tailwindcss@3.4.3): resolution: {integrity: sha512-u5wusj89ZwP8I+s8WZlaAd7aZTWBN/XEG6QgMKpkIKmAf3xP1A6WYf7oYIKmGaB10UAQaSqWopi/i1ozzZEs8Q==} peerDependencies: diff --git a/tailwind.config.ts b/tailwind.config.ts index 9af4ba46..dbde3a01 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -137,6 +137,7 @@ const config: Config = { }, plugins: [ require('tailwindcss-animated'), + require('tailwindcss-animate'), require('@tailwindcss/forms')({ strategy: 'class' }), require('tailwind-scrollbar')({ nocompatible: true, From 1aaeebb9bdb4d4f715aecd866fecd87d955ccac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Fri, 19 Apr 2024 23:53:36 -0300 Subject: [PATCH 09/15] chore(feat/grid): create github status --- .../_components/grid/cards/discord-status.tsx | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/app/_components/grid/cards/discord-status.tsx diff --git a/src/app/_components/grid/cards/discord-status.tsx b/src/app/_components/grid/cards/discord-status.tsx new file mode 100644 index 00000000..c6d7d303 --- /dev/null +++ b/src/app/_components/grid/cards/discord-status.tsx @@ -0,0 +1,67 @@ +import { DiscordLogo } from '@phosphor-icons/react/dist/ssr' + +enum status { + online, + idle, + dnd + // offline, +} + +export type LanyardResponse = { + data: { + discord_user: { + id: string + username: string + discriminator: string + avatar: string + } + discord_status: status + active_on_discord_web: boolean + active_on_discord_desktop: boolean + active_on_discord_mobile: boolean + listening_to_spotify: boolean + activities: { + id: string + name: string + type: number + state: string + timestamps: { + end: number + } + emoji: { + name: string + } + created_at: number + }[] + success: boolean + } +} + +export async function DiscordStatus() { + const { data }: LanyardResponse = await fetch( + 'https://api.lanyard.rest/v1/users/274521154230812672', + { + headers: { + 'Content-Type': 'application/json', + 'cache-control': 'public, s-maxage=60, stale-while-revalidate=30' + } + } + ).then(data => data.json()) + + return ( +
    +
    + {/* */} + + +

    + {data.discord_status} +

    (@mateusfg7)

    +

    +
    +
    + ) +} From f5ee52a66d75d4f054c31fdd6492544e742763b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Wed, 1 May 2024 10:59:10 -0300 Subject: [PATCH 10/15] feat(home/grid): update links card --- src/app/_components/grid/cards/links.tsx | 35 +++++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/app/_components/grid/cards/links.tsx b/src/app/_components/grid/cards/links.tsx index c360a000..bcb63266 100644 --- a/src/app/_components/grid/cards/links.tsx +++ b/src/app/_components/grid/cards/links.tsx @@ -1,26 +1,47 @@ -import { LinkedinLogo, XLogo } from '@phosphor-icons/react/dist/ssr' +import { + LinkedinLogo, + XLogo, + RedditLogo, + CodepenLogo +} from '@phosphor-icons/react/dist/ssr' export const LinksCard = () => { return ( -
    + ) } From 673fda8ed8003091be4e43ac52450dba3753ce7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Wed, 1 May 2024 13:33:09 -0300 Subject: [PATCH 11/15] chore(next): add "i.scdn.co" as image domain on next config --- next.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/next.config.js b/next.config.js index b664b576..4f61bac4 100644 --- a/next.config.js +++ b/next.config.js @@ -9,7 +9,8 @@ const nextConfig = { 'i.imgur.com', 'mateusf.com', 'lastfm.freetls.fastly.net', - 'contribution.catsjuice.com' + 'contribution.catsjuice.com', + 'i.scdn.co' ] }, async rewrites() { From 455a49d30142cf11e7acfde1adb94304fbe5d984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Wed, 1 May 2024 13:34:14 -0300 Subject: [PATCH 12/15] feat(lib): create `getAlbumCover` function for get music cover from Spotify database --- src/lib/get-album-cover.ts | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/lib/get-album-cover.ts diff --git a/src/lib/get-album-cover.ts b/src/lib/get-album-cover.ts new file mode 100644 index 00000000..34fa7a43 --- /dev/null +++ b/src/lib/get-album-cover.ts @@ -0,0 +1,48 @@ +// this is a workaround to get track cover from spotify if lastfm fails to get the image + +const ENDPOINT = 'https://api.spotify.com/v1/search?q=' + +const CLIENT_ID = process.env.SPOTIFY_CLIENT_ID as string +const CLIENT_SECRET = process.env.SPOTIFY_CLIENT_SECRET as string +const REFRESH_TOKEN = process.env.SPOTIFY_REFRESH_TOKEN as string + +const BASIC = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64') + +const TOKEN_ENDPOINT = 'https://accounts.spotify.com/api/token' + +const getAccessToken = async () => { + const response = await fetch(TOKEN_ENDPOINT, { + method: 'POST', + headers: { + Authorization: `Basic ${BASIC}`, + 'Content-Type': 'application/x-www-form-urlencoded' + }, + body: new URLSearchParams({ + grant_type: 'refresh_token', + refresh_token: REFRESH_TOKEN + }) + }) + return await response.json() +} + +export const getAlbumCover = async (track: string) => { + const { access_token } = await getAccessToken() + const URL = ENDPOINT + encodeURI(track) + '&type=track&market=IN&limit=1' + const res = await fetch(URL, { + headers: { + Authorization: `Bearer ${access_token}` + } + }).then(async res => { + return res.json() + }) + + const { name, album, external_urls, preview_url } = await res.tracks.items[0] + + return { + name, + releaseDate: album.release_date, + coverArt: album.images[1], + external_urls, + preview_url + } +} From 94266ba71782b78ebbf73e405cf2f2e099e84730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Wed, 1 May 2024 13:35:02 -0300 Subject: [PATCH 13/15] fix(about/statistics): show album cover on top track card --- .../_components/spotify-dashboard/cards/top-track.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/app/about/statistics/_components/spotify-dashboard/cards/top-track.tsx b/src/app/about/statistics/_components/spotify-dashboard/cards/top-track.tsx index 081b5c27..882de352 100644 --- a/src/app/about/statistics/_components/spotify-dashboard/cards/top-track.tsx +++ b/src/app/about/statistics/_components/spotify-dashboard/cards/top-track.tsx @@ -3,13 +3,14 @@ import { MusicNotes } from '@phosphor-icons/react/dist/ssr' import { placeholder } from '~/lib/placeholder' import { getLastFmTopTracks } from '~/lib/lastFm' +import { getAlbumCover } from '~/lib/get-album-cover' export async function TopTrack() { const track = await getLastFmTopTracks('1month').then(tracks => tracks[0]) - const imageUrl = track.image.find(image => image.size === 'extralarge')?.[ - '#text' - ] + const imageUrl = await getAlbumCover( + `${track.name} - ${track.artist.name}` + ).then(data => data.coverArt.url) return (
    From c9a5d8176015c3fe822879dfa0b3f3b83d196c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 5 May 2024 14:45:31 -0300 Subject: [PATCH 14/15] feat(home): add grid links and statistics --- .env.example | 6 +- .../_components/grid/cards/discord-status.tsx | 2 +- .../_components/grid/cards/github-link.tsx | 2 +- .../_components/grid/cards/github-stats.tsx | 2 +- src/app/_components/grid/cards/icons/bash.tsx | 17 + .../grid/cards/icons/cloudflare.tsx | 20 + src/app/_components/grid/cards/icons/css.tsx | 32 + .../_components/grid/cards/icons/docker.tsx | 12 + src/app/_components/grid/cards/icons/expo.tsx | 16 + .../_components/grid/cards/icons/figma.tsx | 28 + .../grid/cards/icons/google-cloud.tsx | 24 + .../_components/grid/cards/icons/heroku.tsx | 12 + src/app/_components/grid/cards/icons/html.tsx | 21 + .../_components/grid/cards/icons/linux.tsx | 3092 +++++++++++++++++ src/app/_components/grid/cards/icons/nest.tsx | 12 + src/app/_components/grid/cards/icons/next.tsx | 40 + src/app/_components/grid/cards/icons/node.tsx | 73 + .../_components/grid/cards/icons/prisma.tsx | 12 + .../_components/grid/cards/icons/python.tsx | 58 + .../_components/grid/cards/icons/react.tsx | 12 + src/app/_components/grid/cards/icons/rust.tsx | 15 + .../_components/grid/cards/icons/svelte.tsx | 26 + .../grid/cards/icons/tailwindcss.tsx | 12 + .../grid/cards/icons/typescript.tsx | 14 + .../_components/grid/cards/icons/vercel.tsx | 12 + .../grid/cards/letterboxed-link.tsx | 8 +- .../grid/cards/most-listened-music.tsx | 51 + .../_components/grid/cards/stack-icons.tsx | 63 + .../_components/grid/cards/stacks-card.tsx | 80 +- src/app/_components/grid/index.tsx | 26 +- .../spotify-dashboard/cards/top-track.tsx | 2 +- src/lib/get-album-cover.ts | 28 +- 32 files changed, 3753 insertions(+), 77 deletions(-) create mode 100644 src/app/_components/grid/cards/icons/bash.tsx create mode 100644 src/app/_components/grid/cards/icons/cloudflare.tsx create mode 100644 src/app/_components/grid/cards/icons/css.tsx create mode 100644 src/app/_components/grid/cards/icons/docker.tsx create mode 100644 src/app/_components/grid/cards/icons/expo.tsx create mode 100644 src/app/_components/grid/cards/icons/figma.tsx create mode 100644 src/app/_components/grid/cards/icons/google-cloud.tsx create mode 100644 src/app/_components/grid/cards/icons/heroku.tsx create mode 100644 src/app/_components/grid/cards/icons/html.tsx create mode 100644 src/app/_components/grid/cards/icons/linux.tsx create mode 100644 src/app/_components/grid/cards/icons/nest.tsx create mode 100644 src/app/_components/grid/cards/icons/next.tsx create mode 100644 src/app/_components/grid/cards/icons/node.tsx create mode 100644 src/app/_components/grid/cards/icons/prisma.tsx create mode 100644 src/app/_components/grid/cards/icons/python.tsx create mode 100644 src/app/_components/grid/cards/icons/react.tsx create mode 100644 src/app/_components/grid/cards/icons/rust.tsx create mode 100644 src/app/_components/grid/cards/icons/svelte.tsx create mode 100644 src/app/_components/grid/cards/icons/tailwindcss.tsx create mode 100644 src/app/_components/grid/cards/icons/typescript.tsx create mode 100644 src/app/_components/grid/cards/icons/vercel.tsx create mode 100644 src/app/_components/grid/cards/most-listened-music.tsx create mode 100644 src/app/_components/grid/cards/stack-icons.tsx diff --git a/.env.example b/.env.example index f2d7c34b..3e24d19e 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,9 @@ UMAMI_WEBSITE_ID= HOST= -LASTFM_API_KEY= GITHUB_TOKEN= +LASTFM_API_KEY= + +SPOTIFY_CLIENT_ID= +SPOTIFY_CLIENT_SECRET= +SPOTIFY_REFRESH_TOKEN= diff --git a/src/app/_components/grid/cards/discord-status.tsx b/src/app/_components/grid/cards/discord-status.tsx index c6d7d303..baac75ca 100644 --- a/src/app/_components/grid/cards/discord-status.tsx +++ b/src/app/_components/grid/cards/discord-status.tsx @@ -49,7 +49,7 @@ export async function DiscordStatus() { ).then(data => data.json()) return ( -
    +
    {/* */} { return ( diff --git a/src/app/_components/grid/cards/github-stats.tsx b/src/app/_components/grid/cards/github-stats.tsx index 33062af0..ae37097b 100644 --- a/src/app/_components/grid/cards/github-stats.tsx +++ b/src/app/_components/grid/cards/github-stats.tsx @@ -8,7 +8,7 @@ export const GithubStats = async () => { 0 ) return ( -
    +
    ) { + return ( + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/cloudflare.tsx b/src/app/_components/grid/cards/icons/cloudflare.tsx new file mode 100644 index 00000000..9cd61a00 --- /dev/null +++ b/src/app/_components/grid/cards/icons/cloudflare.tsx @@ -0,0 +1,20 @@ +import { SVGProps } from 'react' + +export function CloudflareIcon(props: SVGProps) { + return ( + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/css.tsx b/src/app/_components/grid/cards/icons/css.tsx new file mode 100644 index 00000000..d6734fa9 --- /dev/null +++ b/src/app/_components/grid/cards/icons/css.tsx @@ -0,0 +1,32 @@ +import { SVGProps } from 'react' + +export function CSS3Icon(props: SVGProps) { + return ( + + + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/docker.tsx b/src/app/_components/grid/cards/icons/docker.tsx new file mode 100644 index 00000000..5820ef50 --- /dev/null +++ b/src/app/_components/grid/cards/icons/docker.tsx @@ -0,0 +1,12 @@ +import React from 'react' + +export function DockerIcon(props: React.SVGProps) { + return ( + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/expo.tsx b/src/app/_components/grid/cards/icons/expo.tsx new file mode 100644 index 00000000..e540f456 --- /dev/null +++ b/src/app/_components/grid/cards/icons/expo.tsx @@ -0,0 +1,16 @@ +import { SVGProps } from 'react' + +export function ExpoIcon({ className, ...props }: SVGProps) { + return ( + + Expo + + + ) +} diff --git a/src/app/_components/grid/cards/icons/figma.tsx b/src/app/_components/grid/cards/icons/figma.tsx new file mode 100644 index 00000000..f05f278d --- /dev/null +++ b/src/app/_components/grid/cards/icons/figma.tsx @@ -0,0 +1,28 @@ +import { SVGProps } from 'react' + +export function FigmaIcon(props: SVGProps) { + return ( + + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/google-cloud.tsx b/src/app/_components/grid/cards/icons/google-cloud.tsx new file mode 100644 index 00000000..3d11969e --- /dev/null +++ b/src/app/_components/grid/cards/icons/google-cloud.tsx @@ -0,0 +1,24 @@ +import { SVGProps } from 'react' + +export function GoogleCloudIcon(props: SVGProps) { + return ( + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/heroku.tsx b/src/app/_components/grid/cards/icons/heroku.tsx new file mode 100644 index 00000000..54f736fc --- /dev/null +++ b/src/app/_components/grid/cards/icons/heroku.tsx @@ -0,0 +1,12 @@ +import { SVGProps } from 'react' + +export function HerokuIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/html.tsx b/src/app/_components/grid/cards/icons/html.tsx new file mode 100644 index 00000000..23601c1d --- /dev/null +++ b/src/app/_components/grid/cards/icons/html.tsx @@ -0,0 +1,21 @@ +import { SVGProps } from 'react' + +export function HTML5Icon(props: SVGProps) { + return ( + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/linux.tsx b/src/app/_components/grid/cards/icons/linux.tsx new file mode 100644 index 00000000..186dfa80 --- /dev/null +++ b/src/app/_components/grid/cards/icons/linux.tsx @@ -0,0 +1,3092 @@ +import { SVGProps } from 'react' + +export function LinuxIcon(props: SVGProps) { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/nest.tsx b/src/app/_components/grid/cards/icons/nest.tsx new file mode 100644 index 00000000..367f2125 --- /dev/null +++ b/src/app/_components/grid/cards/icons/nest.tsx @@ -0,0 +1,12 @@ +import { SVGProps } from 'react' + +export function NestIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/next.tsx b/src/app/_components/grid/cards/icons/next.tsx new file mode 100644 index 00000000..a082f8aa --- /dev/null +++ b/src/app/_components/grid/cards/icons/next.tsx @@ -0,0 +1,40 @@ +import { SVGProps } from 'react' + +export function NextIcon(props: SVGProps) { + return ( + + + + + + + + + + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/node.tsx b/src/app/_components/grid/cards/icons/node.tsx new file mode 100644 index 00000000..7e6e8561 --- /dev/null +++ b/src/app/_components/grid/cards/icons/node.tsx @@ -0,0 +1,73 @@ +import { SVGProps } from 'react' + +export function NodeIcon(props: SVGProps) { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/prisma.tsx b/src/app/_components/grid/cards/icons/prisma.tsx new file mode 100644 index 00000000..d4e27b9e --- /dev/null +++ b/src/app/_components/grid/cards/icons/prisma.tsx @@ -0,0 +1,12 @@ +import { SVGProps } from 'react' + +export function PrismaIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/python.tsx b/src/app/_components/grid/cards/icons/python.tsx new file mode 100644 index 00000000..4da91633 --- /dev/null +++ b/src/app/_components/grid/cards/icons/python.tsx @@ -0,0 +1,58 @@ +import { SVGProps } from 'react' + +export function PythonIcon(props: SVGProps) { + return ( + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/react.tsx b/src/app/_components/grid/cards/icons/react.tsx new file mode 100644 index 00000000..f454432f --- /dev/null +++ b/src/app/_components/grid/cards/icons/react.tsx @@ -0,0 +1,12 @@ +import { SVGProps } from 'react' + +export function ReactIcon(props: SVGProps) { + return ( + + + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/rust.tsx b/src/app/_components/grid/cards/icons/rust.tsx new file mode 100644 index 00000000..ff5efeef --- /dev/null +++ b/src/app/_components/grid/cards/icons/rust.tsx @@ -0,0 +1,15 @@ +import { SVGProps } from 'react' + +export function RustIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/svelte.tsx b/src/app/_components/grid/cards/icons/svelte.tsx new file mode 100644 index 00000000..fdd90447 --- /dev/null +++ b/src/app/_components/grid/cards/icons/svelte.tsx @@ -0,0 +1,26 @@ +import { SVGProps } from 'react' + +export function SvelteIcon(props: SVGProps) { + return ( + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/tailwindcss.tsx b/src/app/_components/grid/cards/icons/tailwindcss.tsx new file mode 100644 index 00000000..058fc15a --- /dev/null +++ b/src/app/_components/grid/cards/icons/tailwindcss.tsx @@ -0,0 +1,12 @@ +import { SVGProps } from 'react' + +export function TailwindcssIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/typescript.tsx b/src/app/_components/grid/cards/icons/typescript.tsx new file mode 100644 index 00000000..c55b4635 --- /dev/null +++ b/src/app/_components/grid/cards/icons/typescript.tsx @@ -0,0 +1,14 @@ +import { SVGProps } from 'react' + +export function TypescriptIcon(props: SVGProps) { + return ( + + + + + ) +} diff --git a/src/app/_components/grid/cards/icons/vercel.tsx b/src/app/_components/grid/cards/icons/vercel.tsx new file mode 100644 index 00000000..3d51170e --- /dev/null +++ b/src/app/_components/grid/cards/icons/vercel.tsx @@ -0,0 +1,12 @@ +import { SVGProps } from 'react' + +export function VercelIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/src/app/_components/grid/cards/letterboxed-link.tsx b/src/app/_components/grid/cards/letterboxed-link.tsx index 17d44d9c..f060a169 100644 --- a/src/app/_components/grid/cards/letterboxed-link.tsx +++ b/src/app/_components/grid/cards/letterboxed-link.tsx @@ -16,22 +16,22 @@ export function LetterboxedLink() { boxed
    -
    +
    Letter boxed
    -
    +
    Letter boxed
    -
    +
    Letter boxed
    -
    +
    Letter boxed
    diff --git a/src/app/_components/grid/cards/most-listened-music.tsx b/src/app/_components/grid/cards/most-listened-music.tsx new file mode 100644 index 00000000..b68f8484 --- /dev/null +++ b/src/app/_components/grid/cards/most-listened-music.tsx @@ -0,0 +1,51 @@ +import { LastfmLogo } from '@phosphor-icons/react/dist/ssr' +import Image from 'next/image' +import { getAlbumCover } from '~/lib/get-album-cover' +import { getLastFmTopTracks } from '~/lib/lastFm' + +export async function MostListenedMusic() { + const { + name: title, + artist, + url + } = await getLastFmTopTracks('1month').then(tracks => tracks[0]) + + const cover = await getAlbumCover(`${title} - ${artist.name}`) + + return ( +
    + +
    + + {artist.name} + +
    {title}
    +
    + Top listened this month +
    +
    + {title!} + {title!} +
    + ) +} diff --git a/src/app/_components/grid/cards/stack-icons.tsx b/src/app/_components/grid/cards/stack-icons.tsx new file mode 100644 index 00000000..4d03b701 --- /dev/null +++ b/src/app/_components/grid/cards/stack-icons.tsx @@ -0,0 +1,63 @@ +import { IconType } from 'react-icons' + +import { DockerIcon } from './icons/docker' +import { TypescriptIcon } from './icons/typescript' +import { HTML5Icon } from './icons/html' +import { CSS3Icon } from './icons/css' +import { ReactIcon } from './icons/react' +import { NextIcon } from './icons/next' +import { SvelteIcon } from './icons/svelte' +import { TailwindcssIcon } from './icons/tailwindcss' +import { ExpoIcon } from './icons/expo' +import { PythonIcon } from './icons/python' +import { RustIcon } from './icons/rust' +import { BashIcon } from './icons/bash' +import { NodeIcon } from './icons/node' +import { PrismaIcon } from './icons/prisma' +import { NestIcon } from './icons/nest' +import { HerokuIcon } from './icons/heroku' +import { LinuxIcon } from './icons/linux' +import { GoogleCloudIcon } from './icons/google-cloud' +import { VercelIcon } from './icons/vercel' +import { CloudflareIcon } from './icons/cloudflare' +import { FigmaIcon } from './icons/figma' + +export type IconItem = { + title: string + icon: IconType + color: string +} + +type StackLine = { + top: IconItem[] + bottom: IconItem[] +} + +export const stackLines: StackLine = { + top: [ + { title: 'Typescript', icon: TypescriptIcon, color: '#3178C6' }, + { title: 'HTML5', icon: HTML5Icon, color: '#E34F26' }, + { title: 'CSS3', icon: CSS3Icon, color: '#1572B6' }, + { title: 'React.js', icon: ReactIcon, color: '#61DAFB' }, + { title: 'Next.js', icon: NextIcon, color: '#FFFFFF' }, + { title: 'Svelte', icon: SvelteIcon, color: '#FF3E00' }, + { title: 'Tailwind CSS', icon: TailwindcssIcon, color: '#06B6D4' }, + { title: 'React Native', icon: ReactIcon, color: '#61DAFB' }, + { title: 'Expo', icon: ExpoIcon, color: '#000020' }, + { title: 'Figma', icon: FigmaIcon, color: '#F24E1E' } + ], + bottom: [ + { title: 'Python', icon: PythonIcon, color: '#3776AB' }, + { title: 'Rust', icon: RustIcon, color: '#F74C00' }, + { title: 'Bash Script', icon: BashIcon, color: '#4EAA25' }, + { title: 'Node.js', icon: NodeIcon, color: '#339933' }, + { title: 'Prisma', icon: PrismaIcon, color: '#2D3748' }, + { title: 'Nest.js', icon: NestIcon, color: '#E0234E' }, + { title: 'Heroku', icon: HerokuIcon, color: '#430098' }, + { title: 'Docker', icon: DockerIcon, color: '#2496ED' }, + { title: 'Linux', icon: LinuxIcon, color: '#FCC624' }, + { title: 'Google Cloud', icon: GoogleCloudIcon, color: '#4285F4' }, + { title: 'Vercel', icon: VercelIcon, color: '#000000' }, + { title: 'Cloudflare', icon: CloudflareIcon, color: '#F38020' } + ] +} diff --git a/src/app/_components/grid/cards/stacks-card.tsx b/src/app/_components/grid/cards/stacks-card.tsx index af0efbf5..ae9b5a86 100644 --- a/src/app/_components/grid/cards/stacks-card.tsx +++ b/src/app/_components/grid/cards/stacks-card.tsx @@ -1,4 +1,5 @@ import React from 'react' +import { stackLines, IconItem } from './stack-icons' type MarqueeProps = { children: React.ReactNode @@ -6,20 +7,18 @@ type MarqueeProps = { pauseOnHover?: boolean reverse?: boolean fade?: boolean - className?: string } const range = (start: number, end: number): number[] => Array.from({ length: end - start }, (_, k) => k + start) -const Marquee = (props: MarqueeProps) => { +function Marquee(props: MarqueeProps) { const { children, direction = 'left', pauseOnHover = false, reverse = false, - fade = false, - className + fade = false } = props const ifToRightOrToBottom = (direction: string) => { @@ -32,21 +31,18 @@ const Marquee = (props: MarqueeProps) => { return (
    @@ -57,7 +53,7 @@ const Marquee = (props: MarqueeProps) => { data-pause-on-hover={pauseOnHover} data-reverse={reverse} className=" - animate-marquee-up data-[direction='left']:animate-marquee-left data-[reverse='true']:direction-reverse flex shrink-0 flex-col justify-around gap-4 [--gap:1rem] data-[direction='left']:flex-row data-[pause-on-hover='true']:group-hover:[animation-play-state:paused] + flex shrink-0 animate-marquee-up flex-col justify-around gap-4 [--gap:1rem] data-[direction='left']:animate-marquee-left data-[direction='left']:flex-row data-[reverse='true']:direction-reverse data-[pause-on-hover='true']:group-hover:[animation-play-state:paused] " > {children} @@ -67,46 +63,34 @@ const Marquee = (props: MarqueeProps) => { ) } -const Example = ({ label = 'EX' }: { label?: string }) => ( -
    - {label} +const IconElement = ({ + data: { color, icon: Icon, title } +}: { + data: IconItem +}) => ( +
    +
    ) export const StacksCard = () => { return ( -
    - {/*

    - fun things -

    */} - - - - - - - - - - - +
    + + {stackLines.top.map(data => ( + + ))} - - - - - - - - - - - - - - - + + {stackLines.bottom.map(data => ( + + ))} ) diff --git a/src/app/_components/grid/index.tsx b/src/app/_components/grid/index.tsx index 11233e5b..14a44a9e 100644 --- a/src/app/_components/grid/index.tsx +++ b/src/app/_components/grid/index.tsx @@ -1,13 +1,22 @@ +import { Book, Wrench } from '@phosphor-icons/react/dist/ssr' +import { DiscordStatus } from './cards/discord-status' import { GithubLink } from './cards/github-link' import { GithubStats } from './cards/github-stats' import { LatestPost } from './cards/latest-post' import { LetterboxedLink } from './cards/letterboxed-link' import { LinksCard } from './cards/links' +import { MostListenedMusic } from './cards/most-listened-music' import { StacksCard } from './cards/stacks-card' -const Example = ({ label = 'Example' }: { label?: string }) => ( -
    - {label} +const BooksCard = () => ( +
    +
    + + Books +
    + + + Under construction...
    ) @@ -21,7 +30,7 @@ export function Grid() {
    - +
    @@ -30,9 +39,8 @@ export function Grid() {
    -
    +
    -
    @@ -42,12 +50,12 @@ export function Grid() {
    -
    - +
    +
    - +
    diff --git a/src/app/about/statistics/_components/spotify-dashboard/cards/top-track.tsx b/src/app/about/statistics/_components/spotify-dashboard/cards/top-track.tsx index 882de352..beff4151 100644 --- a/src/app/about/statistics/_components/spotify-dashboard/cards/top-track.tsx +++ b/src/app/about/statistics/_components/spotify-dashboard/cards/top-track.tsx @@ -10,7 +10,7 @@ export async function TopTrack() { const imageUrl = await getAlbumCover( `${track.name} - ${track.artist.name}` - ).then(data => data.coverArt.url) + ).then(data => data.url) return (
    diff --git a/src/lib/get-album-cover.ts b/src/lib/get-album-cover.ts index 34fa7a43..deb861c0 100644 --- a/src/lib/get-album-cover.ts +++ b/src/lib/get-album-cover.ts @@ -25,10 +25,24 @@ const getAccessToken = async () => { return await response.json() } -export const getAlbumCover = async (track: string) => { +type Response = { + tracks: { + items: { + album: { + images: { + url: string + height: 64 | 300 | 640 + width: 64 | 300 | 640 + }[] + } + }[] + } +} + +export async function getAlbumCover(track: string) { const { access_token } = await getAccessToken() const URL = ENDPOINT + encodeURI(track) + '&type=track&market=IN&limit=1' - const res = await fetch(URL, { + const res: Response = await fetch(URL, { headers: { Authorization: `Bearer ${access_token}` } @@ -36,13 +50,5 @@ export const getAlbumCover = async (track: string) => { return res.json() }) - const { name, album, external_urls, preview_url } = await res.tracks.items[0] - - return { - name, - releaseDate: album.release_date, - coverArt: album.images[1], - external_urls, - preview_url - } + return res.tracks.items[0].album.images.filter(img => img.height === 640)[0] } From 350e57796c0331d91aa1f17e259792f3fc382356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Sun, 5 May 2024 14:47:09 -0300 Subject: [PATCH 15/15] style: fix eslint errors --- src/app/about/sections/knowledge/accordion.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/about/sections/knowledge/accordion.tsx b/src/app/about/sections/knowledge/accordion.tsx index b3c69ecc..24732724 100644 --- a/src/app/about/sections/knowledge/accordion.tsx +++ b/src/app/about/sections/knowledge/accordion.tsx @@ -40,7 +40,7 @@ export const AccordionTrigger = React.forwardRef( {children}