From 4b22c0404ecaa6bd3e5fddfe7bbd244a9186583d Mon Sep 17 00:00:00 2001 From: Kanav Arora Date: Fri, 23 Feb 2024 21:09:48 +0530 Subject: [PATCH] WIP: New User Guide (#3984) * initial commit * Theme setup on twenty-website package * Left bar, Content done * Content added, useDeviceType hook added * useDeviceType file renamed * Responsiveness introduced * Mobile responsiveness fix * TOC layout * PR fixes * PR changes 2 * PR changes #3 --- .../user-guide/home/create-a-workspace.png | Bin 0 -> 15795 bytes .../images/user-guide/home/custom-objects.png | Bin 0 -> 27216 bytes .../user-guide/home/import-your-data.png | Bin 0 -> 25563 bytes .../images/user-guide/home/what-is-twenty.png | Bin 0 -> 16600 bytes .../src/app/components/Breadcrumbs.tsx | 50 +++++++- .../components/user-guide/UserGuideCard.tsx | 48 +++++++ .../user-guide/UserGuideContent.tsx | 106 +++++++++++++++ .../components/user-guide/UserGuideMain.tsx | 90 +++++++++++++ .../user-guide/UserGuideSidebar.tsx | 77 +++++++++++ .../user-guide/UserGuideSidebarSection.tsx | 114 +++++++++++++++++ .../user-guide/UserGuideTableContents.tsx | 41 ++++++ .../user-guide/UserGuideTocComponent.tsx | 21 +++ packages/twenty-website/src/app/get-posts.tsx | 17 ++- packages/twenty-website/src/app/layout.css | 20 ++- packages/twenty-website/src/app/layout.tsx | 15 ++- .../twenty-website/src/app/ui/icons/index.ts | 7 + .../src/app/ui/theme/background.ts | 13 ++ .../twenty-website/src/app/ui/theme/border.ts | 19 +++ .../twenty-website/src/app/ui/theme/colors.ts | 24 ++++ .../twenty-website/src/app/ui/theme/font.ts | 14 ++ .../twenty-website/src/app/ui/theme/icon.ts | 13 ++ .../twenty-website/src/app/ui/theme/text.ts | 22 ++++ .../twenty-website/src/app/ui/theme/theme.ts | 18 +++ .../src/app/ui/utilities/useDeviceType.ts | 22 ++++ .../src/app/user-guide/[[...slug]]/layout.tsx | 121 ------------------ .../src/app/user-guide/[[...slug]]/page.tsx | 21 --- .../src/app/user-guide/[slug]/page.tsx | 16 +++ .../constants/UserGuideHomeCards.ts | 34 +++++ .../user-guide/constants/UserGuideIndex.ts | 29 +++++ .../src/app/user-guide/layout.tsx | 40 ++++++ .../src/app/user-guide/page.tsx | 5 + .../src/content/user-guide/home.mdx | 1 + .../src/content/user-guide/what-is-twenty.mdx | 57 +++++++++ 33 files changed, 914 insertions(+), 161 deletions(-) create mode 100644 packages/twenty-website/public/images/user-guide/home/create-a-workspace.png create mode 100644 packages/twenty-website/public/images/user-guide/home/custom-objects.png create mode 100644 packages/twenty-website/public/images/user-guide/home/import-your-data.png create mode 100644 packages/twenty-website/public/images/user-guide/home/what-is-twenty.png create mode 100644 packages/twenty-website/src/app/components/user-guide/UserGuideCard.tsx create mode 100644 packages/twenty-website/src/app/components/user-guide/UserGuideContent.tsx create mode 100644 packages/twenty-website/src/app/components/user-guide/UserGuideMain.tsx create mode 100644 packages/twenty-website/src/app/components/user-guide/UserGuideSidebar.tsx create mode 100644 packages/twenty-website/src/app/components/user-guide/UserGuideSidebarSection.tsx create mode 100644 packages/twenty-website/src/app/components/user-guide/UserGuideTableContents.tsx create mode 100644 packages/twenty-website/src/app/components/user-guide/UserGuideTocComponent.tsx create mode 100644 packages/twenty-website/src/app/ui/icons/index.ts create mode 100644 packages/twenty-website/src/app/ui/theme/background.ts create mode 100644 packages/twenty-website/src/app/ui/theme/border.ts create mode 100644 packages/twenty-website/src/app/ui/theme/colors.ts create mode 100644 packages/twenty-website/src/app/ui/theme/font.ts create mode 100644 packages/twenty-website/src/app/ui/theme/icon.ts create mode 100644 packages/twenty-website/src/app/ui/theme/text.ts create mode 100644 packages/twenty-website/src/app/ui/theme/theme.ts create mode 100644 packages/twenty-website/src/app/ui/utilities/useDeviceType.ts delete mode 100644 packages/twenty-website/src/app/user-guide/[[...slug]]/layout.tsx delete mode 100644 packages/twenty-website/src/app/user-guide/[[...slug]]/page.tsx create mode 100644 packages/twenty-website/src/app/user-guide/[slug]/page.tsx create mode 100644 packages/twenty-website/src/app/user-guide/constants/UserGuideHomeCards.ts create mode 100644 packages/twenty-website/src/app/user-guide/constants/UserGuideIndex.ts create mode 100644 packages/twenty-website/src/app/user-guide/layout.tsx create mode 100644 packages/twenty-website/src/app/user-guide/page.tsx create mode 100644 packages/twenty-website/src/content/user-guide/what-is-twenty.mdx diff --git a/packages/twenty-website/public/images/user-guide/home/create-a-workspace.png b/packages/twenty-website/public/images/user-guide/home/create-a-workspace.png new file mode 100644 index 0000000000000000000000000000000000000000..9df5a6fdacf1482739f8fc00ee79b3fe1f40f9cc GIT binary patch literal 15795 zcmeHucQ~8j+jdm#Qq`)~s8*?})z*$(TB~U7t!jnTOzc^dDuUWu?G>Z;UM)o>X6#iZ z2!a?j!uNQ8?|U5I-`{b3|Gj@W9^y%!JNJE!^E|KX3V)-aL`%&~4FZ8^Rg@LAK%gr_ zAP|WTCHdtmnKWqNLglP%2m^s=ZeIS7fKt=%056ijw3J?e%2BNAz#ms_<<;dupsHw^ zGYc{hNLpD%QC`QBWNVJfQ)lJ)Xjk&Ijs8VoWiW3;HiV4v2kqDu44L!GTPEhEfj-cS zP-klc&32LgU@K8w?DtW%I-HLcl*j0cI2Ane1OvQ;jOJ_@|l_E?>Lq zu8~ByYFTvoJLLHlVc@cOg@hTnIDZ7u0+$B4z{|rlxi5G5WC8kY65zr_2^=#hkmf1` zxO9;H@7w-&Oa33MWRTBx;I>O?O~bEQ5Qv{0u)5T6^2Ne?zhZD3!N3$M3~ zXZiDKzoLudMc{aawo^GIjOQqvK^-4&{>PH}{>zfL?VQb|JnHzoz3bv{OX$b?9BgrW z$UajVX@Va}I(2(MUoT=nTl`3<*j=B2TN2A%!&g8M3Do*Xr!S`*X@|_vj^uKAA7c8| zX?1~eUuwQqN^K8pGcuwl`AwO;5$Tayw1&{fncJg2F^WLgIOcU{8@=y$L7=%3>I5uB zDUdwSj~;Shpx}&sHp<13|6u2~|1)!UfwV{C$IV>_Dz?|fu#>#w--g4#irSZOW(-wM zn`9*MG-4!P@_LNRwsebu78f4?3o)at@n#(^PlGcHslPwHM(wGwoyPnbD;ZQnj&(28 zh>!2Q$tC<~7|*(}gDf3>*rOQ}yUa}uyczJ%Ks7;W(ZONZyf)?GYU}sSX0299<~ENu zkwKVw@cx|U??f}D!<)czUjoa0L_G$>ET(%O#!Hi9SLKkTAR}_Xk2mE}nAa&T*!a1_ z^y{1pMoK2{bBf`R7;?~N0O0KqMN94H@SlxUnS_sdwTQFpwrZv?6%rJoY!kC-54bZ# zOhBO1>%d7~F%b5sYZ10g&Bc~=HqI?3y6xVpr2~oY0Fh(yC6rl{$fF=yHYd_-h?Njq zxzZV2?0KLyRkbG58xpNnMz0R6C-u@I@>UMgkMzzds@0L*KAUW5l^{97cT#u}NRGwI z8x^e{htp*FONAa@C+5u@(Bz%c(gZz`;zcI^IFjsz$=a$FNO>+_B>@SyJCg*8J~Hq| zsq5CATTY#iSSdv*Oa;gQAIBj_3K4?m8|r7Y;+QF1Ghr}ZvuYh`nRI?@oIBAAuK(k+ zyQz9nsN`Wfe&o-K-iYWLfjMRw_k23iY!VV?xzY(EZ`3^e(f;9av%szWd)0-b5|l$9 z?c9_EZ_VvwxEVL=iTbzqP!D`UsJpr=**f6_Vos_G532MR{8wd6Vc8DA!9!|=`S>#> zXR3&GIir?&6|{_$vW0{U5onDgv|BWca^$STsIC$)8%FztViyAIF@5+fWqA}iCf ztNKW_ntZir-=AT@sezN#4Y3|B7S^=KakJ#$WrX|ifM1EwiBq;vBf7!421Mx(7#Z>l zc_9!5oLi9Pt&26WcNymLvufNwx<4Ar+y<=p*?15}7yq} z{skR#fuH%%(9^&_exV>r znaekp@*e`0na$s3tj6te;!ywVw4(jJ%!CIUoT)DnoH%rpLGnVFJ{?#{kVbZ9>Cu_x z)!RkvNcod(Zkx2bJ)LXEb^&oo>;YrG{`b3K@Q?#Z+qu1gA0i9%euJ%dpS$`xZ~If# z=w3c5w<;4hU35)Imqb06M8NiKXnfg}+c)c{hq)I=UDbR4q&<{9J-hYDTk+>s72Slu zdmOfGc4U9FViVHJW>!1Q3pjN1uG+mYnS(P%fIVU z*p5Cqn!8<)2SWaYVVcdqFhW55TG^Sfk-%p*<0+Xi!Y@BtTTguT^w3AeYyKan<$ zeTqAh)6Y6uIg;1JM;j$*Xu97!?K1K*+a=8FihrnGdHMZZkks%Kc~DI2 z6}Bg!p&*E<0ypp3(%x|9PMNgrR)agUWYo@VBwYU$(MO$ih&~xsXVo7m$vtqOK%s)d z@Q*OGwnM%ZHhpVnIz2hfmiO#bjSWluTsBvSYtR#I>8{ojy;sv_vs>avgH{a=7@@NK zjWtr4u5^zAQ3?R(%O6B;YwFT=Uh^?C;wsCkgl5vV7~djCCy|pQKdrcXzwOlWrg8$g z9nmA%Wg`AIQ(k}>F$zoQshe|G>;A4M=IsGFgTg;~|9wWwiviIKfShC2RjbRvLg?eg z;rmEIoffPT&VAAws*)CPi|Lj!Z1|~f{{s&0eF){SDAL~dpPIS?j?Eo{p+}0DM)~8K z{fxsg4($$hrcG3Vi!TDnori=mFbqw%(T3ClMx&I>d(^)M6^+Ta@e6dY?t+*e!pC2b^UG9ylu<~L=_S3f_NJaQ&;=nDzH6t6n^F=6hd_SK( zi`>&?ju#+`^kS$KcrY@*`Wd=$g-Te~h}&(J_#-`7^l-ZXhW=WX)pj&H5uti8_odas zT&~E%NI#y1#lm)Uu`CV@ck?F7oN)_5&#ib)-cKy76VZb27%1pDHzOzwKaxAkt$(RL zlCniY^P*Dik>2DNC{JY6Tr`GB)EKKSTw37WnRb|K+glT>o^#u#34;mt8}>(r&F4;|xX_)pd=8{tSo+hrDw|3c-oJNgH%>O;kzQIS9MTgtV>`(l;Sm{cg7H%+_VVwL~w zGNqv1xQz5Y>d{#vIeNJwPjTp4xB07@o*FDE55ik;SFVa&5e~GehircsjjI)85SF&( z6@H3tJlM%(cbEXbR>y+S(cAFd1unl?Rx~=B&2nx9|Bk|rc3>K9c7*+ynczZP_}CWs zL2S}%*ivn-hFosB;WNElwM8auCRg4F%GO56J@Byj@sH}c>)E{eFGxwu4keV!yTQvM z@nZh<)G^9(wc%XKdvsdGw|!~V{XPWU2p`nyJAGGY`_pjUvnO6CfY(~q@7+0Sv*Y@G z@f+DBo7L&aliTOFdM^(deorW)y$(9omsfn-7n)k^2Ki*WI|@s6^M}9o4T@h$ zP*Ya^Y$?PrcTck5NRG;lC>VN&KR}{kA@#?&y{n)%~{hoK8IS-4z6I( zS^#Y5MO*osRqRGeI7!_n<6TwNLZP+v4L6TdgQfef2KxN|NM1Q{We|qYz;m;`vUxKO z>Ao@;EwjG4dE#q})BWl!`HZeE* zom(j}d6{FC1Otd7Dc~hl6%CE&N43nczI)=~+n5DB)XlA-$+Pr?#IrJd?4w{h${a{onjghu}DT2o3eeck+ScmHIUWyJK0; ze}^)QvO!;=??&xzE0xxi&mA^l-kQ9*k7XY=exJ+1$-&VDliCWBRcn@CW;Ji#ts>;P z4m^>7Z!qILg!*7o0YA0B5>75s5>|ihw`s-I|BUQ{+E-#2p>qvfBVgHnaQiga9Lme) zPoz+h*g6T6RY3PSsp??cz7q!RzMkrJZ*KZ?(|)DMwAE(3pImwK0Z4yM!qUkuL*9di z@9h1@LUyDj9)9z7y*&7VgyA{9uki1-nv$B4QAxUHoF&-rhLCbT`iR^8>{=TJ*EXHm74N63$sK=BaQNyA@D z>g0ggHZBNKdf;%D~s=zYkQ}H?tTBI46w26!OL+&5w8+EpG&x$0PI zkgU<@km*Vd?n9U@E&YGR&PbbY)oE@)p>1&%69W5WY3K7IZpJ&^h;_m0#8%#5CDX@- zhErO`#!v(_%dmdX>>??2`f~|Se`0DEU;Ci$2J}h(6Q_tV!%qDTd)8>(Ed#+?>tn4H zV(!9G`DER6S;2&EqBsIKp}*pg_(zv!@Tk5U=I7VSDrr^p+Po!l=UUAbVDopfv5~>@ z!9|F)0rM&-YmOPj6F^|DBZlfTAnRcv&4IY7C}SnpgSe2qIkNE>4(QJHz0nGKD{@-`$p(d#XdGV-?zJ0>#!QuA4ZP- z7k}tF=Xd>A%#GZua?ZJ3Bpuz`5;!SapPvAb8C6s=5PV){+-!imjrA>S={G7atCKOR zKl>hv9&T7&Q}Ur$Z)h;kl$}nKCN<)=3*q(<$-=$j1BilFEv!1e+|<5AmAOdd8gAA$ zgVglC#3DHN!B zvA?dD?0z$kNmf#`?RZUrS5Zlnxgaf~Tv%UMS0%ajtKaIHn$?ciL#qxu1u{7t04b)$ zk#=i$p5dE9sZcg6QC=uf+Fyl-H`eFAEn#Mbl`Ce)=nLEun48z?7Qu%O=Br9hGc|AZ z+Uia8+AcEPj0L=AsyUxO?+RHT8luM$l&kqYwe8-N7gyU*ovd@^@j9{9h*{ZhjnA0#7ETcNxA@;6 z75;}VH(mIRM;Z8^twN7o#>KunEWZ-!Q&|77F*NjMDzkBlP`j(5@-;dALzk;}bmr=5 z4>y;ZH#&2q(dW8EOF+Q-2R4c!clzv)qM^XiLPRWoJfjd5Kjlz99lf7X{kXfDtZsV3 zp_8P8|BCQXCdc09~xz9P<%tuA@Akb}ap>>#T zng(u&o;H9vuXY+W8aG*CoWt^W8F!tcJxncrjGW z!v?ZO!NMS63gCOGLfXB0Oyi`PC`bvC**ZIqRwI~6^IeIZo32-3V;g{X%K%T@MWxll#i(#`XQ2P7-O(wKY%4R*R!62f6<(?SvUo1h&2kBoETD zl*S(FIctDFGS(F|9bAh=^)bNLUNq;*gJBqm5;E9dIIz{4V(kqHy)c}qR>>)gQ&6U^ z6gPWb#xnvN(dw#J>%5bxTX{Z9p{A%Rw(f`Kw&~9P>`wdfIOF1X5`d~wZbXAB#ef~B zH$2;vI^JoIVC}W1u2bF;G}RPVfBJe3^7?hiJ3-Ejr?0$UduzY<5gSX}CtHg!OQRtP zWVs5t|9OqNMleIF5`b_vC!o|<^}pyaG`o}YK6o9hZGWBZBjuEdB1zDsF>tT49o7)X zQc~CQ%j9Y8xnOXaT&rBA?F=>NV=^4tuX2r(&d;UM<;0oCc!ECD?Z-pVCe0OL`X5?h z>ap`40es=4%qQrk{yHGNPuU}Dyv&8k0-)8LkCAhaARK-kHgj1NsZ2@Cc_QMt2-LRN z4#&-oHb8%n*AV==A?4n*|1W?>x>r?CuvRaZ!pOp#TE6K9uNawm)Wi0%lSVO`Lpdlj z*h?YcV#{#o!MCN6l~mi`5gMzxq?7trA=wF^w_RG`ti(znQ49+?$ms*z8&QC{5$LG; zeUXOh2~FFr&Ct*lJ{;Q}Vn#iV8O$PGGI|3Ou+>%8OG5@qRcHWF+KX^Wa!Iwd9!nkn zsG?=3K*XJ0UsXQ;GL>l*b|@zq*&h?)-%Un~u@d>9>WYaS`Lm90%yc0}jV$0>uDfr^ z6uHsP=@iW^hTGhR>&`z4m;9?k61WQ3caTBfb$mZYLSMCo@k_IbNH5F;%2sRLxJp>t z_t&a&Q18AKw`oc=a{X*`)Y)TaYI&*_C#}l`zKBC% z6rgP0qvMT=ysvNO89RQ)AP#e!)}$#$c2NDdG<6m1Omhjz>kJGxxNzID8ZTaS|E;7D zlR)vF{o(5K@dyQVv;mGM&)08c3Q!Kaj^2GFv^AvyH`H4ug*A3^!3K!WT(!%1ojnJs z136_sFcRczaa10dgjoAIDk!BjqBV?$hZdGiDjKm(39Z}0cV=v3um)j-i^mThoF^S~ zvI=QEsVn>Xr^1{GFh+p%)NmMQwQAH6Pi=}Tid|VN`VF~_Gh2RmvotruoBcm7OiE_3 zo2Jyhng-LBUgxh0!u1C;nYfMg2w`$I;_x>!{k)>{wT&i}0d~=fKb{Q1_HVLFnWwq- zi;Qgl-CZR#^}jEkZyff$7n?4?hH5niy)&=8LR-UdAd;XJYuCD9ZfwUD%8XOa!&ZGM ztJOLogfaO1coU8n`yJUjO5Ka`x~cArxsPN~ABuL&<{kEC8OmM4Na`L+n!2pM={BivIrKi$3r3M=Ic5t##oOCj_Bh+9&vcHA{H{Y92pn1_-H}yq6&> zBt%Ii8X!&(#rP0Kuq0)8FCxAOrKGAe{UFoQ`)vY77OpG!28eNRV_OP4Bz%8+sKvtQ zbZ~~6MfBA%2c@kRJEhUYFEh`qTV7EXW2gYn7ZfTi2}}Q`*EE!rbtWv!0?&BcvEkD2 z&tnsMYKmI6|6`)2FRT6v5KB2(ecFEPOUZZL9F>aJ{cx=JrOo#^Nw#l%1mK#{orIpKW2?QcagFQegt z$`Om1yHp)vODWH4P%C_0=ncb322R4P(IJX4zEDl)B=(Wq3_PqZrpTbrZ>jTy}p$XtPE@NAseOch}d1PAtGFd?4B#1?E?WgXuRtnX#C0hvu z?k`=20e#9yH$MIE%^o976Ry|{x+FG?F_!tgursc1aX+_8Rzx(hyu0z}*J=Rb>vYbC zc9?ysYJMG`=0;ic{Kk`kGD~YMbJGeEZq4ouwcJ1y+z z6=IJ|PQC+M5F68TG=2Es#xO$)rWZfEN1K(R3*J)oDdm~8DPa1+=HIj+F~c+~@F}Z( zt+8Uc3(gqhFPy5T-7_+tz?3qDYHM#UDG=B1x_K6{&YX?Rhf+m-A)NY8Rh(&jY4abP zZNE4sa~)F&z6whH131NRrJhL=c}{?teEFi9S67FbouD~~yBP>x8S98SuBiIH8*71~ zHVI#r%6LpHw&gp zF=6pjL_RbCb4!S;U@^B5L(|O8g6QS+?yAnLUQSAl{oY+YWk+bl1a+NGwAYg>Vi%}!Dc?+^F6~qE; zOO&a?yZg6XwB(1+%jrRynQ>qE7sL@{-BhL zm>)l`hDXeZoXbn1P6;`(_$m+4lVJ$;Dcd!C6?_^fl5Dm{ymK=vIQX-v4qJNX`66{$ zqF>C9r#8QlVZkGL+0#_F(a;c4Z6>$z`4x<><4()3bM==p)=u7@2*dnTRc^YRiu@n`RG zM*>YS^L8dkEmxynwi(YZG4wPeS8%VTJqwemao4477Jd{Da~wl456UIIg7CXu z+Ar#F%b`y@7G>ld_8~(|{);}pyRU4kK*zcN!NGy6^2IXOathN*`CTC@G$@sfcSw$R zuPajN?}E_1gzrI8+FO;!<#af5J_d#jv2SwYw;Ypp@-#@Y+ELW=->S|@6c=3U>&fch z;vh53ENV;)cOMqpo?+m))-8j*7#$`Xl@kN(r}9h9ck7si>wIT)FhbPnrFpxfK+Kl7 zYstZ>3I2%K#gS{()vCQRJ5Wv!g3#%R2kP}VW0q#3>2BE{AP>GEOY=s51`t?oCKCJS z9{CogpI@-{mbyE}&vFIC(P8J7Jq5OuY}@@S#`F`t5O(b%!zXQ5*X!i<{oM4`kVlig zy(1z=M+CNDeN$8ZT&GM$^j*1XfC$!Txg(boYGqaIC+>aCXzg~|%+QdiY#uP$9a<;T zZI8TGy-xWoV>9;XJkEb1cX2d8ZC9)!O@(Tn0de=if$j?8etG93*eaxFzLw_xZ5=uv=ZdsIBDpnT$_#=V;R_ zyyeM2`}~DYdDHT}E}=kT=reaY-hBC!g{%Osh)l2P$ku^@!PvY!MWI6tQiLM`C_~yY zof|%>FHbBIP?AJV>{?{Jl4Y$##ky`>4X;FS(>DBaF|oxLm>=f>aY#j{@FB5he*KfF zX%9NF2=#m3LH$Zpz8dq>S0k^ie_^mrU%w2RtNOX6EVKIIs>|#8XMM+sd$nzZ--BKv zx~oS#0I26d&x)jK^aA1M-&+a)9lI-_Qx-?qH@^J`ukow6#vzAc=bn;SA|^%K2D zP8CP@teS?wnqsRlaa>a6t;=U68EN@otWvn-9$!0F;P{;FW&^3Z%CC#HyS$2M+f7s6 zJbBFT4~I<<;UNR?99WW*qX&O>vO(QiGH#TC*ztL-kL-RwBZ06pRcIa|V;>~2TJo_4 zl7<65MZQ(c&XySS$P0h2FrDR9nn%~(?Xum|i;C;#FU`Z|<=bFtkbj%&t#GruHu1@* ztiw9%?QyM>x#ueF?+d1QhCTdi$ocEYuFFJ4<&OqvwhlRAXQEX+eSK8G>#n_C%ncrG zry+UiQf3^I5@O23Z%nk)`HQ>D7Mf$|(Yq(9{h=8Y3NO@YKUcv)bdMzEw3k5B^v&$j zd;O)H%hRQ7wRBr?B{82N;gY^Z3yoAt7t>{WVO(zRtkK)9HB*C6&wo`DQ7U6!lpsZl z9$SJpcuWVMc$`zfI0IfPC}HO1V~>YB6>!Wm=Bb;W5AtT53Jp39J#LJdUV$Z@kDqv4 zkNa`6Hx;?)@UnD1rb{!kN~SbUgGpx1b3Xmzyl+1>4(Ytr>h(oq`j`2$37EMLD(s$^ zoIvY==ms;0j#&@j%D=ajk~|$~$~UV#0Nf?~5loNt33+c77O&wJ_efT~Tbg z-tTYrAeQaqpDEnPxJerT)!*mG#pm#iZX(861E&k%H`0nY=57I&UMpG<1)Jq2=#CMt zVQXpKW^=BuUB>+T_wR$Orp7<(#%;KUB>!S2bkk^c;ra?;P0X+=0|>n3;6k8{wu&By zJf^ex5~SYkiuaLu#t2FawP*9GABC0+($Otc!Bu(hP6r>+p@k z*Z3jBr5gZl% zH6sZxws`Or5$9LN!M?z@e;l4P08>TB6w!q#H$RvFx3z%-N>h4brPfr#FB5Q8PK8D{-ThVf>g9Mj-k}=93OFyj=oS8iNlVhpP#P4g3vvt?M8q zjlZ7mHqfx5-|kFBXnnW;25;Gs4_98__I%CFJC?Yb@+44<*4Wravfd0KYu}I;m9C1k zl%)|)6nMV%X5F(hi|Br13{=KMv@4uTD!+%5yz#)|e0kme3k>POp(SmOHNI{Ecxz%L zHAUcD)Ased&!JPz&ppRJ6=2>PO;@W zWm}+4BjEg>JqBPaj8OCN6m|Pqv{k!r;SV;i0(j$|N-x2|XPcbItkz(pm#D^o08hYLo}VgB z?XNW!sQIiB7u50@PwG%<9h1#|m4#Jsqluv?HL%$~rtl4T$nvZM+Kku2rFiw3(<4^F z26YC+y$5~4Jref@jAgV{F#-wwTe43R>EwoTNon6z*vT68&S!x4#1Q^9p|*^-<_?Ln=8M-s-U+YM!A?uBX^UWbX-9@}%UGM;0D0M@BqKF3-+h2y~ zIvnc6v`1HKXeTtw+edgPzpgMp_KW_CUr0#a?o~1P;M(D>{N6tGb%U5fXyhF(5Pcbd zsUdpqm)irl#=Jb(!78+dMQV8Wpvk_BrDFfPUc5q!sOhi@Es!<%?AqJ(r!(Axm(%$* zO?g&uvI+O<1!8~EwGKX`9g&Dg&z%rf_P8r+oC7|JtK)lv7canue+8du^cpmcuqPUK zdW9{}M4z01c?_OSY;r&@{ANnr9iL;ljPdl7%NuvpD6(q-FqLf>#VR%**(!Egozw5(vqYA1JMf4laBA1|bnYVaT z%6ST<_?cKxRRs_4HGfQ&CB?giZWynq10o=emcHJ79t9^jYsL6|N91GNr;KN)f4Xo^)?J_OO%P6utSUWxXGAu0&w%HS&=K4;{{c)tZS@^*|BU!r$CH zq1lXsK~hCIuR6FqElbDxg1+)Rhj#|R(W^f-J4|UVzh?rl>F?S{fr1sg*sqm1e9Xyb z2+xxzqP-%%D@GPhM04^K8WP^;?TLGX<|^ZdcsA@r0+UhajyBIZCSXtD)4{6>oB$n>VrFBpX z2aF<&Cb<#~Ba3Dv3hRFhHhJQFLX3 znJdj5BO0N!gxuQl96`m+<9=`kkjZ(1xl`LKGVtf4CTkPcvvCZ!XHc+Ajp@mg{i`bC zCsOUxuR43ts>2f%YK0N^;(ygButqziKI>|ktg4E*A6OR(q@v)i`P;su*B4Yy54X#zl10}jc1j{uAWn8tLK*`93r zL!QEg$DgtWk63)Lrd(9F9eYMZ!sJG!0AJ^-e;o@GY<>YW83Picco8#BY38d&iw-#I zJZ*UrNLG2zp-6c1u5S32TMo8i`%Te!WYPY^d~BXI0`}d!S)W?Q+Xx($A)rF~Dy_<+ z$sX6t@A-5;mz2zKOTyz$ip3)+B*3d%Az1zMwmb1kZ{sKP7S5@QM&pqR-x2B=TgiJf zQqZ!ozYd9++KDOakLyY@Sgc1a+eLMmSuEEk;OVhK^$7Ef z&&01PPfd~*R;t(A@o~@pdRPDS1T>)JQ}AJVHDf{T>N_VI$D>>| zj6iHnthTWUQh}ElP~oZ_-AxrOfAGks ztl(WlO2aoMhtO9dtOR5j#55OO)!VlH?v(Fjm8+vf^&FnNX zR%(8Y*?HV+DMB`r_rxjgq3=vTfG4fUg$sO3RK@=06_Qe_%0=r@ zrzJeUzni^=A4-~;69(v_pM{eYdT|00MP3+tKK5Gn;AQaoIW=0hIB&X=;Uvu=xsdXJ zr_hwUxEt>(6|M2PXnMDr)pbD(p&DfNrmz$>Ja?jY#B#ALQC^GKx@gqy_dn@?ZN8fT zUm=^SOy*Q!7n`ZN@ufVIsmycww-+YC6Ck{8_OC{2WqrOczkH?Mr_pDA9s;P1op4k_ zxv;HZi{_WMNnPSlQ;&pxWKt>qq!k3ZV@Z)s#_T-(M(A++Q0aXAu212^k@%xYNk*Sv z#SG&Icf!|Qaux_b?ujbq_*`=iv1Lq{*Uv%1{zOX+xBxmkl~Q!fqymN7pTN+L4-?>h zpW8lz;Q0lB`HikKGY8`AO99Zvcf8Hkcd=&2^Y83sJGTE~jc4k3TQ<-2^g3eM`+?2; zsgN~5g;GzM$K06YC8cl+$5TmWc0D6EGD$kvd4Y~UPNZAQ&SdWQcdN2z_H0cfB{0O1 z{?DBMw3fD!n&Bqr44S^O&nHy=qhs*+3>&>;DlK^InDXO@ZS|;H*9w{NMcrIwuVa9% z7wF7D$}R`w7dSWH^4}}NqWb`xGbs%e*n?hZ*O5)2@T?}nFK2`7Ps!Nu=5Ra_4*UjyW{>w$s7C3__sn?~w zReLrYpTGNMXR~RVsV{3JSUF06$LAN1O~2v+YS166&*b2gEc4dv?@_Ww))1|JOQB}+ za=zr?OE)T|3~s7kV$ZWf4cQ5171)2=*bJu_Tf&C3nrWf>3V?V3Nt?4`9sKtgZif13 z7;UUc^`}FrTMTMALGs)eI!}PGs=C2;^|A+`DdyvQ1c|#`qSLr0jhGw`s_pa z#;oQnrEsDKj=8DHAv(Wwau4~};G5XW7?kt82*!rRk;ShVw!Jo{;h9D0O(6Srh@2oZ`lo`S_Dcxm1s-+zHh7YkPzCCxo2b@&HVTm zp0{U&M2-N|%qYE^XKtGur0>-!x`Ah5=7K+FM4fUJ-K1W7&z{I)VbUJKwKT;GjndvOBb0k@@wyhnFN%xIi0Cc%lOU1B2BN7 zyjvIo_I|&Horp)b?|q=j#0trJ15yK`-1Tg!P^~xO;>jg1mDUd<_zOO3)%e=b9V(81 zPGU5^Yjo@+g3Fe?j>e)f_n~19PTrlCM=a?x4mh1_8Rn)L?c+DH-4b%2cm$7aJmQh5 zvCje6wTCyt?#)qo*qT9;_N#P3vAK);op(X0B$w_O1q5<2rq!s7)q0_C8k0jvhF z>eHbD5ixOVMH!+9??_epiE&aN5?naTw@jq~l1H`|z#@m9G)~?2og?-d^EOE4p<8*m zfEpda4Zu>|Qx&sp&R2Q>4F(Fo(t|!anA<{QwnCEzZ(VabW|y(%nggSM28+^mN-p@B zOkZ!*+Cm$vrKdBa~#>HZ&h2Yy$TO4e~Y*7 z#BVd)z5z@UFh5~wIzf^&Y!)7=4>7usud%7!i$5uOuCgZEf8$St9)IHhrJ{)2VkM(h zS1{u?ypFVlHn%8?q^P*k?S`->ph2G-V2P0NP5&B1>*zS7nH||#Ct)K&kt1(d57M7= zG`N4G&oqB6?d4bBKL%70PWXRDa|e}eO*#zG%|k9GrCelL?VJFb*h$-d+vtF-ec>NH zcFR_BgBkGXKw<=dP(*Wi0I@fqdgyhBa=U8*VD(*ufAg<9c4&v%=5XKL*i}MmwYFFy z-548vM*$Jw4BjrQaBPE2feWJtfygB;en}LBYA`M{-J>fb#*POww_99in0Ytpgn|CH z37u3IH@c;_1q&wn+Dk_*2O_#QS6+R_OEg>5QDupBnuJVlog}eFue9uP^PKH_@xm{9 zspq)80K>3WTU};KDX%eGgaASuh?N!SdUNR62IBO%x#kC+U3Os?@Jn49`U;HTZXP)=jARM{^yvcZ3`$L*1s0hm$IdrW$)-<~Ziw zbnn#Jf4#EW6QIE0z{|}jt#atBWe577Dr(rhs~J6`Vd-%fORPM^a|b}lOI*0qRL0~a zVhk0SMT4-(+g%=z*4g8&pYwcy2`al`b)TGqbkbWopY~ zV8P5x*^@jlI1)sgtzHdft0*I?Xf+?kq^Fw*QETX)jYOlW^geFgpIiBoGIFrt<Lz(#=jii1P@&}qNI(8iP?b&ZJ_i$eM>?V6^+erIofl2e_R9rC9<-0OsZUVAjMKJ zX^Pz!_1YE$c>owdAd}CgX)L;K@gpDum%xT6Xt>(&Q~oza{CA3-H^cu+m^j|z@Z7o} zzNM2aXa|AlWPr3w-|@?3*?Ksd)_cW3j;;0xZQVxr+ou0+IC&VJz^g zCle#_T!jEUdfV!b$G^K@J@>uT{pUA;L5H?oSTWBehsaBbuNO-n(3Y3pun6!6kZ{+w z(gmS?fb+=%mA$<^X(D8f!9>g;Ttimtz5lubG_0|$&buCc7pSo}>aIBMhXC!VtbYCU zURJx$>lVoa?_Yk%W@q4NXsS^dP`<6@_uT$&rk z;s5)nX%P9E`bl3&v_2*9G*AF;qD+(>V1{j%1Hb|5__C9=hnLf>i}>+?!SAv}Fefmk zTXfLZyc@2vhqlJ6_Lk3GPW8$KZ~lJWXuk;buk7sXn0;$(Y#c!9t|_T~p{g~uKVDq_r}m1_SYrsxR)at)FEtd)U%U(YKi_gA AM*si- literal 0 HcmV?d00001 diff --git a/packages/twenty-website/public/images/user-guide/home/custom-objects.png b/packages/twenty-website/public/images/user-guide/home/custom-objects.png new file mode 100644 index 0000000000000000000000000000000000000000..24ffedeefa13ea90ec055b3dc5726ccb46d4e413 GIT binary patch literal 27216 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 literal 0 HcmV?d00001 diff --git a/packages/twenty-website/public/images/user-guide/home/what-is-twenty.png b/packages/twenty-website/public/images/user-guide/home/what-is-twenty.png new file mode 100644 index 0000000000000000000000000000000000000000..4ae3d7bb195b4bf30fe834eb60dc93ddd72cbd10 GIT binary patch literal 16600 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 Q;4_G#oT_ZG^s9jX1C1G%W&i*H literal 0 HcmV?d00001 diff --git a/packages/twenty-website/src/app/components/Breadcrumbs.tsx b/packages/twenty-website/src/app/components/Breadcrumbs.tsx index 045dbd7be..0e7ebadc3 100644 --- a/packages/twenty-website/src/app/components/Breadcrumbs.tsx +++ b/packages/twenty-website/src/app/components/Breadcrumbs.tsx @@ -1,16 +1,25 @@ +'use client'; + import React from 'react'; import styled from '@emotion/styled'; +import { IconChevronLeft } from '@tabler/icons-react'; import Link from 'next/link'; +import { Theme } from '@/app/ui/theme/theme'; +import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType'; + const Container = styled.div` display: flex; - gap: 8px; + gap: ${Theme.spacing(2)}; color: #b3b3b3; `; const InternalLinkItem = styled(Link)` text-decoration: none; color: #b3b3b3; + &:hover { + color: ${Theme.text.color.quarternary}; + } `; const ExternalLinkItem = styled.a` @@ -19,7 +28,26 @@ const ExternalLinkItem = styled.a` `; const ActivePage = styled.span` - color: #818181; + color: ${Theme.text.color.secondary}; + font-weight: ${Theme.font.weight.medium}; +`; + +const StyledSection = styled.div` + font-size: ${Theme.font.size.sm}; + font-weight: ${Theme.font.weight.medium}; + color: ${Theme.text.color.quarternary}; + display: flex; + flex-direction: row; + gap: ${Theme.spacing(2)}; +`; + +const StyledMobileContainer = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: ${Theme.spacing(1)}; + color: ${Theme.text.color.quarternary}; + font-size: ${Theme.font.size.sm}; `; interface BreadcrumbsProps { @@ -37,17 +65,29 @@ export const Breadcrumbs = ({ activePage, separator, }: BreadcrumbsProps) => { + const isMobile = useDeviceType() === DeviceType.MOBILE; + if (isMobile) { + const lastItem = items[items.length - 1]; + return ( + + + + {lastItem.label} + + + ); + } return ( {items.map((item, index) => ( - + {item.isExternal ? ( {item.label} ) : ( {item.label} )} - {separator} - +
{separator}
+ ))} {activePage}
diff --git a/packages/twenty-website/src/app/components/user-guide/UserGuideCard.tsx b/packages/twenty-website/src/app/components/user-guide/UserGuideCard.tsx new file mode 100644 index 000000000..791e0d927 --- /dev/null +++ b/packages/twenty-website/src/app/components/user-guide/UserGuideCard.tsx @@ -0,0 +1,48 @@ +'use client'; +import styled from '@emotion/styled'; +import { useRouter } from 'next/navigation'; + +import { Theme } from '@/app/ui/theme/theme'; +import { UserGuideHomeCardsType } from '@/app/user-guide/constants/UserGuideHomeCards'; + +const StyledContainer = styled.div` + color: ${Theme.border.color.plain}; + border: 2px solid ${Theme.border.color.plain}; + border-radius: ${Theme.border.radius.md}; + padding: ${Theme.spacing(6)}; + gap: ${Theme.spacing(4)}; + display: flex; + flex-direction: column; + cursor: pointer; + width: 348px; +`; + +const StyledHeading = styled.div` + font-size: ${Theme.font.size.lg}; + color: ${Theme.text.color.primary}; +`; + +const StyledSubHeading = styled.div` + font-size: ${Theme.font.size.sm}; + color: ${Theme.text.color.secondary}; + font-family: ${Theme.font.family}; +`; + +const StyledImage = styled.img` + width: 300px; +`; + +export default function UserGuideCard({ + card, +}: { + card: UserGuideHomeCardsType; +}) { + const router = useRouter(); + return ( + router.push(`/user-guide/${card.url}`)}> + + {card.title} + {card.subtitle} + + ); +} diff --git a/packages/twenty-website/src/app/components/user-guide/UserGuideContent.tsx b/packages/twenty-website/src/app/components/user-guide/UserGuideContent.tsx new file mode 100644 index 000000000..71cce0ded --- /dev/null +++ b/packages/twenty-website/src/app/components/user-guide/UserGuideContent.tsx @@ -0,0 +1,106 @@ +'use client'; +import React from 'react'; +import styled from '@emotion/styled'; + +import { Breadcrumbs } from '@/app/components/Breadcrumbs'; +import { FileContent } from '@/app/get-posts'; +import { Theme } from '@/app/ui/theme/theme'; +import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType'; + +const StyledContainer = styled.div<{ devicetype: string }>` + width: ${({ devicetype }) => + devicetype === DeviceType.TABLET + ? '70%' + : devicetype === DeviceType.DESKTOP + ? '60%' + : '100%'}; + display: flex; + flex-direction: row; + justify-content: center; + font-family: ${Theme.font.family}; + border-bottom: 1px solid ${Theme.background.transparent.medium}; +`; + +const StyledWrapper = styled.div` + width: 79.3%; + padding: ${Theme.spacing(10)} 0px ${Theme.spacing(20)} 0px; +`; + +const StyledHeader = styled.div` + display: flex; + flex-direction: column; + gap: ${Theme.spacing(8)}; +`; + +const StyledHeading = styled.div` + font-size: 40px; + font-weight: 700; +`; + +const StyledHeaderInfoSection = styled.div` + display: flex; + flex-direction: column; + gap: ${Theme.spacing(4)}; +`; + +const StyledHeaderInfoSectionTitle = styled.div` + font-size: ${Theme.font.size.sm}; + padding: ${Theme.spacing(2)} 0px; + color: ${Theme.text.color.secondary}; + font-weight: ${Theme.font.weight.medium}; +`; + +const StyledHeaderInfoSectionSub = styled.div` + display: flex; + flex-direction: column; + gap: ${Theme.spacing(4)}; + color: ${Theme.text.color.tertiary}; + font-family: ${Theme.font.family}; +`; + +const StyledRectangle = styled.div` + width: 100%; + height: 1px; + background: ${Theme.background.transparent.medium}; +`; + +export default function UserGuideContent({ item }: { item: FileContent }) { + const BREADCRUMB_ITEMS = [ + { + uri: '/user-guide', + label: 'User Guide', + }, + ]; + const deviceType = useDeviceType(); + return ( + + + + + {item.itemInfo.title} + {item.itemInfo.image && ( + {item.itemInfo.title} + )} + + + In this article + + + {item.itemInfo.info} + + + + +
{item.content}
+
+
+ ); +} diff --git a/packages/twenty-website/src/app/components/user-guide/UserGuideMain.tsx b/packages/twenty-website/src/app/components/user-guide/UserGuideMain.tsx new file mode 100644 index 000000000..cf416f6b2 --- /dev/null +++ b/packages/twenty-website/src/app/components/user-guide/UserGuideMain.tsx @@ -0,0 +1,90 @@ +'use client'; +import styled from '@emotion/styled'; + +import UserGuideCard from '@/app/components/user-guide/UserGuideCard'; +import { Theme } from '@/app/ui/theme/theme'; +import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType'; +import { UserGuideHomeCards } from '@/app/user-guide/constants/UserGuideHomeCards'; + +const StyledContainer = styled.div<{ isMobile: boolean }>` + width: ${({ isMobile }) => (isMobile ? '100%' : '60%')}; + display: flex; + flex-direction: row; + justify-content: center; +`; + +const StyledWrapper = styled.div` + width: 79.3%; + padding: ${Theme.spacing(10)} 0px ${Theme.spacing(20)} 0px; + display: flex; + flex-direction: column; + gap: ${Theme.spacing(8)}; +`; + +const StyledHeader = styled.div` + display: flex; + flex-direction: column; + gap: 0px; +`; + +const StyledHeading = styled.h1` + line-height: 38px; + font-weight: 700; + font-size: 38px; + color: ${Theme.text.color.primary}; + margin: 0px; +`; + +const StyledSubHeading = styled.h1` + line-height: 12px; + font-family: ${Theme.font.family}; + font-size: ${Theme.font.size.sm}; + font-weight: ${Theme.font.weight.regular}; + color: ${Theme.text.color.tertiary}; +`; + +const StyledContentGrid = styled.div` + width: 100%; + padding-top: ${Theme.spacing(6)}; + display: grid; + grid-template-rows: auto auto; + grid-template-columns: auto auto; + gap: ${Theme.spacing(6)}; +`; + +const StyledContentFlex = styled.div` + width: 100%; + padding-top: ${Theme.spacing(6)}; + display: flex; + flex-direction: column; + gap: ${Theme.spacing(6)}; +`; + +export default function UserGuideMain() { + const deviceType = useDeviceType(); + return ( + + + + User Guide + + A brief guide to grasp the basics of Twenty + + + {deviceType === DeviceType.DESKTOP ? ( + + {UserGuideHomeCards.map((card) => { + return ; + })} + + ) : ( + + {UserGuideHomeCards.map((card) => { + return ; + })} + + )} + + + ); +} diff --git a/packages/twenty-website/src/app/components/user-guide/UserGuideSidebar.tsx b/packages/twenty-website/src/app/components/user-guide/UserGuideSidebar.tsx new file mode 100644 index 000000000..de419eb85 --- /dev/null +++ b/packages/twenty-website/src/app/components/user-guide/UserGuideSidebar.tsx @@ -0,0 +1,77 @@ +'use client'; + +import styled from '@emotion/styled'; +import { useRouter } from 'next/navigation'; + +import UserGuideSidebarSection from '@/app/components/user-guide/UserGuideSidebarSection'; +import { IconBook } from '@/app/ui/icons'; +import { Theme } from '@/app/ui/theme/theme'; +import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType'; +import { UserGuideIndex } from '@/app/user-guide/constants/UserGuideIndex'; + +const StyledContainer = styled.div<{ isTablet: boolean }>` + width: ${({ isTablet }) => (isTablet ? '30%' : '20%')}; + background: ${Theme.background.secondary}; + display: flex; + flex-direction: column; + border-right: 1px solid ${Theme.background.transparent.medium}; + border-bottom: 1px solid ${Theme.background.transparent.medium}; + padding: ${Theme.spacing(10)} ${Theme.spacing(3)}; + gap: ${Theme.spacing(6)}; +`; + +const StyledHeading = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: ${Theme.spacing(2)}; + font-size: ${Theme.font.size.sm}; + font-weight: ${Theme.font.weight.medium}; +`; + +const StyledIconContainer = styled.div` + width: 24px; + height: 24px; + display: flex; + flex-direction: row; + justify-content: center; + font-size: ${Theme.font.size.sm}; + font-weight: ${Theme.font.weight.medium}; + color: ${Theme.text.color.secondary}; + border: 1px solid ${Theme.text.color.secondary}; + border-radius: ${Theme.border.radius.sm}; + padding: ${Theme.spacing(1)} ${Theme.spacing(1)} ${Theme.spacing(1)} + ${Theme.spacing(1)}; +`; + +const StyledHeadingText = styled.div` + cursor: pointer; + font-size: ${Theme.font.size.sm}; + font-weight: ${Theme.font.weight.medium}; +`; + +const UserGuideSidebar = () => { + const router = useRouter(); + const isTablet = useDeviceType() === DeviceType.TABLET; + return ( + + + + + + router.push('/user-guide')}> + User Guide + + + {Object.entries(UserGuideIndex).map(([heading, subtopics]) => ( + + ))} + + ); +}; + +export default UserGuideSidebar; diff --git a/packages/twenty-website/src/app/components/user-guide/UserGuideSidebarSection.tsx b/packages/twenty-website/src/app/components/user-guide/UserGuideSidebarSection.tsx new file mode 100644 index 000000000..a098bf07b --- /dev/null +++ b/packages/twenty-website/src/app/components/user-guide/UserGuideSidebarSection.tsx @@ -0,0 +1,114 @@ +'use client'; + +import { useState } from 'react'; +import styled from '@emotion/styled'; +import { useRouter } from 'next/navigation'; +import { usePathname } from 'next/navigation'; + +import { IconChevronDown, IconChevronRight } from '@/app/ui/icons'; +import { Theme } from '@/app/ui/theme/theme'; +import { IndexSubtopic } from '@/app/user-guide/constants/UserGuideIndex'; + +const StyledContainer = styled.div` + display: flex; + flex-direction: column; +`; + +const StyledTitle = styled.div` + cursor: pointer; + display: flex; + flex-direction: row; + align-items: center; + gap: ${Theme.spacing(2)}; + color: ${Theme.text.color.quarternary}; + padding-bottom: ${Theme.spacing(2)}; + font-family: ${Theme.font.family}; + font-size: ${Theme.font.size.xs}; +`; + +const StyledSubTopicItem = styled.div<{ isselected: boolean }>` + cursor: pointer; + display: flex; + flex-direction: row; + align-items: center; + height: ${Theme.spacing(8)}; + color: ${(props) => + props.isselected ? Theme.text.color.primary : Theme.text.color.secondary}; + font-weight: ${(props) => + props.isselected ? Theme.font.weight.medium : Theme.font.weight.regular}; + font-family: ${Theme.font.family}; + font-size: ${Theme.font.size.xs}; + gap: 19px; + padding: ${(props) => + props.isselected ? '6px 12px 6px 11px' : '0px 12px 0px 11px'}; + background: ${(props) => + props.isselected + ? Theme.background.transparent.light + : Theme.background.secondary}; + border-radius: ${Theme.border.radius.md}; + text-decoration: none; + &:focus, + &:hover, + &:visited, + &:link, + &:active { + text-decoration: none; + } +`; + +const StyledIcon = styled.div` + padding: 0px 4px 0px 4px; +`; + +const StyledRectangle = styled.div<{ isselected: boolean }>` + height: 100%; + width: 2px; + background: ${(props) => + props.isselected + ? Theme.border.color.plain + : Theme.background.transparent.light}; +`; + +const UserGuideSidebarSection = ({ + title, + subTopics, +}: { + title: string; + subTopics: IndexSubtopic[]; +}) => { + const [isUnfolded, setUnfoldedState] = useState(true); + const pathname = usePathname(); + const router = useRouter(); + return ( + + setUnfoldedState(!isUnfolded)}> + {isUnfolded ? ( + + + + ) : ( + + + + )} +
{title}
+
+ {isUnfolded && + subTopics.map((subtopic, index) => { + const isselected = pathname === `/user-guide/${subtopic.url}`; + return ( + router.push(`/user-guide/${subtopic.url}`)} + > + + {subtopic.title} + + ); + })} +
+ ); +}; + +export default UserGuideSidebarSection; diff --git a/packages/twenty-website/src/app/components/user-guide/UserGuideTableContents.tsx b/packages/twenty-website/src/app/components/user-guide/UserGuideTableContents.tsx new file mode 100644 index 000000000..ba5e2315b --- /dev/null +++ b/packages/twenty-website/src/app/components/user-guide/UserGuideTableContents.tsx @@ -0,0 +1,41 @@ +'use client'; + +import styled from '@emotion/styled'; +import { useRouter } from 'next/navigation'; + +import { Theme } from '@/app/ui/theme/theme'; + +const StyledContainer = styled.div` + width: 20%; + background: ${Theme.background.secondary}; + display: flex; + flex-direction: column; + border-left: 1px solid ${Theme.background.transparent.medium}; + border-bottom: 1px solid ${Theme.background.transparent.medium}; + padding: ${Theme.spacing(10)} ${Theme.spacing(6)}; + gap: ${Theme.spacing(6)}; +`; + +const StyledContent = styled.div` + position: fixed; +`; + +const StyledHeadingText = styled.div` + font-size: ${Theme.font.size.sm}; + color: ${Theme.text.color.quarternary}; +`; + +const UserGuideTableContents = () => { + const router = useRouter(); + return ( + + + router.push('/user-guide')}> + Table of Contents + + + + ); +}; + +export default UserGuideTableContents; diff --git a/packages/twenty-website/src/app/components/user-guide/UserGuideTocComponent.tsx b/packages/twenty-website/src/app/components/user-guide/UserGuideTocComponent.tsx new file mode 100644 index 000000000..28160311c --- /dev/null +++ b/packages/twenty-website/src/app/components/user-guide/UserGuideTocComponent.tsx @@ -0,0 +1,21 @@ +interface Heading { + id: string; + value: string; +} + +const UserGuideTocComponent = ({ headings }: { headings: Heading[] }) => { + return ( +
+ ); +}; + +export default UserGuideTocComponent; diff --git a/packages/twenty-website/src/app/get-posts.tsx b/packages/twenty-website/src/app/get-posts.tsx index 4141c0ca9..135ad64fa 100644 --- a/packages/twenty-website/src/app/get-posts.tsx +++ b/packages/twenty-website/src/app/get-posts.tsx @@ -1,5 +1,5 @@ import { ReactElement } from 'react'; -import rehypeToc from '@jsdevtools/rehype-toc'; +import { toc } from '@jsdevtools/rehype-toc'; import fs from 'fs'; import { compileMDX } from 'next-mdx-remote/rsc'; import path from 'path'; @@ -12,6 +12,8 @@ interface ItemInfo { path: string; type: 'file' | 'directory'; icon?: string; + info?: string; + image?: string; } export interface FileContent { @@ -99,14 +101,13 @@ async function parseFrontMatterAndCategory( export async function compileMDXFile(filePath: string, addToc: boolean = true) { const fileContent = fs.readFileSync(filePath, 'utf8'); - const compiled = await compileMDX<{ title: string; position?: number }>({ source: fileContent, options: { parseFrontmatter: true, mdxOptions: { remarkPlugins: [gfm], - rehypePlugins: [rehypeSlug, ...(addToc ? [rehypeToc] : [])], + rehypePlugins: [rehypeSlug, ...(addToc ? [toc] : [])], }, }, }); @@ -121,21 +122,19 @@ export async function getPosts(basePath: string): Promise { } export async function getPost( - slug: string[], + slug: string, basePath: string, ): Promise { const postsDirectory = path.join(process.cwd(), basePath); - const modifiedSlug = slug.join('/'); - const filePath = path.join(postsDirectory, `${modifiedSlug}.mdx`); + const filePath = path.join(postsDirectory, `${slug}.mdx`); if (!fs.existsSync(filePath)) { return null; } - - const { content, frontmatter } = await compileMDXFile(filePath); + const { content, frontmatter } = await compileMDXFile(filePath, true); return { content, - itemInfo: { ...frontmatter, type: 'file', path: modifiedSlug }, + itemInfo: { ...frontmatter, type: 'file', path: slug }, }; } diff --git a/packages/twenty-website/src/app/layout.css b/packages/twenty-website/src/app/layout.css index 9df57cb6e..49c2040c4 100644 --- a/packages/twenty-website/src/app/layout.css +++ b/packages/twenty-website/src/app/layout.css @@ -30,8 +30,24 @@ a { } nav.toc { - width: 200px; + width: 20%; position: fixed; - top: 100px; + top: 125px; right: 0; +} + +nav.toc ol{ + list-style-type: circle; +} + +nav.toc li{ + height: 32px; +} + +nav.toc a{ + color: #141414; + font-family: var(--font-inter); + font-size: 15px; + font-weight: 500; + text-decoration: none; } \ No newline at end of file diff --git a/packages/twenty-website/src/app/layout.tsx b/packages/twenty-website/src/app/layout.tsx index 50383869f..68ae29871 100644 --- a/packages/twenty-website/src/app/layout.tsx +++ b/packages/twenty-website/src/app/layout.tsx @@ -1,5 +1,5 @@ import { Metadata } from 'next'; -import { Gabarito } from 'next/font/google'; +import { Gabarito, Inter } from 'next/font/google'; import { HeaderMobile } from '@/app/components/HeaderMobile'; @@ -16,10 +16,19 @@ export const metadata: Metadata = { }; const gabarito = Gabarito({ - weight: ['400', '500'], + weight: ['400', '500', '600', '700'], subsets: ['latin'], display: 'swap', adjustFontFallback: false, + variable: '--font-gabarito', +}); + +const inter = Inter({ + weight: ['400', '500', '600', '700'], + subsets: ['latin'], + display: 'swap', + adjustFontFallback: false, + variable: '--font-inter', }); export default function RootLayout({ @@ -28,7 +37,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - + diff --git a/packages/twenty-website/src/app/ui/icons/index.ts b/packages/twenty-website/src/app/ui/icons/index.ts new file mode 100644 index 000000000..9ce102922 --- /dev/null +++ b/packages/twenty-website/src/app/ui/icons/index.ts @@ -0,0 +1,7 @@ +export type { TablerIconsProps } from '@tabler/icons-react'; +export { + IconBook, + IconChevronDown, + IconChevronLeft, + IconChevronRight, +} from '@tabler/icons-react'; diff --git a/packages/twenty-website/src/app/ui/theme/background.ts b/packages/twenty-website/src/app/ui/theme/background.ts new file mode 100644 index 000000000..f5597fbff --- /dev/null +++ b/packages/twenty-website/src/app/ui/theme/background.ts @@ -0,0 +1,13 @@ +import { Color, rgba } from './colors'; + +export const Background = { + primary: Color.white, + secondary: Color.gray10, + tertiary: Color.gray20, + transparent: { + strong: rgba(Color.gray60, 0.16), + medium: rgba(Color.gray60, 0.08), + light: rgba(Color.gray60, 0.06), + lighter: rgba(Color.gray60, 0.04), + }, +}; diff --git a/packages/twenty-website/src/app/ui/theme/border.ts b/packages/twenty-website/src/app/ui/theme/border.ts new file mode 100644 index 000000000..84b02f4ae --- /dev/null +++ b/packages/twenty-website/src/app/ui/theme/border.ts @@ -0,0 +1,19 @@ +import { Color } from './colors'; + +const common = { + radius: { + xs: '2px', + sm: '4px', + md: '8px', + xl: '20px', + pill: '999px', + rounded: '100%', + }, +}; + +export const Border = { + color: { + plain: Color.gray60, + }, + ...common, +}; diff --git a/packages/twenty-website/src/app/ui/theme/colors.ts b/packages/twenty-website/src/app/ui/theme/colors.ts new file mode 100644 index 000000000..dac86ad2b --- /dev/null +++ b/packages/twenty-website/src/app/ui/theme/colors.ts @@ -0,0 +1,24 @@ +import hexRgb from 'hex-rgb'; + +export const mainColors = { + white: '#ffffff', +}; + +export const secondaryColors = { + gray60: '#141414', + gray50: '#474747', + gray40: '#818181', + gray30: '#b3b3b3', + gray20: '#f1f1f1', + gray10: '#fafafa', +}; + +export const Color = { + ...mainColors, + ...secondaryColors, +}; + +export const rgba = (hex: string, alpha: number) => { + const rgb = hexRgb(hex, { format: 'array' }).slice(0, -1).join(','); + return `rgba(${rgb},${alpha})`; +}; diff --git a/packages/twenty-website/src/app/ui/theme/font.ts b/packages/twenty-website/src/app/ui/theme/font.ts new file mode 100644 index 000000000..f2628f10e --- /dev/null +++ b/packages/twenty-website/src/app/ui/theme/font.ts @@ -0,0 +1,14 @@ +export const Font = { + size: { + xs: '0.875rem', + sm: '1rem', + base: '1.125rem', + lg: '1.25rem', + xl: '1.5rem', + }, + weight: { + regular: 400, + medium: 500, + }, + family: 'Inter, sans-serif', +}; diff --git a/packages/twenty-website/src/app/ui/theme/icon.ts b/packages/twenty-website/src/app/ui/theme/icon.ts new file mode 100644 index 000000000..ca4170250 --- /dev/null +++ b/packages/twenty-website/src/app/ui/theme/icon.ts @@ -0,0 +1,13 @@ +export const Icon = { + size: { + sm: 14, + md: 16, + lg: 20, + xl: 40, + }, + stroke: { + sm: 1.6, + md: 2, + lg: 2.5, + }, +}; diff --git a/packages/twenty-website/src/app/ui/theme/text.ts b/packages/twenty-website/src/app/ui/theme/text.ts new file mode 100644 index 000000000..05dcf3df6 --- /dev/null +++ b/packages/twenty-website/src/app/ui/theme/text.ts @@ -0,0 +1,22 @@ +import { Color } from './colors'; + +export const Text = { + color: { + primary: Color.gray60, + secondary: Color.gray50, + tertiary: Color.gray40, + quarternary: Color.gray30, + Inverted: Color.white, + }, + lineHeight: { + lg: 1.5, + md: 1.2, + }, + + iconSizeMedium: 16, + iconSizeSmall: 14, + + iconStrikeLight: 1.6, + iconStrikeMedium: 2, + iconStrikeBold: 2.5, +}; diff --git a/packages/twenty-website/src/app/ui/theme/theme.ts b/packages/twenty-website/src/app/ui/theme/theme.ts new file mode 100644 index 000000000..fa4fb9a60 --- /dev/null +++ b/packages/twenty-website/src/app/ui/theme/theme.ts @@ -0,0 +1,18 @@ +import { Background } from '@/app/ui/theme/background'; +import { Border } from '@/app/ui/theme/border'; +import { Color } from '@/app/ui/theme/colors'; +import { Font } from '@/app/ui/theme/font'; +import { Icon } from '@/app/ui/theme/icon'; +import { Text } from '@/app/ui/theme/text'; + +export const Theme = { + color: Color, + border: Border, + background: Background, + text: Text, + spacingMultiplicator: 4, + icon: Icon, + font: Font, + spacing: (...args: number[]) => + args.map((multiplicator) => `${multiplicator * 4}px`).join(' '), +}; diff --git a/packages/twenty-website/src/app/ui/utilities/useDeviceType.ts b/packages/twenty-website/src/app/ui/utilities/useDeviceType.ts new file mode 100644 index 000000000..d60821189 --- /dev/null +++ b/packages/twenty-website/src/app/ui/utilities/useDeviceType.ts @@ -0,0 +1,22 @@ +import { useMediaQuery } from 'react-responsive'; + +export enum DeviceType { + DESKTOP = 'DESKTOP', + TABLET = 'TABLET', + MOBILE = 'MOBILE', +} + +export const useDeviceType = () => { + const isTablet = useMediaQuery({ + query: '(max-width: 1199px) and (min-width: 810px)', + }); + const isMobile = useMediaQuery({ query: '(max-width: 809px)' }); + + if (isMobile) { + return DeviceType.MOBILE; + } + if (isTablet) { + return DeviceType.TABLET; + } + return DeviceType.DESKTOP; +}; diff --git a/packages/twenty-website/src/app/user-guide/[[...slug]]/layout.tsx b/packages/twenty-website/src/app/user-guide/[[...slug]]/layout.tsx deleted file mode 100644 index 27cbeb49d..000000000 --- a/packages/twenty-website/src/app/user-guide/[[...slug]]/layout.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { FunctionComponent } from 'react'; -import * as TablerIcons from '@tabler/icons-react'; -import Link from 'next/link'; - -import { ContentContainer } from '@/app/components/ContentContainer'; -import { Directory, FileContent, getPosts } from '@/app/get-posts'; - -function loadIcon(iconName?: string) { - const name = iconName ? iconName : 'IconCategory'; - - try { - const icon = TablerIcons[ - name as keyof typeof TablerIcons - ] as FunctionComponent; - return icon as TablerIcons.Icon; - } catch (error) { - console.error('Icon not found:', iconName); - return null; - } -} - -const DirectoryItem = ({ - name, - item, -}: { - name: string; - item: Directory | FileContent; -}) => { - if ('content' in item) { - // If the item is a file, we render a link. - const Icon = loadIcon(item.itemInfo.icon); - - return ( -
- - {Icon ? : ''} - {item.itemInfo.title} - -
- ); - } else { - // If the item is a directory, we render the title and the items in the directory. - return ( -
-

- {item.itemInfo.title} -

- {Object.entries(item).map(([childName, childItem]) => { - if (childName !== 'itemInfo') { - return ( - - ); - } - })} -
- ); - } -}; - -export default async function UserGuideHome({ - children, -}: { - children: React.ReactNode; -}) { - const basePath = '/src/content/user-guide'; - - const posts = await getPosts(basePath); - - return ( - -
-
- {posts['home.mdx'] && ( - - )} - {Object.entries(posts).map(([name, item]) => { - if (name !== 'itemInfo' && name != 'home.mdx') { - return ( - - ); - } - })} -
-
- {children} -
-
-
- ); -} diff --git a/packages/twenty-website/src/app/user-guide/[[...slug]]/page.tsx b/packages/twenty-website/src/app/user-guide/[[...slug]]/page.tsx deleted file mode 100644 index af01ca094..000000000 --- a/packages/twenty-website/src/app/user-guide/[[...slug]]/page.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { getPost } from '@/app/get-posts'; - -export default async function UserGuideHome({ - params, -}: { - params: { slug: string[] }; -}) { - const basePath = '/src/content/user-guide'; - - const mainPost = await getPost( - params.slug && params.slug.length ? params.slug : ['home'], - basePath, - ); - - return ( -
-

{mainPost?.itemInfo.title}

-
{mainPost?.content}
-
- ); -} diff --git a/packages/twenty-website/src/app/user-guide/[slug]/page.tsx b/packages/twenty-website/src/app/user-guide/[slug]/page.tsx new file mode 100644 index 000000000..b796d56db --- /dev/null +++ b/packages/twenty-website/src/app/user-guide/[slug]/page.tsx @@ -0,0 +1,16 @@ +import UserGuideContent from '@/app/components/user-guide/UserGuideContent'; +import { getPost } from '@/app/get-posts'; + +export default async function UserGuideSlug({ + params, +}: { + params: { slug: string }; +}) { + const basePath = '/src/content/user-guide'; + + const mainPost = await getPost( + params.slug && params.slug.length ? params.slug : 'home', + basePath, + ); + return mainPost && ; +} diff --git a/packages/twenty-website/src/app/user-guide/constants/UserGuideHomeCards.ts b/packages/twenty-website/src/app/user-guide/constants/UserGuideHomeCards.ts new file mode 100644 index 000000000..7ee950904 --- /dev/null +++ b/packages/twenty-website/src/app/user-guide/constants/UserGuideHomeCards.ts @@ -0,0 +1,34 @@ +export type UserGuideHomeCardsType = { + url: string; + title: string; + subtitle: string; + image: string; +}; + +export const UserGuideHomeCards: UserGuideHomeCardsType[] = [ + { + url: 'what-is-twenty', + title: 'What is Twenty', + subtitle: + "A brief on Twenty's commitment to reshaping CRM with Open Source", + image: '/images/user-guide/home/what-is-twenty.png', + }, + { + url: 'create-a-workspace', + title: 'Create a Workspace', + subtitle: 'Custom objects store unique info in workspaces.', + image: '/images/user-guide/home/create-a-workspace.png', + }, + { + url: 'import-your-data', + title: 'Import your data', + subtitle: 'Easily create a note to keep track of important information.', + image: '/images/user-guide/home/import-your-data.png', + }, + { + url: 'custom-objects', + title: 'Custom Objects', + subtitle: 'Custom objects store unique info in workspaces.', + image: '/images/user-guide/home/custom-objects.png', + }, +]; diff --git a/packages/twenty-website/src/app/user-guide/constants/UserGuideIndex.ts b/packages/twenty-website/src/app/user-guide/constants/UserGuideIndex.ts new file mode 100644 index 000000000..e9a09b1a9 --- /dev/null +++ b/packages/twenty-website/src/app/user-guide/constants/UserGuideIndex.ts @@ -0,0 +1,29 @@ +export type IndexSubtopic = { + title: string; + url: string; +}; + +export type IndexHeading = { + [heading: string]: IndexSubtopic[]; +}; + +export const UserGuideIndex = { + 'Getting Started': [ + { title: 'What is Twenty', url: 'what-is-twenty' }, + { title: 'Create a Workspace', url: 'create-a-workspace' }, + { title: 'Import your data', url: 'import-your-data' }, + ], + Objects: [ + { title: 'People', url: 'people' }, + { title: 'Companies', url: 'companies' }, + { title: 'Opportunities', url: 'opportunities' }, + { title: 'Custom Objects', url: 'custom-objects' }, + { title: 'Remote Objects', url: 'remote-objects' }, + ], + Functions: [ + { title: 'Email', url: 'email' }, + { title: 'Calendar', url: 'calendar' }, + { title: 'Notes', url: 'notes' }, + { title: 'Tasks', url: 'tasks' }, + ], +}; diff --git a/packages/twenty-website/src/app/user-guide/layout.tsx b/packages/twenty-website/src/app/user-guide/layout.tsx new file mode 100644 index 000000000..1e799e7e7 --- /dev/null +++ b/packages/twenty-website/src/app/user-guide/layout.tsx @@ -0,0 +1,40 @@ +'use client'; +import { ReactNode } from 'react'; +import styled from '@emotion/styled'; +import { usePathname } from 'next/navigation'; + +import UserGuideSidebar from '@/app/components/user-guide/UserGuideSidebar'; +import UserGuideTableContents from '@/app/components/user-guide/UserGuideTableContents'; +import { Theme } from '@/app/ui/theme/theme'; +import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType'; + +const StyledContainer = styled.div` + width: 100%; + display: flex; + flex-direction: row; + justify-content: space-between: + border-bottom: 1px solid ${Theme.background.transparent.medium}; +`; + +const StyledEmptySideBar = styled.div` + width: 20%; +`; + +export default function UserGuideLayout({ children }: { children: ReactNode }) { + const pathname = usePathname(); + const deviceType = useDeviceType(); + + return ( + + {deviceType !== DeviceType.MOBILE && } + {children} + {deviceType !== DeviceType.DESKTOP ? ( + <> + ) : pathname === '/user-guide' ? ( + + ) : ( + + )} + + ); +} diff --git a/packages/twenty-website/src/app/user-guide/page.tsx b/packages/twenty-website/src/app/user-guide/page.tsx new file mode 100644 index 000000000..5e4a71120 --- /dev/null +++ b/packages/twenty-website/src/app/user-guide/page.tsx @@ -0,0 +1,5 @@ +import UserGuideMain from '@/app/components/user-guide/UserGuideMain'; + +export default async function UserGuideHome() { + return ; +} diff --git a/packages/twenty-website/src/content/user-guide/home.mdx b/packages/twenty-website/src/content/user-guide/home.mdx index 7d99476b2..4f6d0865d 100644 --- a/packages/twenty-website/src/content/user-guide/home.mdx +++ b/packages/twenty-website/src/content/user-guide/home.mdx @@ -2,6 +2,7 @@ title: Get started position: 0 icon: IconUsers +info: This is homepage --- The purpose of this user guide is to help you learn how you can use Twenty to build the CRM you want. diff --git a/packages/twenty-website/src/content/user-guide/what-is-twenty.mdx b/packages/twenty-website/src/content/user-guide/what-is-twenty.mdx new file mode 100644 index 000000000..022dda1e5 --- /dev/null +++ b/packages/twenty-website/src/content/user-guide/what-is-twenty.mdx @@ -0,0 +1,57 @@ +--- +title: What is Twenty +position: 0 +icon: IconUsers +info: A brief on Twenty's commitment to reshaping CRM with Open Source +image: /images/user-guide/home/what-is-twenty.png +--- + +## What is Twenty + +The purpose of this user guide is to help you learn how you can use Twenty to build the CRM you want. + +## Quick Search + +You'll see a search bar at the top of your sidebar. You can also bring up the command bar with the `cmd`/`ctrl` + `k` shortcut to navigate through your workspace, and find people, companies, notes, and more. + +The command bar also supports other shortcuts for navigation. + +## Create Pre-filtered Views + +Twenty allows you to add filters to see data that meets certain criteria and hides the rest. You can apply multiple filters at once. + +To create a filter in your workspace, click Filter at the top right and select the attribute you'd like to filter your records by. Create your filter and then save changes in a new view by clicking `+ Create view`. + +The filtered view is now available to your whole team. + +## Add Stages For Opportunities + +You can also add more stages to the opportunities board. + +On the Opportunities page, click on Options, Stages, then `+ Add Stage`. + +You can also edit the stage by clicking on the name. + +## Create Notes and Tasks For Each Record + +You can attach notes and tasks to each record. With Notes, you can keep a record of any observations, comments, and interactions, and keep track of all items that require action with Tasks. + +There are multiple ways to create notes and tasks. Learn more about [Notes](./basics/notes.mdx) and [Tasks](./basics/tasks.mdx). + +## Upload Files For Each Record + +You can also upload and attach files for each record. To do so, expand a record, and head over to the Files tab. You'll then see the `+ Add file` button. + + + +## Add Records To Favorites + +You can add records to your favorites for quick access. To do so, expand the record you want to add, and click on the heart icon on the top right. You'll now be able to see your favorite records in your sidebar right above your workspace. + + + +## Import data + +You can easily import People and Companies data into Twenty from other apps using a .csv, .xslx, or .xsl file. In the Companies or People page, click on Options and then on Import. + +Upload your file, match the columns, and validate the data to import it. \ No newline at end of file