From 135a9aa031307630fcfebb7294666923991ea0cf Mon Sep 17 00:00:00 2001 From: sosokker Date: Thu, 23 Nov 2023 03:03:19 +0700 Subject: [PATCH 1/4] Refactor according to ESlint --- frontend/.eslintrc.cjs | 1 + frontend/src/App.jsx | 33 +++-- frontend/src/PrivateRoute.jsx | 4 +- frontend/src/PublicRoute.jsx | 4 +- frontend/src/api/AuthenticationApi.jsx | 31 +---- frontend/src/api/AxiosConfig.jsx | 4 +- frontend/src/api/TaskApi.jsx | 2 +- frontend/src/assets/calendar.png | Bin 6785 -> 0 bytes frontend/src/assets/home.png | Bin 6259 -> 0 bytes frontend/src/assets/pie-chart.png | Bin 12169 -> 0 bytes frontend/src/assets/planning.png | Bin 19124 -> 0 bytes frontend/src/assets/plus.png | Bin 9855 -> 0 bytes frontend/src/assets/react.svg | 1 - .../EisenhowerMatrix/Eisenhower.jsx | 8 +- .../components/authentication/LoginPage.jsx | 34 ++---- .../components/authentication/SignUpPage.jsx | 50 +++----- .../authentication/refreshAcessToken.jsx | 39 ------ .../components/calendar/TaskDataHandler.jsx | 6 +- frontend/src/components/calendar/calendar.jsx | 4 +- .../src/components/dashboard/Areachart.jsx | 2 +- .../src/components/dashboard/Barchart.jsx | 2 +- .../src/components/dashboard/DonutChart.jsx | 4 +- frontend/src/components/dashboard/KpiCard.jsx | 4 +- .../components/dashboard/ProgressCircle.jsx | 4 +- .../src/components/dashboard/dashboard.jsx | 8 +- .../kanbanBoard/columnContainer.jsx | 14 +-- .../kanbanBoard/columnContainerWrapper.jsx | 6 +- .../components/kanbanBoard/kanbanBoard.jsx | 75 +----------- .../src/components/kanbanBoard/kanbanPage.jsx | 19 ++- .../src/components/kanbanBoard/taskCard.jsx | 7 +- .../kanbanBoard/taskDetailModal.jsx | 13 +- .../components/navigations/IconSideNav.jsx | 18 +-- .../src/components/navigations/Navbar.jsx | 8 +- .../{ => profile}/ProfileUpdateComponent.jsx | 16 ++- .../components/{ => profile}/profilePage.jsx | 38 +++--- frontend/src/components/signup.jsx | 115 ------------------ frontend/src/components/signup/Signup.jsx | 4 +- frontend/src/components/testAuth.jsx | 47 ------- frontend/src/main.jsx | 2 +- frontend/tailwind.config.js | 17 +-- 40 files changed, 133 insertions(+), 511 deletions(-) delete mode 100644 frontend/src/assets/calendar.png delete mode 100644 frontend/src/assets/home.png delete mode 100644 frontend/src/assets/pie-chart.png delete mode 100644 frontend/src/assets/planning.png delete mode 100644 frontend/src/assets/plus.png delete mode 100644 frontend/src/assets/react.svg delete mode 100644 frontend/src/components/authentication/refreshAcessToken.jsx rename frontend/src/components/{ => profile}/ProfileUpdateComponent.jsx (88%) rename frontend/src/components/{ => profile}/profilePage.jsx (82%) delete mode 100644 frontend/src/components/signup.jsx delete mode 100644 frontend/src/components/testAuth.jsx diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index 1a8aa39..809eec3 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -13,5 +13,6 @@ module.exports = { plugins: ["react-refresh"], rules: { "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], + "react/prop-types": 0, }, }; diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 1ab242f..619149d 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,21 +1,19 @@ -import { useEffect } from "react"; import "./App.css"; -import { Route, Routes, Navigate } from "react-router-dom"; import axios from "axios"; -import TestAuth from "./components/testAuth"; -import LoginPage from "./components/authentication/LoginPage"; -import SignUpPage from "./components/authentication/SignUpPage"; -import NavBar from "./components/navigations/Navbar"; -import Calendar from "./components/calendar/calendar"; -import KanbanPage from "./components/kanbanBoard/kanbanPage"; -import IconSideNav from "./components/navigations/IconSideNav"; -import Eisenhower from "./components/EisenhowerMatrix/Eisenhower"; -import PrivateRoute from "./PrivateRoute"; -import ProfileUpdatePage from "./components/profilePage"; -import Dashboard from "./components/dashboard/dashboard"; +import { useEffect } from "react"; +import { Route, Routes, Navigate } from "react-router-dom"; +import { LoginPage } from "./components/authentication/LoginPage"; +import { SignUp } from "./components/authentication/SignUpPage"; +import { NavBar } from "./components/navigations/Navbar"; +import { Calendar } from "./components/calendar/calendar"; +import { KanbanPage } from "./components/kanbanBoard/kanbanPage"; +import { SideNav } from "./components/navigations/IconSideNav"; +import { Eisenhower } from "./components/EisenhowerMatrix/Eisenhower"; +import { PrivateRoute } from "./PrivateRoute"; +import { ProfileUpdatePage } from "./components/profile/profilePage"; +import { Dashboard } from "./components/dashboard/dashboard"; import { LandingPage } from "./components/landingPage/LandingPage"; -import PublicRoute from "./PublicRoute"; - +import { PublicRoute } from "./PublicRoute"; import { useAuth } from "./hooks/AuthHooks"; const baseURL = import.meta.env.VITE_BASE_URL; @@ -70,7 +68,7 @@ const NonAuthenticatedComponents = () => { } /> }> - } /> + } /> } /> @@ -81,7 +79,7 @@ const NonAuthenticatedComponents = () => { const AuthenticatedComponents = () => { return (
- +
@@ -90,7 +88,6 @@ const AuthenticatedComponents = () => { }> } /> - } /> }> } /> diff --git a/frontend/src/PrivateRoute.jsx b/frontend/src/PrivateRoute.jsx index 01afc6a..3daa62b 100644 --- a/frontend/src/PrivateRoute.jsx +++ b/frontend/src/PrivateRoute.jsx @@ -1,9 +1,7 @@ import { Navigate, Outlet } from "react-router-dom"; import { useAuth } from "src/hooks/AuthHooks"; -const PrivateRoute = () => { +export const PrivateRoute = () => { const { isAuthenticated } = useAuth(); return isAuthenticated ? : ; }; - -export default PrivateRoute; diff --git a/frontend/src/PublicRoute.jsx b/frontend/src/PublicRoute.jsx index ffdc39c..69f980a 100644 --- a/frontend/src/PublicRoute.jsx +++ b/frontend/src/PublicRoute.jsx @@ -1,9 +1,7 @@ import { Navigate, Outlet } from "react-router-dom"; import { useAuth } from "src/hooks/AuthHooks"; -const PublicRoute = () => { +export const PublicRoute = () => { const { isAuthenticated } = useAuth(); return isAuthenticated ? : ; }; - -export default PublicRoute; diff --git a/frontend/src/api/AuthenticationApi.jsx b/frontend/src/api/AuthenticationApi.jsx index bca81d5..b0a0956 100644 --- a/frontend/src/api/AuthenticationApi.jsx +++ b/frontend/src/api/AuthenticationApi.jsx @@ -1,10 +1,10 @@ import axios from "axios"; -import axiosInstance from "./AxiosConfig"; +import { axiosInstance } from "./AxiosConfig"; const baseURL = import.meta.env.VITE_BASE_URL; // Function for user login -const apiUserLogin = (data) => { +export const apiUserLogin = (data) => { return axiosInstance .post("token/obtain/", data) .then((response) => { @@ -19,14 +19,14 @@ const apiUserLogin = (data) => { }; // Function for user logout -const apiUserLogout = () => { +export const apiUserLogout = () => { axiosInstance.defaults.headers["Authorization"] = ""; // Clear authorization header localStorage.removeItem("access_token"); // Remove access token localStorage.removeItem("refresh_token"); // Remove refresh token }; // Function for Google login -const googleLogin = async (token) => { +export const googleLogin = async (token) => { axios.defaults.withCredentials = true; let res = await axios.post(`${baseURL}auth/google/`, { code: token, @@ -35,20 +35,8 @@ const googleLogin = async (token) => { return await res; }; -// Function to get 'hello' data -const getGreeting = () => { - return axiosInstance - .get("hello") - .then((response) => { - return response; - }) - .catch((error) => { - return error; - }); -}; - // Function to register -const createUser = async (formData) => { +export const createUser = async (formData) => { try { axios.defaults.withCredentials = true; const response = axios.post(`${baseURL}user/create/`, formData); @@ -58,12 +46,3 @@ const createUser = async (formData) => { console.log(e); } }; - -// Export the functions and Axios instance -export default { - apiUserLogin, - apiUserLogout, - getGreeting: getGreeting, - googleLogin, - createUser, -}; diff --git a/frontend/src/api/AxiosConfig.jsx b/frontend/src/api/AxiosConfig.jsx index b037386..f2de1b7 100644 --- a/frontend/src/api/AxiosConfig.jsx +++ b/frontend/src/api/AxiosConfig.jsx @@ -3,7 +3,7 @@ import { redirect } from "react-router-dom"; const baseURL = import.meta.env.VITE_BASE_URL; -const axiosInstance = axios.create({ +export const axiosInstance = axios.create({ baseURL: baseURL, timeout: 5000, headers: { @@ -43,5 +43,3 @@ axiosInstance.interceptors.response.use( return Promise.reject(error); } ); - -export default axiosInstance; diff --git a/frontend/src/api/TaskApi.jsx b/frontend/src/api/TaskApi.jsx index daad9c3..098d934 100644 --- a/frontend/src/api/TaskApi.jsx +++ b/frontend/src/api/TaskApi.jsx @@ -1,4 +1,4 @@ -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; const baseURL = import.meta.env.VITE_BASE_URL; diff --git a/frontend/src/assets/calendar.png b/frontend/src/assets/calendar.png deleted file mode 100644 index 8c30ce33e34f3dfdec02f5f6560bcaf83a901a3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6785 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 diff --git a/frontend/src/assets/home.png b/frontend/src/assets/home.png deleted file mode 100644 index c40c6b2296a5a1ebeaaf9ba657b2357fafb84de0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6259 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 Ef=3;FXaE2J diff --git a/frontend/src/assets/plus.png b/frontend/src/assets/plus.png deleted file mode 100644 index a5252f5137d705f9a1a58f451470598217c3885b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9855 zcmeHti9b|t6!)DOW9*bH*_Vq*M%iV}dP@{4vX&(Kl#!h~lqK0lBx^Axr6@!qw~ZF- zWGmaWVaOI`vc6ZpcljIM_w)LEd}i)>p8GuKo_Wqa-}5~u<%q2nFP9h>006v@wYfb2 zV9~EwfP)?VSPJi5K|k0+4nU3^=wCF)nPl{ulVt520swrkxBf9XyZOXX;ZCxJ6WJm7 zEII7d1#ciMEKJQe$UnsE6vg)RjMnbQhMxUZeYdjCk|yZN9e~K>rYxxa6j0tTse?(h3Eav zw}o)~B@XNX_!8T`@=Yh5@$JDEx{Q2E7Kf%Q=O!Xz?br_dnpJo@-Msqq6!0TR-ZSae zC$2oK0U@uc^Q!d9Ul*QrU8zA@Ii#S~bK3J$_hxMLWZP|IEp)u+Rs=^L_b|7?$cLNv z22996-5H5$?rK7{c(uH`*SRNLhZHKv{MlEK;ak!^{2epMuLdW-%lMlS+SosMck|El zVT9tY&vOig3T7^*p86i?K!Pd$3s+6coPe)^_$GloyaezQXTx(CgnqkVhS^*>T?wx2 z?WsJD`rIaSX?S;@CJ9}hLGjJFOvgJ>a4LlxF3EmqcqF4?VX0MLDVhKG(fO4m{7tD!)3SBAO;+z+|{y+(VKf>Y(HD}&nyBl#ZKcc+B z+|J80Pd+TMBKTstP4wSv`Z8FPGE`b|gD5MCkvl1q)oM=QsMVW?7~(9q7BJ_G6|n3L`da>D8m97g4=e@@5J7YVXGEoZlfld6S6?9_f=2^ zxn+;Ob=9>C?4GLg7YNJ*F#zSVq<@=@Oadr+#`&@-^Dy!*Vg} zl7Kcr8&|BcRMzOVlcdQ!9Dk~m8=0l0$`uP0%7n+ih;A3dP{t=Dln8Om8rf*-7H;7-p%}i5Ho~U0F@|1_QXK5 z6~!QF&&^w(_zS%rCSMtBqV0sEb; zKoVwxI%|1lLx1?1Gt_8NO`K`}?9zR(#EN3~4WCJU|HP0vLR?JQY#hFHga7AX&lT-% z&{KOMRopNPH;30|2IwhNRN1hN+BD|qtxS`bhRsXdcChw*716p7M6ji0rW$}1hrO)r z5}UJGRYO^eb+#gpl}ByXPFr@wAp5QPdo#hhvzg?;UbokAk{S5}VNF+FT$C}4)sB>n zGE9Z-sJ8wP`l3l+dgPn3`t}>L)OlUKRfe>4A$9PBGiM>M%}n%P5Hh<1lxIu%ORa}K zzrMITf06$Dppos`*WVY;;)wUWe}Itu4bFDijp-QT#H+eWSN<6*z2z`9j8Wq9!XbO& zRe}*lRbgW~j(B!w^@%;Z2XNo4>-U-yPZGx?>5G3Apys;WB>9C^ld3=Ys%naxyB1RW zW}Gcn4Ezop_E&`N1xYaDr?(fYufB-Pt&F;eDOQZV)u_jx=}wo2{1RV5RlRAW(v5m{ zn7CsD@qK}r~-A;vuSE4KGPyVbxq`VxQQ`;|7OhkHVl%X85fV)YHNl zo7-AE$RVRAhy41^a5J`j6}cl`!^4{XeEcA_H!xT!W+r{qxN$E(uAr~pv1or0%Yxae z%9eibd=UsWpWn5<%KkYHz0m(RVlgCa>6)#S^(k?b#Wm(*f3Q}-8tO8B(yY!Us-`)SX)8gLg%ng_B zY4}~J8WpVAb|-8Jl{xPNZGDXg_K2G4ACrn< zgmx6MU};F@MJ_UzG8Q(KuSe7PWw>}pO~Sml{SEg9SOE@w^avv~Jskbv+_D!5G}OK6 z-j4Omh`eq^y+(1Pw55zCP37&M>>0w^ap^V$weO=R$bpcze*8v6dWX2bdqImjFieMW z54<)SM{j3=-jg%0=d42850n37~$eTl16FC|6 zIIsIsl^|3mYE{ht#s!M(>G5zHa|5bw-YMt!J*Y$x>X8MZ7#}^7A30f@2TQE_MO?eY z>bDP_Wp8!VvxcZDqGrWDnApK7Ogf=Bz=Uz{WB+A7DtK(({p<3xdo`KDC0C-Ha4(M+ z{Y4ZXNECvQ6xjtuC4-7%goR~J$jm9TxwSP#rwe;%_SvR z<=9yT_2#rUnP7$FM{AKntGT#iw;g{fTK zhG2>wSS3r?y|JeLx_FihUtx!DyxMGS#CvXzdRM$jKrU}R(;Gc$mIFEY%30pc)Zs3m zFoAyq1q7oP7^^+9D*1KKe^1_+%jUDB(m3wJi=}3cOQl+yUg4NQ4H;{t z*zJ-gRL7=aHS;kqT1$lBLb>9}A`9e_{_(A-Y$H>(JmFfe$ja9MzQGfH^-^wOdztYT z5LIpuUM+*~=!=JllamW@@zxt1yw+=r9t;SHQ9l-IVg`5i3&X=kn_U%w5Ou{RD2hH? z{RH?aCQ7^41`m~@w$=PD%t)CO5ce(W zYDf$HUaK<$pd!AlnL$e>a*(~9o3!N3_??+jx1Vt`rCMF3?myF-KSJh!sEMEWSZ3s8 z;Ro#6QlJ*aReRHF3ruNsts`rb0(-=OJN(#>W!a9T5HhfZY;4Ie*F{mbCn>f^DfOEW zHGk^QBp?)E$YFy@UJOqHRPaGta}P!(Zy$$E`u`E3BSJP$0BaQC7Ip$QQf$SNMWyks zL61=UqM+O0n%J?fV{*dKs)R$e?zWO_lRt3#`h|^q`p3kdWh3@$(t76LR5ec z|Bc@6!JO1QB_Jw|F7Z_L9$4Y}^ye{WA)pJ@E?=zxt1c`mhz{*8!&%?>%rPh(u8ihJ z+|@$rzLOU24$%`USfQBwvy6Ye-`6G5Vl|M8p1N} zBkk@e#7~ zZ?Q5zd{umL>CxAg%^6XMHf1MR_YM{Mz_owv()h3eP~)PB{aIDOK6cbxe|>C660Rzh zPqsn~UG91c;!|dJmBIae(R~}_1ki>H%{7ceN-QJUDKs1Ox@qk&8RiWSMi0(|Eo}#{ zFKM^j`79J}ivE@l9-)$OZ!#?WJ@e>xVL(~waO1DImqIp^^$|T_->)50$;F$zH{&bc z92f-k;s0jxm=o^Glvmn6QbkXv5c<%NJ>~y@{lC}_=K{#U@5`p1`qhTj@4D~0Yn0&} zGadR1Ri*M*;Rxj3pzix3yvfXGk#L21drxW4(*Y7%Z&wp7M{3v_gd5m&r5lX2(=VLC z91#+vWW!;&F8)rroB%lz(j6_)fM>NJ1C-n6A6*ly!W`Mn4%Y+AfCq}o{PNu>akyFb zQIi#o-GP~Sld@0gB&HnpD&wae}1@)>CiI8Lo_DJ*K?|!oY)R3q&tG zDY=)}n)#4>aKCDYN&O(wDM)t=HI_T1E-{{8=j_GV{zy0Y7$b7&x2N30P0XB{7_VQujuxz zR&XDRCPMpE7-c=Oy*#MB&kN1}Mjx_q%7&5upMerrr4hreS#R7BLYdiJJyk$#mXi^R zd_*~!KEJ&r1LhxN&T3$ixSqar`LqR^{MR|zu4u$~kp;9;@h0+5Gs%j`>ZRLFhKE0| z#feFpcX(mCR|*LdDZxD17kc|dDAjxk6Wn%_g?wYeKM9U2+WYDJK+0JRY6X#r#tTdze4{X2_^PY z$F2T%bhMW$PDg|4SJdk)eK487=FgzO?818$p$}UTb_=D=rt-=7lF@L@zxei>7hI0= zWM)-kt3vA3QYdGrx zLhq05p2DPk)i?hari*)sb?5rYA1&lG*jn`n(B%%_OWHMG@R<(zU3!GRG($W3%oghr z8++wJ-a&jGmyOs;L@G?6?1w+mPOP{e{<$ZS+8Cf(y{ecrhc*` z?E3tXyPmaC*PN8}RyJ_dCYi6h^tPT5>?(YW>iE$0&%N6T-xu{td;kzSjI!$SY5$?( z6ciQL1_(Gwq0l!Qg}x|^R^AekGs%}pd?;L^-HE!0!nHk;Y*HC0)b2n@LNpsYnX!P> zpn2cqBU45Xin+yPO3o@kDt5L$_a^wUi)9Xu>U*|O`1GR~^!P}1FnIvv>VH`RADShE zYu0N3dV3y%6{>nOM?b}|sT=;Ay;ok}1iwgtf-xW7#Gz*nqDTHjVSIcNJLPGQvdWMN;RA9G>Mz*O4!VA0acM%VVlI=tsa&&-P`!;Lc$}MBnbJo<5Oz_8C4ublvBl%6@ z#+TgJah69z)qZ;J1tGt-uH>=Jd+jPGcd3Sm3Dmx?WV@5`FULQ_?mL$5?CQR2eu4#6a9WDNgj-LsL;>AWZ$bw0->A$E(6=O=O;q>{C+T6 zaopkpPo|oleV5cW{Fj%*HFOr+S{n(Y#D%7C-l4VF6QQx{^cR(L z8dr0TcAv{Df(NWnj^_6RovaCqiJXTsL%C}YNv^!Zkl#6!f$)_e@h_~p_BnF~xc&Bw z8-W=!?JoDF?xJacSV#$_7S{%R+ShCwSq1W5#3Ml(au!S%}r& ziNkfu^EXhyLHijag(fTJ1)a?A9>q41VI*>@ug`I;#(uqU$i9aUY&KVlH1_u?#%j-z zG0#83INz|?3=y`2)O!WM@WC~s{@LiVbPHV?hCqK8UHTu(<@j~E%61&l7d{0q!9|k^ zzG1n*v;IfuZgM{{s`9a0+?f2#h7;{W_csRG2mCyQ z=st2!iS1^{#sAp9kFfDJl>O6>>Tg!}Un|8B2AHmC_3Q_!{bB@H)3uFWreowx@G&bb z1~8pR?EA+u7MZR+cWje5x%`qx2WSsMO#Al+S49M(rKJd^h1H{yA!Z}o8q|6=N!O7Y z9^KOMx-9U=w{xC)|He*t_-mBzr6uv0O9x2SWU9HV%R+vYBd}8P77IEAMTOWE4kqBH z`r2_%s=^{bh*uleP{LX-e;5(?;J(HcQ^r4Lb(k~2VVVo2InM1~nNa=XM-Pp7V9-~8 zysAPrJbPT59w$nrZD`{2%+_KZCYm1i3;Fc`%zLjU6RJWUDy8?C*bSO{EEZe7BnOXS!f< z3gwb#Y$8{WETL5MB0S>nssz~wH^Uo^pW`}IF&F=F)D~YwXyS_?$tG}F%yCnJDS3wFFsp?krL} zlO4e3YPD862Ex`)sGC4nYj_;t@OT0%99px zbxFINDf!?o_#=>=X=;=qxEcDCb8%Np6H$V%QYJR5VBcU;>G zR*y_IVP1-HfIjeWvZ_R{J(#0$lKA+%je;a=3E|N@3Ak!$4q$2^A0Dvc`kk!j%Adps zqLmZ_rNcTy|YjPI9B{hC32MzR&KZyF3a~8nFzS>&{q&|I)6XwYC@fMtMgo z@0l@aJRL{y6rqQ$xLi`0=Fi9)l@4)ngeS28iDTZOiR*bmF*xG>OSGE9$+qz;`P7+R zP};mI-Rym9)@)mxwmN=LbDv|03zq~G*&mmuxC4L(Fk`QkexQ`<&_R0f^7^FA;ZLLq zU>Q?&Q}4Dpm8SoI-Bvc{mH0ztJit(-D^FeDDlAuUkJ?2FACT8Xe?eEX71x!wXqg@C zn|y_cl$r4i)M5c#zWPh@ya;+A7pfAxhTxo9FXS0>DGi zP~ywECiNrKYuEdbRhVc_a4u040bqZ~?qDR|2z!EhEhz^XqM!ihu`F5<&MYQ{DOIq2 z&pd$wwcAJvQeT#ERk7S*ItiHg;+3EPbu8(UBuLJr^xW@`08nff`JwkJLxKwOh7p;1 z+NZkyRH@W=^#$Yq$h*nxLYos@%_8r6XcriNKLN-z_l{dLthQ8qv!7pAG+bBL%KNFi zW4(l~NO(Ru&?HFO8>QW! zlswPCqs9C=b3%oKF={hkxW?%B``*CfVX1AR3Iva~nE%h1My7FV_gSsj4Lwjt$&X2;ZCS3BG$ zM^m2B*xIeD8o;X=jj*!yUaJ{Ny8 zlmJL$(_e&U(-a%GvkaJWEq!R8Nmp8BqakG(rv!XM`%LVaxmlz1FfsN0x`&Rd0y9JL z#bt6Q!7~CTbw1%O$O&3OzW9cjb-Fs9iALAzp6m3`BZ~ zGkzdFwDKc?V&Ya*F&|mdUeY$E$_Byf+mi8CE0Fw%efW+FfuB<7@XKMewTLJ;^0MAQ z+tyhXSSYrLH28r*DsM?EB`Q*BD-UD>Stqb3fa{nHb9R*?v>{0myGlLyLW-ur_6#d1 zX9n5h55X>!0%&=BGj~a@_;%Klhdk3gYWQ^x46r-VGS z&+~I&Oj{Lu4e&i!&i@1ANFO0MB%b}%9q{7wgrGqxIqIvfr+r4vLBC=PTG!|as@iK@ xI9Iqtp0Q>I&pK-tn&3S(tD)5&JyyQSf7y3EH}4a}3T+kxAPZabhX*|4{|7xaN+SRO diff --git a/frontend/src/assets/react.svg b/frontend/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/frontend/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/components/EisenhowerMatrix/Eisenhower.jsx b/frontend/src/components/EisenhowerMatrix/Eisenhower.jsx index 619dca9..cc19aaa 100644 --- a/frontend/src/components/EisenhowerMatrix/Eisenhower.jsx +++ b/frontend/src/components/EisenhowerMatrix/Eisenhower.jsx @@ -1,7 +1,7 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { FiAlertCircle, FiClock, FiXCircle, FiCheckCircle } from "react-icons/fi"; import { readTodoTasks } from "../../api/TaskApi"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; function EachBlog({ name, colorCode, contentList, icon }) { const [tasks, setTasks] = useState(contentList); @@ -55,7 +55,7 @@ function EachBlog({ name, colorCode, contentList, icon }) { ); } -function Eisenhower() { +export function Eisenhower() { const [tasks, setTasks] = useState([]); useEffect(() => { @@ -108,5 +108,3 @@ function Eisenhower() {
); } - -export default Eisenhower; diff --git a/frontend/src/components/authentication/LoginPage.jsx b/frontend/src/components/authentication/LoginPage.jsx index dff40ab..2c3489b 100644 --- a/frontend/src/components/authentication/LoginPage.jsx +++ b/frontend/src/components/authentication/LoginPage.jsx @@ -1,24 +1,16 @@ -import { useEffect, useState } from "react"; import { useNavigate, redirect } from "react-router-dom"; import { useGoogleLogin } from "@react-oauth/google"; -import { useCallback } from "react"; +import { useCallback, useState } from "react"; import Particles from "react-tsparticles"; import { loadFull } from "tsparticles"; -import refreshAccessToken from "./refreshAcessToken"; -import axiosapi from "../../api/AuthenticationApi"; import { FcGoogle } from "react-icons/fc"; import { useAuth } from "src/hooks/AuthHooks"; +import { googleLogin, apiUserLogin } from "src/api/AuthenticationApi"; -function LoginPage() { +export function LoginPage() { const { setIsAuthenticated } = useAuth(); const Navigate = useNavigate(); - useEffect(() => { - if (!refreshAccessToken()) { - Navigate("/"); - } - }, []); - const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); @@ -33,16 +25,14 @@ function LoginPage() { event.preventDefault(); // Send a POST request to the authentication API - axiosapi - .apiUserLogin({ - email: email, - password: password, - }) + apiUserLogin({ + email: email, + password: password, + }) .then((res) => { // On successful login, store tokens and set the authorization header localStorage.setItem("access_token", res.data.access); localStorage.setItem("refresh_token", res.data.refresh); - axiosapi.axiosInstance.defaults.headers["Authorization"] = "Bearer " + res.data.access; setIsAuthenticated(true); redirect("/"); }) @@ -57,7 +47,7 @@ function LoginPage() { redirect_uri: "postmessage", onSuccess: async (response) => { try { - const loginResponse = await axiosapi.googleLogin(response.code); + const loginResponse = await googleLogin(response.code); if (loginResponse && loginResponse.data) { const { access_token, refresh_token } = loginResponse.data; @@ -76,14 +66,9 @@ function LoginPage() { /* Particles Loader*/ } const particlesInit = useCallback(async (engine) => { - console.log(engine); await loadFull(engine); }, []); - const particlesLoaded = useCallback(async (container) => { - console.log(container); - }, []); - return (
{/* Particles Container */} @@ -91,7 +76,6 @@ function LoginPage() { ); } - -export default LoginPage; diff --git a/frontend/src/components/authentication/SignUpPage.jsx b/frontend/src/components/authentication/SignUpPage.jsx index 6bcc8dc..fb6202e 100644 --- a/frontend/src/components/authentication/SignUpPage.jsx +++ b/frontend/src/components/authentication/SignUpPage.jsx @@ -1,21 +1,18 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { useNavigate } from "react-router-dom"; -import axiosapi from "../../api/AuthenticationApi"; import { useCallback } from "react"; import Particles from "react-tsparticles"; import { loadFull } from "tsparticles"; import { FcGoogle } from "react-icons/fc"; import { useGoogleLogin } from "@react-oauth/google"; - +import { useAuth } from "src/hooks/AuthHooks"; +import { createUser, googleLogin } from "src/api/AuthenticationApi"; function Copyright(props) { return (
{"Copyright © "} - + TurTask {" "} {new Date().getFullYear()} @@ -24,8 +21,9 @@ function Copyright(props) { ); } -export default function SignUp() { +export function SignUp() { const Navigate = useNavigate(); + const { setIsAuthenticated } = useAuth; const [formData, setFormData] = useState({ email: "", @@ -41,7 +39,7 @@ export default function SignUp() { setError(null); try { - axiosapi.createUser(formData); + createUser(formData); } catch (error) { console.error("Error creating user:", error); setError("Registration failed. Please try again."); @@ -54,26 +52,20 @@ export default function SignUp() { const handleChange = (e) => { const { name, value } = e.target; setFormData({ ...formData, [name]: value }); - console.log(formData); }; { /* Particles Loader*/ } const particlesInit = useCallback(async (engine) => { - console.log(engine); await loadFull(engine); }, []); - const particlesLoaded = useCallback(async (container) => { - console.log(container); - }, []); - const googleLoginImplicit = useGoogleLogin({ flow: "auth-code", redirect_uri: "postmessage", onSuccess: async (response) => { try { - const loginResponse = await axiosapi.googleLogin(response.code); + const loginResponse = await googleLogin(response.code); if (loginResponse && loginResponse.data) { const { access_token, refresh_token } = loginResponse.data; @@ -91,16 +83,12 @@ export default function SignUp() { }); return ( -
+
{/* Particles Container */}
*

- +
{/* Username Input */}
@@ -225,17 +207,13 @@ export default function SignUp() {
OR
{/* Login with Google Button */} - {/* Already have an account? */}
diff --git a/frontend/src/components/authentication/refreshAcessToken.jsx b/frontend/src/components/authentication/refreshAcessToken.jsx deleted file mode 100644 index e07395b..0000000 --- a/frontend/src/components/authentication/refreshAcessToken.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import axios from "axios"; - -const baseURL = import.meta.env.VITE_BASE_URL; - -async function refreshAccessToken() { - const refresh_token = localStorage.getItem("refresh_token"); - const access_token = localStorage.getItem("access_token"); - - if (access_token) { - return true; - } - - if (!refresh_token) { - return false; - } - - const refreshUrl = `${baseURL}token/refresh/`; - - try { - const response = await axios.post(refreshUrl, { refresh: refresh_token }); - - if (response.status === 200) { - // Successful refresh - save the new access token and refresh token - const newAccessToken = response.data.access; - const newRefreshToken = response.data.refresh; - - localStorage.setItem("access_token", newAccessToken); - localStorage.setItem("refresh_token", newRefreshToken); - - return true; - } else { - return false; - } - } catch (error) { - return false; - } -} - -export default refreshAccessToken; diff --git a/frontend/src/components/calendar/TaskDataHandler.jsx b/frontend/src/components/calendar/TaskDataHandler.jsx index ff8a5df..793ca4b 100644 --- a/frontend/src/components/calendar/TaskDataHandler.jsx +++ b/frontend/src/components/calendar/TaskDataHandler.jsx @@ -1,9 +1,9 @@ -import { readTodoTasks } from "../../api/TaskApi"; +import { readTodoTasks } from "src/api/TaskApi"; let eventGuid = 0; -const mapResponseToEvents = response => { - return response.map(item => ({ +const mapResponseToEvents = (response) => { + return response.map((item) => ({ id: item.id, title: item.title, start: item.start_event, diff --git a/frontend/src/components/calendar/calendar.jsx b/frontend/src/components/calendar/calendar.jsx index e4f1bdd..a85ea2d 100644 --- a/frontend/src/components/calendar/calendar.jsx +++ b/frontend/src/components/calendar/calendar.jsx @@ -5,9 +5,9 @@ import dayGridPlugin from "@fullcalendar/daygrid"; import timeGridPlugin from "@fullcalendar/timegrid"; import interactionPlugin from "@fullcalendar/interaction"; import { getEvents, createEventId } from "./TaskDataHandler"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; -export default class Calendar extends React.Component { +export class Calendar extends React.Component { state = { weekendsVisible: true, currentEvents: [], diff --git a/frontend/src/components/dashboard/Areachart.jsx b/frontend/src/components/dashboard/Areachart.jsx index 862fa21..cd6bb93 100644 --- a/frontend/src/components/dashboard/Areachart.jsx +++ b/frontend/src/components/dashboard/Areachart.jsx @@ -1,6 +1,6 @@ import { AreaChart, Title } from "@tremor/react"; import { useState, useEffect } from "react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; export const AreaChartGraph = () => { const [areaChartDataArray, setAreaChartDataArray] = useState([]); diff --git a/frontend/src/components/dashboard/Barchart.jsx b/frontend/src/components/dashboard/Barchart.jsx index 63a2c4f..bf84a2b 100644 --- a/frontend/src/components/dashboard/Barchart.jsx +++ b/frontend/src/components/dashboard/Barchart.jsx @@ -1,6 +1,6 @@ import { BarChart, Title } from "@tremor/react"; import { useState, useEffect } from "react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; export const BarChartGraph = () => { const [barchartDataArray, setBarChartDataArray] = useState([]); diff --git a/frontend/src/components/dashboard/DonutChart.jsx b/frontend/src/components/dashboard/DonutChart.jsx index ccab32f..63fc591 100644 --- a/frontend/src/components/dashboard/DonutChart.jsx +++ b/frontend/src/components/dashboard/DonutChart.jsx @@ -1,8 +1,8 @@ import { DonutChart } from "@tremor/react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; import { useState, useEffect } from "react"; -export default function DonutChartGraph() { +export function DonutChartGraph() { const [donutData, setDonutData] = useState([]); useEffect(() => { diff --git a/frontend/src/components/dashboard/KpiCard.jsx b/frontend/src/components/dashboard/KpiCard.jsx index 47c7162..c5c3165 100644 --- a/frontend/src/components/dashboard/KpiCard.jsx +++ b/frontend/src/components/dashboard/KpiCard.jsx @@ -1,8 +1,8 @@ import { BadgeDelta, Card, Flex, Metric, ProgressBar, Text } from "@tremor/react"; import { useEffect, useState } from "react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; -export default function KpiCard() { +export function KpiCard() { const [kpiCardData, setKpiCardData] = useState({ completedThisWeek: 0, completedLastWeek: 0, diff --git a/frontend/src/components/dashboard/ProgressCircle.jsx b/frontend/src/components/dashboard/ProgressCircle.jsx index c6d09b3..683781e 100644 --- a/frontend/src/components/dashboard/ProgressCircle.jsx +++ b/frontend/src/components/dashboard/ProgressCircle.jsx @@ -1,8 +1,8 @@ import { Card, Flex, ProgressCircle } from "@tremor/react"; import { useState, useEffect } from "react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; -export default function ProgressCircleChart() { +export function ProgressCircleChart() { const [progressData, setProgressData] = useState(0); useEffect(() => { diff --git a/frontend/src/components/dashboard/dashboard.jsx b/frontend/src/components/dashboard/dashboard.jsx index 761f0ca..f735146 100644 --- a/frontend/src/components/dashboard/dashboard.jsx +++ b/frontend/src/components/dashboard/dashboard.jsx @@ -1,11 +1,11 @@ import { Card, Grid, Tab, TabGroup, TabList, TabPanel, TabPanels, Text, Title, Legend } from "@tremor/react"; -import KpiCard from "./KpiCard"; +import { KpiCard } from "./KpiCard"; import { BarChartGraph } from "./Barchart"; -import DonutChartGraph from "./DonutChart"; +import { DonutChartGraph } from "./DonutChart"; import { AreaChartGraph } from "./Areachart"; -import ProgressCircleChart from "./ProgressCircle"; +import { ProgressCircleChart } from "./ProgressCircle"; -export default function Dashboard() { +export function Dashboard() { return (
diff --git a/frontend/src/components/kanbanBoard/columnContainer.jsx b/frontend/src/components/kanbanBoard/columnContainer.jsx index 80bd445..819a980 100644 --- a/frontend/src/components/kanbanBoard/columnContainer.jsx +++ b/frontend/src/components/kanbanBoard/columnContainer.jsx @@ -3,13 +3,13 @@ import { BsFillTrashFill } from "react-icons/bs"; import { AiOutlinePlusCircle } from "react-icons/ai"; import { CSS } from "@dnd-kit/utilities"; import { useMemo, useState } from "react"; -import TaskCard from "./taskCard"; +import { TaskCard } from "./taskCard"; -function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { +export function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { const [editMode, setEditMode] = useState(false); const tasksIds = useMemo(() => { - return tasks.map(task => task.id); + return tasks.map((task) => task.id); }, [tasks]); const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({ @@ -78,12 +78,12 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks updateColumn(column.id, e.target.value)} + onChange={(e) => updateColumn(column.id, e.target.value)} autoFocus onBlur={() => { setEditMode(false); }} - onKeyDown={e => { + onKeyDown={(e) => { if (e.key !== "Enter") return; setEditMode(false); }} @@ -109,7 +109,7 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks {/* Column task container */}
- {tasks.map(task => ( + {tasks.map((task) => ( ))} @@ -126,5 +126,3 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks
); } - -export default ColumnContainer; diff --git a/frontend/src/components/kanbanBoard/columnContainerWrapper.jsx b/frontend/src/components/kanbanBoard/columnContainerWrapper.jsx index 478a529..b14adb1 100644 --- a/frontend/src/components/kanbanBoard/columnContainerWrapper.jsx +++ b/frontend/src/components/kanbanBoard/columnContainerWrapper.jsx @@ -1,6 +1,6 @@ -import ColumnContainer from "./columnContainer"; +import { ColumnContainer } from "./columnContainer"; -function ColumnContainerCard({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { +export function ColumnContainerCard({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { return (
); } - -export default ColumnContainerCard; diff --git a/frontend/src/components/kanbanBoard/kanbanBoard.jsx b/frontend/src/components/kanbanBoard/kanbanBoard.jsx index a4ecd79..a91b2db 100644 --- a/frontend/src/components/kanbanBoard/kanbanBoard.jsx +++ b/frontend/src/components/kanbanBoard/kanbanBoard.jsx @@ -1,13 +1,12 @@ import { useMemo, useState, useEffect } from "react"; -import ColumnContainerCard from "./columnContainerWrapper"; +import { ColumnContainerCard } from "./columnContainerWrapper"; import { DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from "@dnd-kit/core"; import { SortableContext, arrayMove } from "@dnd-kit/sortable"; import { createPortal } from "react-dom"; -import TaskCard from "./taskCard"; -import { AiOutlinePlusCircle } from "react-icons/ai"; -import axiosInstance from "src/api/AxiosConfig"; +import { TaskCard } from "./taskCard"; +import { axiosInstance } from "src/api/AxiosConfig"; -function KanbanBoard() { +export function KanbanBoard() { const [columns, setColumns] = useState([]); const columnsId = useMemo(() => columns.map((col) => col.id), [columns]); const [boardId, setBoardData] = useState(); @@ -26,40 +25,6 @@ function KanbanBoard() { }) ); - // Example - // { - // "id": 95, - // "title": "Test Todo", - // "notes": "Test TodoTest TodoTest Todo", - // "importance": 1, - // "difficulty": 1, - // "challenge": false, - // "fromSystem": false, - // "creation_date": "2023-11-20T19:50:16.369308Z", - // "last_update": "2023-11-20T19:50:16.369308Z", - // "is_active": true, - // "is_full_day_event": false, - // "start_event": "2023-11-20T19:49:49Z", - // "end_event": "2023-11-23T18:00:00Z", - // "google_calendar_id": null, - // "completed": true, - // "completion_date": "2023-11-20T19:50:16.369308Z", - // "priority": 3, - // "user": 1, - // "list_board": 1, - // "tags": [] - // } - // ] - - // [ - // { - // "id": 8, - // "name": "test", - // "position": 2, - // "board": 3 - // } - // ] - useEffect(() => { const fetchData = async () => { try { @@ -73,7 +38,6 @@ function KanbanBoard() { difficulty: task.difficulty, notes: task.notes, importance: task.importance, - difficulty: task.difficulty, challenge: task.challenge, fromSystem: task.fromSystem, creation_date: task.creation_date, @@ -149,31 +113,6 @@ function KanbanBoard() { ))}
- {/* create new column */} -
{createPortal( @@ -409,10 +348,4 @@ function KanbanBoard() { }); } } - - function generateId() { - return Math.floor(Math.random() * 10001); - } } - -export default KanbanBoard; diff --git a/frontend/src/components/kanbanBoard/kanbanPage.jsx b/frontend/src/components/kanbanBoard/kanbanPage.jsx index 37671ae..9225ae7 100644 --- a/frontend/src/components/kanbanBoard/kanbanPage.jsx +++ b/frontend/src/components/kanbanBoard/kanbanPage.jsx @@ -1,12 +1,12 @@ -import KanbanBoard from "./kanbanBoard"; -import React, { useState } from 'react'; +import { KanbanBoard } from "./kanbanBoard"; +import { useState } from "react"; -const KanbanPage = () => { - const [activeTab, setActiveTab] = useState('kanban'); +export const KanbanPage = () => { + const [activeTab, setActiveTab] = useState("kanban"); - const handleTabClick = (tabId) => { - setActiveTab(tabId); - }; + const handleTabClick = (tabId) => { + setActiveTab(tabId); + }; return (
@@ -29,10 +29,7 @@ const KanbanPage = () => {
-
-
+
); }; - -export default KanbanPage; diff --git a/frontend/src/components/kanbanBoard/taskCard.jsx b/frontend/src/components/kanbanBoard/taskCard.jsx index 2c5053f..e1814c6 100644 --- a/frontend/src/components/kanbanBoard/taskCard.jsx +++ b/frontend/src/components/kanbanBoard/taskCard.jsx @@ -2,9 +2,9 @@ import { useState } from "react"; import { BsFillTrashFill } from "react-icons/bs"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; -import TaskDetailModal from "./taskDetailModal"; +import { TaskDetailModal } from "./taskDetailModal"; -function TaskCard({ task, deleteTask, updateTask}) { +export function TaskCard({ task, deleteTask, updateTask }) { const [mouseIsOver, setMouseIsOver] = useState(false); const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({ @@ -15,7 +15,6 @@ function TaskCard({ task, deleteTask, updateTask}) { }, }); - const style = { transition, transform: CSS.Transform.toString(transform), @@ -79,5 +78,3 @@ function TaskCard({ task, deleteTask, updateTask}) {
); } - -export default TaskCard; diff --git a/frontend/src/components/kanbanBoard/taskDetailModal.jsx b/frontend/src/components/kanbanBoard/taskDetailModal.jsx index ddf954b..e151d8f 100644 --- a/frontend/src/components/kanbanBoard/taskDetailModal.jsx +++ b/frontend/src/components/kanbanBoard/taskDetailModal.jsx @@ -1,9 +1,9 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { FaTasks, FaRegListAlt } from "react-icons/fa"; import { FaPlus } from "react-icons/fa6"; import { TbChecklist } from "react-icons/tb"; -function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId }) { +export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId }) { const [isChallengeChecked, setChallengeChecked] = useState(challenge); const [isImportantChecked, setImportantChecked] = useState(importance); const [currentDifficulty, setCurrentDifficulty] = useState(difficulty); @@ -28,7 +28,8 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo

- {}{title} + {} + {title}

{title}

@@ -45,13 +46,13 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo
-
+
@@ -144,5 +145,3 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo ); } - -export default TaskDetailModal; diff --git a/frontend/src/components/navigations/IconSideNav.jsx b/frontend/src/components/navigations/IconSideNav.jsx index dc364f3..02cc1a0 100644 --- a/frontend/src/components/navigations/IconSideNav.jsx +++ b/frontend/src/components/navigations/IconSideNav.jsx @@ -1,9 +1,9 @@ import { useState } from "react"; -import { AiOutlineHome, AiOutlineSchedule, AiOutlineUnorderedList, AiOutlinePieChart } from "react-icons/ai"; +import { AiOutlineHome, AiOutlineSchedule, AiOutlineUnorderedList } from "react-icons/ai"; import { PiStepsDuotone } from "react-icons/pi"; import { IoSettingsOutline } from "react-icons/io5"; import { AnimatePresence, motion } from "framer-motion"; -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; const menuItems = [ { id: 0, path: "/", icon: }, @@ -13,20 +13,12 @@ const menuItems = [ { id: 4, path: "/priority", icon: }, ]; -const IconSideNav = () => { - return ( -
- -
- ); -}; - -const SideNav = () => { +export const SideNav = () => { const [selected, setSelected] = useState(0); return (
); } -export default NavBar; diff --git a/frontend/src/components/ProfileUpdateComponent.jsx b/frontend/src/components/profile/ProfileUpdateComponent.jsx similarity index 88% rename from frontend/src/components/ProfileUpdateComponent.jsx rename to frontend/src/components/profile/ProfileUpdateComponent.jsx index 74da41f..12f5e98 100644 --- a/frontend/src/components/ProfileUpdateComponent.jsx +++ b/frontend/src/components/profile/ProfileUpdateComponent.jsx @@ -1,7 +1,7 @@ -import React, { useState, useRef } from "react"; -import { ApiUpdateUserProfile } from "../api/UserProfileApi"; +import { useState, useRef } from "react"; +import { ApiUpdateUserProfile } from "src/api/UserProfileApi"; -function ProfileUpdateComponent() { +export function ProfileUpdateComponent() { const [file, setFile] = useState(null); const [username, setUsername] = useState(""); const [fullName, setFullName] = useState(""); @@ -15,7 +15,7 @@ function ProfileUpdateComponent() { } }; - const handleFileChange = e => { + const handleFileChange = (e) => { const selectedFile = e.target.files[0]; if (selectedFile) { setFile(selectedFile); @@ -66,7 +66,7 @@ function ProfileUpdateComponent() { placeholder="Enter your username" className="input w-full" value={username} - onChange={e => setUsername(e.target.value)} + onChange={(e) => setUsername(e.target.value)} /> @@ -78,7 +78,7 @@ function ProfileUpdateComponent() { placeholder="Enter your full name" className="input w-full" value={fullName} - onChange={e => setFullName(e.target.value)} + onChange={(e) => setFullName(e.target.value)} /> @@ -89,7 +89,7 @@ function ProfileUpdateComponent() { placeholder="Tell us about yourself" className="textarea w-full h-32" value={about} - onChange={e => setAbout(e.target.value)} + onChange={(e) => setAbout(e.target.value)} /> @@ -100,5 +100,3 @@ function ProfileUpdateComponent() { ); } - -export default ProfileUpdateComponent; diff --git a/frontend/src/components/profilePage.jsx b/frontend/src/components/profile/profilePage.jsx similarity index 82% rename from frontend/src/components/profilePage.jsx rename to frontend/src/components/profile/profilePage.jsx index 4b0d0b4..d61368a 100644 --- a/frontend/src/components/profilePage.jsx +++ b/frontend/src/components/profile/profilePage.jsx @@ -1,7 +1,6 @@ -import * as React from "react"; -import ProfileUpdateComponent from "./ProfileUpdateComponent"; +import { ProfileUpdateComponent } from "./ProfileUpdateComponent"; -function ProfileUpdatePage() { +export function ProfileUpdatePage() { return (
@@ -47,7 +46,7 @@ function ProfileUpdatePage() {
3213/321312321 points
- +
@@ -75,10 +74,10 @@ function ProfileUpdatePage() {
-
-

About me

-
-