From 1ca92b3cfe5e7045fb0701a39b281eb1388c9b8b Mon Sep 17 00:00:00 2001 From: Guilhem CARRON <gcarron@grandlyon.com> Date: Wed, 15 Dec 2021 15:46:07 +0000 Subject: [PATCH] feat: Add partners issue info --- .gitignore | 2 +- .vscode/settings.json | 22 +- docker-compose.local.yml | 16 +- docker-compose.yml | 2 +- nginx/site.conf | 7 +- public/index.html | 18 +- public/logo192.png | Bin 5347 -> 4944 bytes public/logo512.png | Bin 9664 -> 12597 bytes public/og-icon.png | Bin 0 -> 17060 bytes scripts/import-convert-assets.sh | 29 + src/components/Editing/Editing.tsx | 551 +++++++++--------- src/components/ImagePicker/ImagePicker.tsx | 6 +- src/components/PartnersInfo/PartnersInfo.tsx | 187 ++++++ src/components/PartnersInfo/partnersInfo.scss | 59 ++ src/components/Settings/Settings.tsx | 14 +- src/enum/checkboxType.enum.ts | 6 + src/hooks/useFindUser.ts | 13 +- src/models/partnersInfo.model.ts | 6 + src/services/newsletter.service.ts | 162 +++-- src/services/partnersInfo.service.ts | 48 ++ src/styles/index.scss | 1 - 21 files changed, 774 insertions(+), 375 deletions(-) create mode 100644 public/og-icon.png create mode 100755 scripts/import-convert-assets.sh create mode 100644 src/components/PartnersInfo/PartnersInfo.tsx create mode 100644 src/components/PartnersInfo/partnersInfo.scss create mode 100644 src/enum/checkboxType.enum.ts create mode 100644 src/models/partnersInfo.model.ts create mode 100644 src/services/partnersInfo.service.ts diff --git a/.gitignore b/.gitignore index 70d1ca62..06f1ac1a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ /coverage # production /build - +/image-lib # misc .DS_Store /.env diff --git a/.vscode/settings.json b/.vscode/settings.json index dce69f3f..2a18744c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,28 @@ { + "workbench.colorCustomizations": { + "activityBar.background": "#37cc4e", + "activityBar.activeBorder": "#7867d8", + "activityBar.foreground": "#15202b", + "activityBar.inactiveForeground": "#15202b99", + "activityBarBadge.background": "#7867d8", + "activityBarBadge.foreground": "#e7e7e7", + "titleBar.activeBackground": "#2aa63d", + "titleBar.inactiveBackground": "#2aa63d99", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveForeground": "#e7e7e799", + "statusBar.background": "#2aa63d", + "statusBarItem.hoverBackground": "#37cc4e", + "statusBar.foreground": "#e7e7e7", + "activityBar.activeBackground": "#37cc4e", + "sash.hoverBorder": "#37cc4e", + "statusBarItem.remoteBackground": "#2aa63d", + "statusBarItem.remoteForeground": "#e7e7e7" + }, "editor.formatOnSave": true, "eslint.format.enable": true, "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode", + "peacock.color": "#2aa63d" } diff --git a/docker-compose.local.yml b/docker-compose.local.yml index bb3f992e..14115d60 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -2,26 +2,20 @@ version: '3.7' services: nginx: image: nginx:1.16 - depends_on: - - front - - backend volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/site.conf:/etc/nginx/conf.d/default.conf - ./cert.pem:/etc/nginx/cert.pem - ./key.pem:/etc/nginx/key.pem - - ./../${IMAGE_FOLDER}:/usr/share/nginx/html/lib/${IMAGE_FOLDER} ports: - 443:443 depends_on: - backend - environment: - - IMAGE_FOLDER=${IMAGE_FOLDER} # For linux users # extra_hosts: - # - "host.docker.internal:host-gateway" + # - 'host.docker.internal:host-gateway' - database: + database-agent: image: mysql:5 ports: - 3306:3306 @@ -37,7 +31,7 @@ services: backend: image: registry.forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server:dev depends_on: - database: + database-agent: condition: service_healthy restart: unless-stopped volumes: @@ -45,7 +39,7 @@ services: - ./configs:/app/configs - ./letsencrypt_cache:/app/letsencrypt_cache - ./data:/app/data - - ./../${IMAGE_FOLDER}:/app/${IMAGE_FOLDER} + - ./${IMAGE_FOLDER}:/app/${IMAGE_FOLDER} ports: - ${HTTPS_PORT}:${HTTPS_PORT} - 8090:8090 @@ -63,6 +57,6 @@ services: - DATABASE_USER=${DATABASE_USER} - DATABASE_NAME=${DATABASE_NAME} - DATABASE_PASSWORD=${DATABASE_PASSWORD} - - DATABASE_HOST=database + - DATABASE_HOST=database-agent - MOCK_OAUTH2=${MOCK_OAUTH2} - IMAGE_FOLDER=${IMAGE_FOLDER} diff --git a/docker-compose.yml b/docker-compose.yml index 86d3e525..0ef136a4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,7 +43,7 @@ services: - ./configs:/app/configs - ./letsencrypt_cache:/app/letsencrypt_cache - ./data:/app/data - - ./image-lib/${IMAGE_FOLDER}:/app/${IMAGE_FOLDER} + - ./${IMAGE_FOLDER}:/app/${IMAGE_FOLDER} ports: - ${HTTPS_PORT}:${HTTPS_PORT} - 8190:8090 diff --git a/nginx/site.conf b/nginx/site.conf index 2ab117ce..8304b5b0 100644 --- a/nginx/site.conf +++ b/nginx/site.conf @@ -24,10 +24,7 @@ server { location /swagger { proxy_pass https://backend:1443/swagger; } - location ~ ^/assets/(.+\.(?:gif|jpe?g|svg))$ { - alias /usr/share/nginx/html/lib/$1; - gzip_static on; - expires max; - add_header Cache-Control public; + location /assets { + proxy_pass https://backend:1443/assets; } } \ No newline at end of file diff --git a/public/index.html b/public/index.html index f7cd1670..ca83182e 100644 --- a/public/index.html +++ b/public/index.html @@ -5,10 +5,7 @@ <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> - <meta - name="description" - content="Web site created using create-react-app" - /> + <meta name="description" content="Le backoffice de l'application Ecolyo."> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <!-- manifest.json provides metadata used when your web app is installed on a @@ -24,7 +21,18 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - <title>Backoffice Ecolyo</title> + <title>Ecolyo - Agent</title> + <meta property="og:url" content="%PUBLIC_URL%"> + <meta property="og:type" content="website"> + <meta property="og:title" content="Ecolyo - Agent"> + <meta property="og:description" content="Le backoffice de l'application Ecolyo."> + <meta property="og:image:secure_url" content="https://ecolyo-agent.grandlyon.com/og-icon.png"> + <meta property="og:image" content="https://ecolyo-agent.grandlyon.com/og-icon.png"> + <meta property="og:image:type" content="image/png" /> + <meta property="og:image:width" content="1200" /> + <meta property="og:image:height" content="627" /> + <meta property="og:image:alt" content="Ecolyo Logo" /> + </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> diff --git a/public/logo192.png b/public/logo192.png index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..62e287da17b3a66f7d9745a726e35b6b7a79de88 100644 GIT binary patch literal 4944 zcmZu#Rb0~z7yfT-12$5+LrDQ?a3G9sNqs>OhIC0wDx*_EUZf-?6hvA?YLtKi1L=}U zNJ&bJ+{b(WT|B36&bc_x@0@s}`&yK6RyY6vlsek#Cf6GKAIM<W(q!J9^jeX7X<PUL z0D|s6fPkDg%-2DXuZfl_@Nt-Z<Jy5ZsTimLKy3=*!WIeuH&%7jRm=iG+j)=OtyZ)9 z3bJdLQ>VRE$=FPUV-{#Wl~l@rg-eITeml}tnTcj--#Lc8U8oehQDVYZ676W^UHj<$ zt!C$t^a`D7;iU1EVtO$nevi%vF3};j;}09;q0y<*z0dxj*l~BC7fdPro@SZbJ$aKt zG-P%B^CrHVaN2<*2K`Ji<r$$}sy8ctc^IkOu1P2N+lAmunZr%<MmQYb<2hp55dO0` z3$~mU^TqXWa<^T>kdEwrG)jD_V2s;;l$PpZC1khtc%vZE=4;PO#(NR&G*o2VK-Z3Y zDJLz#@2_A1BevYL(C#lSM=Z?+31WrCHh`0%lgOAB)BAp8Y(WNj9_u+u1FGgG3FH;> z8GBaF;UR_fxsPjF7q1KF;s*LYI0VcVaRWM~ssf{;KGY(qYD>nn1h)0ZyeAwSJB*!- z&7>??(2q4b4u%w@OK}e9hgXwef=eJyZsQi{HaCEnZItnsphbbB(9{q#CJ}2`LyJn_ zZ*(T)#{|M2p#av;6c-RJu(or;qhIur5l9*gcpn$lw_8?j1yhnjwx_-D{g_MjGbF<b z>{dbrse#w!H5)^o-$Ei8_Gfu^Z8nR$7w32&UWpeuQ1L^oRztmKzSS$TA_il+?XhDN za647DJoid1aFb^$T=|}5DczluvG{_+vBSn(<Vd<2^^1m#Xguq_UOqkX?#rO4+;G6z zyP<jj8}QWk#`F&R)z0?e)#^u?>SYluua`%nN#T8MV^<J?eVa~x&nD1i?$v^^1A40O za1igX_DL{&JB?r{l~cYP!YZxFSLz3*sc-b(Km5$R5p>{+QS4MA&fT1IUa{hu!B;A2 zcR!)A_(cd+FaPeCrptpVEfkPg3aOJP-y($Csgl{IN$j)aC20JziWxLA2Z_w&Y9}B1 zA0$;{4ZAyWs`8)LT*-KDW&dg*P~hnOUsZ{N<7}9o#b}-6P@I8m@?Y@rfW!ETqOo2A zLcdwovW6Li6jn@tI=3;t$WWA`vPi;orxB=NBpz#{<7udVzExlJVN~)*1P#fsxwVw~ zZ)lCkwA&$WiDa#7!gBu$=ln!a?Tl7+dvmj0_+m0frt4AC17T@?$sSJ&da0$YbG9c` zyxsPyfMmZMS%EceingNsNRWDpec_Z4N!BMRweD?Gi6TvsfKXKnw1lab?a=FuQ2J5G z6l48T8q`~!4*R6sA^fy=N`|&)|CNjd!8&8-(HZh}N>$NzqHz3B(9w{Aw9=?r5O21T zor<6Q?GN!ZvGh@acZKTu>?<|aPS2N)qC%6EJiaHm3ADJVNCzmmPO&0T&n#U1Uc<>! zj@`YdH|+<0XYnE&_xp7pdJP>hE)avdi(3;hw{UMSgIf>Il}`Kh9*&fTbUubKqGZ^9 z&cmpJEk>?_O@FtwA;he=i-~SKsnr$`(vv}YRf>#?=4e?aY(xN#!vS$N!QA4N7%Cpb zq^6!ngVIDyJxellPwlimF0^@>@nqVjgTElav*4|wQM>{V@a-cI_-~j-;OS_S#t2c^ z^78CMIwOfwBvfTkSHfOK!R%W;C~$R^&C|1_Nn`))TeaNx>hOD3Qn#Se^&#i}v(M+O zenX6_jFnlQm_knKPvMj)J8yZX7hA?f3ub<xqo}(T{s~^WNee-s5>(@C@lsuq3rK-X zrxo%R-szi)2_5IQCo81?xLO9;hwb_>MclLVioy5Y;g_Ymbj-crL~zqa)AxH!ZE$_U z8611Wwf5?<=LX!041scXo=Wh6vztio4;}b6QFvWl5l%UC^564^=jW=jiHQ5Qeff}V zu71U7!HfXYW<OC=S7@3yuQOH%S$iq^KtInVa`J)LGVftOb<_8$z2B=b+jRA+>~fvF zw&9AWy&e6@<H2S^-G2eoDPgkELa0+(w3fj}a4rS<={trNl)EP&9=?Up=z^ofY+&4K ztrOyjI`tGa#+R{G0aR2#Wl<XFUB`EKF|0n2_5~<&91mp&WUX?`J?t?7ApNkU?llYx zlhe2q%22cfnqW)<5C;d}$Chu{XJrG@<6rd{0dbW^O4rB}3T%A~K=|rsh_Uc<{Q&8m z<v=IgXX?N9UHpn+fC`?)mcg~LbWF2hF9#$}3b>C7MHz@QU|!9ZIikZ*%#V!wg8&UY zF<i957c`;UpN$?Q!Jytv0u1oG)P?4dj#yT}d?`c>YX<mdB$heVQjtv;J%aRwOJQ!j z17Sof82jnBJ2*l>C~d#l!mwcLFfo*k^)vziziOta@jLDSU)!or>IAT!l$bUEdt)&K zY*ZT2MboHChFWe1#%fU5SBd{joTO*X3t-(~S*mRG_U!3oRh8CpL*iJ*Jh9Y)PuluX z;ri*lt0P%tB-uSHnk;8vtRpiG^F&n|zuY&B7N}G+EbI3IdjBkQ)mv`5y^U)uoV0pi z?aJW$u3wj4%jtese^viemR|dRvYHm{f5P$ATxZ%!50{7M)?5k#uQu^XG@Y`ifGvIo zossL5^#>jaEk26uSU4hH?wUdl3^$-&Yso=XctiY&`^>-9Y+Vd_^4d&-Vv|p6+K#sD zyIv2a?T3VOGL=ufRx=Y))8ipbY6qb`7cQQz%kDyF02vJQ4HVTL4xrvkya(0LgY93* zTk7$6*#LN0K|o>@6kG}e1OFci3UDgVox6v750HeB#!q^3Uj<}G;xo@(N@lbiAS{L0 zz5M93n_T?{ij`HCOVH<99nZ2~oaQNiFa6~}0u~fhJdlg|C}@N0Bwl)2mDJhtV#qTR zcjmn#QEMaQSCC;CY1D&ntip3V*$GeF%T!>3+&=Zgj~zo8s1&8u9Kc{fZdrv1CCfS_ z00y$lo61Z5@&x}1=+LFFj?f8bW_a8JU9E2$&jtNM&I<tWsDb2~zrvZ%kDu8C_?VxR zt}NUMI_EX~gOC6+F|%Da-wMd0scmR6Y2TePBL-BJ?kuU|M%cI7Jqx%%K7Qogu@_#B zvxAqvLdoLq7pB}c`B*>Ni6G3o(gKjaD^RLRq7^ewL8^Sm!2Aw@#kzgZWEl**LAiv| z*o)eXcCfOnV_YPDjeSHy687R{QHN2sF~?=LE}xxL=OuI7YkBFw31?I)Vn+Ak?#>@m z8xuM$9!XRb1v+9#BH?_;a#0c#6q^Nr*G-sEVb!w~)+{wFz2E<<eZZye#t@t-J<5a? z*c4WS0iV{#fiU8SS@s949w0MLT5#NiI)-l)%SZ`wp5yxZf$ZUjPX?JQ;M5x5#93}u zwm(qxAjIgwx$R}!IvAv2=7y1<Y*J3j1|GR8C%FOoD*)TS0g=5tQkbvQ-F43BZ##42 za>wc!so;?;#B_+<&Rgi<h<kW)8psj6{*Y*UQbYrb`SbH5rvkq(kdy`ppR2=++@rg| zAX90Pk&*#+z^<K9yO9BofKZI~1DeONwH6d7mKlj7<Y4|ie&z`(Blh>bPZS2BH18{^ z5}Pq%JV;d1OQ>sw^|!u5P+>QgV>7bMg)~lr3HwI#c0)1}SeMviIa2wXzcx;~oWYDh zi6xkdC<TftZUTjonlR^A&}Rx=Pmtw4*@~4nEC4~t8olR-O+pwJ1yF<ECP3eXdU@%8 zL|3u=Ih_Ti1^m~5>$*M0Ew2HE^aq@PaS;06=aXtAh%s@xrNj0UEq~{g8Cfq9bGnIt z07i?#c1FD5X~BQ0V%h*+WL5A+c&sBircs`dvKeV#TEQ7oX?q6~WE)P;^tBTf-iSVb zJ9_n|VS^}OjzCR<7?5v+@43^MQ*xZs^&TI`dizRVw*{9a`w;W`k|*T6`!g-}4WZ9@ zy09(4)`UVtYwT*o{a+rCHk;W4n^ZqMVy1;bU|mFw`W@Hyoj*91xnrk@mTvDg7xN>N z_Q<;lwyBy<2YP;-hOcf~!BNd@J#LXyp`b><9FNbh+|0F!<KOZ4T&tYa)n+{&Z&Pl! z<Qb~FIy<`m($6`N$)9yt-I9WO@0y=}9Lh9G+#1K}d>&ik^w_n5hy0Vnb-7kBfg`>j z8Cbympj#npB9>cajgLdHz2eo>tk2IGH*c|<f9cFvEl8(9#u?adz4ZllC@CweBE}ZA zS8dc4%<Rgir>I>P$0+ENibxxu6rMK6oF4Z*`^@!9nm)%KWOP69aLVQRSBX5{K6xh0 zAh<R-5pGe~dd+mVzfJk<x2)yvd{HKE*Wd7-K%_yxkq5l+yZ?d??zMSIcR_}}?-wau zhaDw0>la$B2ZnK8J|4RG*pmn_%6$`b0x2mX9==mlJT^29Zc^q$uDbpX;JZ5W$+5sV z#d;goE_H|Fz(&zp#M9Ryy9Iay;LCrBSgt!K21Vb2>eEq<%g0ShV}!iy(Lr#lHWk#{ z`&ZWqzHL)4Kj^Sy?XGL8Rx2DWfnc8uqGswb7yL&taD3{`;lbpo&hqo8?FW3n7Ns3y zo2lf_8ucIv(I1cYCr)g1vU-Jbw&bSa-o_LOAf`6tWUNc$IxQSU0}>ggy3N!>(WEiT z@J;#0nPQ>S^T6J6T$h}|=hb-M;;d1@xaQl3*K21poPBJLZnXA}O)9RU=E%Ek$yYRj z9L3lp+U7t11{4!J!a8)@aHpks^_;JGk5cAL>X#&@@SxfUY3ZhWK7yxkjQ1rA2=#le zY*|1P?U_>uPPNLkK&!5aieS{Jmlcazu^QDMcd0#|--tk9d*Bj^%9v%dI^53oRO9Qr z0&y&h0;-P+qV`xYgI`n!wU<f!Vk9ZfFYRouFci$sya$WO@5}XW-AMUi!4svDchVZx zoXF|+=M|1yK?FjCUKVG*6N*sQ#&vLT3;;q6TcBZJo>POrpQ^00<MWTP8FFfVKWP&2 z{Vi$k{NaSKfroh~JaqOXiD?Dudy5O?iv?w4ESM?yep<pK#BXN%h+#Xrizirx`3<}i zQVh@(%aSrb&5Q#UiuSyk`s4}C>(5^&8^hK=Lv`Q!)>-9j%m{N_?N9|D4Glpq>N}M5 za1_>)kCsxoLy7zMaHC`Y(n|6H{8!Qaum{0!D4gHS-xsjn5x`UDuSjnEmEt8B#^bq) zDbmOh4M}W1env{J_YCaT;jaw>qcY{PU>#`pPZ@b>$~?X-n0Q=5vQf%9McN-4m%p3U zvZHCHO+{)eWS@{Y;+zKSv_ok9-`Z@(drMpPq->Hxz}JTm=kza~6=U@%$H;<#4*;_z zt(W&jSHJ8yH0D;~tbW3Rh9t*@ei;<2P3vC5wI!CV?Yks!X+p-6B7l=(-(x2r*G?LW zgd&KyEvR1b{{?H;Y*0zmsJnWF5l>0DX3g{UpM^ZUDF;UPD5|JkB&MW7-;fhPPrsJ+ zW<Qxeu}~5l$N-p`cu}(ER4K>TbE(@nxV0io$et(1#D{67n7n*Z*n)Y=*AHu0ITD3G zb~I@{j}IyM>l;yT=pzL1bC!M)&z<L~NQXKM!LH93eZv<U2|rmbJ@9-(p)rPxjGwYo zEkWXmyz;`<O1iIGr~fd_;3vBfoyM^OJWP4{js1<l4Xbe|1u3y9nvd1x*qGLPWXdpI zp<^*wl?;>SuaY?k^RJ7F-m@VR1EgQH$0h)C9M*lyh5ZhJ4Mg4Y<Gn9s;$U<MAFnaH zrG8H7K#Qo)^n#A_0pr)!v&(1nx&Zk{5o6V#QCP;cTAbkqmsUG6ed+JuAU|U!y$O(1 zDP|0=zP%))aVO!7yHZsfyr^O+HDqp8DsX&JJ#*vegQ+>_*5_du`-Mn^2zjR|UMgD9 zZ>o3?jJ9$j;YX<MF%t|VHo3$$-xZY6gSF!p3(KQvlBb8c%YWg+>_Y8ESUc_TOp{yH zn(rZ45y!}wK$q4!KbcUb?*pQmr;fhKBn2eD4qrZ$O%^8C*?^?teSV_(M55AspGzZO zAeyn>TwyG&|AteSiR#+eWd4A2tIYDg(yARFkdT%7uGqEP;r1}UcK7C<i>>Nb;ArCf zkzgCZT<|Gw^gW&8**PD<J%5H#=AbpEkAVgSUsOdCdJ^cAw>t(nPaEzE!R6B35Rehr zl%DWxT7xn1OyB@Hd*??9ReooI12;w{E=&wE!Z%yS8ND~`wvx`zvo{3+8)3_76v+#9 z$U^zJ0m@La&RQTR3OfY`i(?&X|7ZgSs(3aK$Q-Xq#t6<zx`~`f*kJyG{EY&rQdOPf zvsWvwqH@B4709H1VscT6Cp840Met{R)H)FRBdClO?0n4(IWO0x!HXO;7=e``qOebP zZ_cqZ2S_{D^!*PPLWnX7$WJ>Kyz%&Lw87n@jIj0uAdusVWtyFc0zhdV<2j1b&xCH5 zKro~2Bq)G`JA)zr1~`j8uS80UHm}E-E58F&bzWOB*R<Ji{Qv`WH14Z^R7FSp4-7UD A(*OVf literal 5347 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 X@eDJUQo;Ye2mwlRs<JiGX2Jghdw)}T diff --git a/public/logo512.png b/public/logo512.png index a4e47a6545bc15971f8f63fba70e4013df88a664..d94e3e561d3c694f3d7627931c16b609fed77898 100644 GIT binary patch literal 12597 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 RC#p+eX}Wtyp0VqN{{!T%B?$lk literal 9664 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN diff --git a/public/og-icon.png b/public/og-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ab931e75cc8477bbcb634499d985bb490ca8a91e GIT binary patch literal 17060 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	K20R`AmOJ<Z1}Xeqqu1@nP}anL_8~-<@etF9 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 literal 0 HcmV?d00001 diff --git a/scripts/import-convert-assets.sh b/scripts/import-convert-assets.sh new file mode 100755 index 00000000..73615174 --- /dev/null +++ b/scripts/import-convert-assets.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Get env variables +. ../.env + +REGISTRY_ID=409 +EMAIL_ASSETS_PATH="src/assets/icons/email" +ECOGESTURE_ASSETS_PATH="src/assets/icons/visu/ecogesture" +pwd=$(pwd) + +# Fetch and convert email assets +curl "https://forge.grandlyon.com/api/v4/projects/${REGISTRY_ID}/repository/archive?path=${EMAIL_ASSETS_PATH}" --output email.tar.gz +tar -xf email.tar.gz +cd *-email/$EMAIL_ASSETS_PATH && for file in *.svg; do inkscape -h 200 --export-type="png" $file; done && rm *.svg + +cd $pwd +# Fetch and convert ecogesture assets +curl "https://forge.grandlyon.com/api/v4/projects/${REGISTRY_ID}/repository/archive?path=${ECOGESTURE_ASSETS_PATH}" --output ecogesture.tar.gz +tar -xf ecogesture.tar.gz +cd *-ecogesture/$ECOGESTURE_ASSETS_PATH && for file in *.svg; do inkscape -h 200 --export-type="png" $file; done && rm *.svg + +# Cleanup +cd $pwd +rm -rf ../${IMAGE_FOLDER}/* + +# Copy assets in IMAGE_FOLDER +mv *-email/$EMAIL_ASSETS_PATH/* ../${IMAGE_FOLDER} +mv *-ecogesture/$ECOGESTURE_ASSETS_PATH ../${IMAGE_FOLDER}/ecogesture +rm -rf email.tar.gz ecogesture.tar.gz *-email *-ecogesture diff --git a/src/components/Editing/Editing.tsx b/src/components/Editing/Editing.tsx index 90158488..f0ef6d39 100644 --- a/src/components/Editing/Editing.tsx +++ b/src/components/Editing/Editing.tsx @@ -1,281 +1,270 @@ -import React, { useCallback, useContext, useEffect, useState } from 'react' -import DateSelector from '../DateSelector/DateSelector' -import { NewsletterService } from '../../services/newsletter.service' -import { UserContext, UserContextProps } from '../../hooks/userContext' -import { IMonthlyNews } from '../../models/monthlyNews.model' -import { IMonthlyInfo } from '../../models/monthlyInfo.model' -import { IPoll } from '../../models/poll.model' -import Poll from '../Poll/Poll' -import MonthlyInfo from '../MonthlyInfo/MonthlyInfo' -import MonthlyNews from '../MonthlyNews/MonthlyNews' -import Loader from '../Loader/Loader' -import Modal from '../Modal/Modal' -import './editing.scss' - -export type ContentItems = 'monthlyInfo' | 'monthlyNews' | 'poll' | '' - -const Editing: React.FC = () => { - const [date, setDate] = useState<Date>(new Date()) - const [info, setInfo] = useState<string>('') - const [title, setTitle] = useState<string>('') - const [imageURL, setImageURL] = useState<string>('') - const [content, setContent] = useState<string>('') - const [question, setQuestion] = useState<string>('') - const [link, setLink] = useState<string>('') - const [isTouched, setIsTouched] = useState<boolean>(false) - const [refreshData, setRefreshData] = useState(false) - const [isLoading, setisLoading] = useState<boolean>(false) - const [warningModal, setwarningModal] = useState<boolean>(false) - const [toDelete, settoDelete] = useState<ContentItems>('') - const { user }: Partial<UserContextProps> = useContext(UserContext) - const newsletterService = new NewsletterService() - - const handleSaveMonthlyInfo = async (): Promise<void> => { - if (user) { - const newsletterService = new NewsletterService() - await newsletterService.saveMonthlyInfo( - date, - info, - imageURL, - user.xsrftoken - ) - setIsTouched(false) - } - } - - const handleSaveMonthlyNews = async (): Promise<void> => { - if (user) { - const newsletterService = new NewsletterService() - await newsletterService.saveMonthlyNews( - date, - title, - content, - user.xsrftoken - ) - setIsTouched(false) - } - } - const handleSavePoll = async (): Promise<void> => { - if (user) { - await newsletterService.savePoll(date, question, link, user.xsrftoken) - setIsTouched(false) - } - } - const handleCancel = useCallback(() => { - setRefreshData(true) - }, []) - - const handleDeleteMonthlyInfo = async (): Promise<void> => { - if (user) { - await newsletterService.deleteMonthlyInfo( - date.getFullYear(), - date.getMonth(), - user.xsrftoken - ) - setRefreshData(true) - } - } - const handleDeleteMonthlyNews = async (): Promise<void> => { - if (user) { - await newsletterService.deleteMonthlyNews( - date.getFullYear(), - date.getMonth(), - user.xsrftoken - ) - setRefreshData(true) - } - } - const handleDeletePoll = async (): Promise<void> => { - if (user) { - await newsletterService.deletePoll( - date.getFullYear(), - date.getMonth(), - user.xsrftoken - ) - setRefreshData(true) - } - } - const handleOpenDeleteModal = (target: ContentItems) => { - settoDelete(target) - setwarningModal(true) - } - const handleConfirmAlert = () => { - if (toDelete === 'monthlyInfo') { - handleDeleteMonthlyInfo() - } - if (toDelete === 'monthlyNews') { - handleDeleteMonthlyNews() - } - if (toDelete === 'poll') { - handleDeletePoll() - } - setwarningModal(false) - } - - const isEmpty = (): boolean => { - if ( - (info !== '' || - title !== '' || - content !== '' || - question !== '' || - imageURL !== '' || - link !== '') && - isTouched - ) { - return false - } else return true - } - - const handleEditorChange = ( - value: string, - type: 'info' | 'title' | 'content' | 'question' | 'link' | 'image' - ): void => { - setIsTouched(true) - if (type === 'info') { - setInfo(value) - } - if (type === 'title') { - setTitle(value) - } - if (type === 'content') { - setContent(value) - } - if (type === 'question') { - setQuestion(value) - } - if (type === 'link') { - setLink(value) - } - if (type === 'image') { - setImageURL(value) - } - } - const resetFields = useCallback(() => { - setImageURL('') - setInfo('') - setTitle('') - setContent('') - setLink('') - setQuestion('') - }, []) - - useEffect(() => { - let subscribed = true - resetFields() - setisLoading(true) - async function getCurrentMonthlyNews() { - if (user) { - const newsletterService = new NewsletterService() - const montlhyInfo: IMonthlyInfo | null = - await newsletterService.getSingleMonthlyInfo( - date.getFullYear(), - date.getMonth(), - user.xsrftoken - ) - const montlhyNews: IMonthlyNews | null = - await newsletterService.getSingleMonthlyNews( - date.getFullYear(), - date.getMonth(), - user.xsrftoken - ) - const poll: IPoll | null = await newsletterService.getSinglePoll( - date.getFullYear(), - date.getMonth(), - user.xsrftoken - ) - if (montlhyInfo) { - setInfo(montlhyInfo.info) - setImageURL(montlhyInfo.image) - setIsTouched(false) - } - if (montlhyNews) { - setTitle(montlhyNews.title) - setContent(montlhyNews.content) - setIsTouched(false) - } - if (poll) { - setLink(poll.link) - setQuestion(poll.question) - setIsTouched(false) - } - } - setisLoading(false) - } - if (subscribed) { - getCurrentMonthlyNews() - } - return () => { - subscribed = false - setRefreshData(false) - } - }, [date, user, refreshData, resetFields]) - - return ( - <> - <div className="header"> - <p className="title pagetitle">Édition de la newsletter</p> - <DateSelector date={date} setDate={setDate} isEmpty={isEmpty} /> - </div> - {isLoading ? ( - <Loader /> - ) : ( - <div className="content"> - <MonthlyInfo - info={info} - onSave={handleSaveMonthlyInfo} - onCancel={handleCancel} - handleChange={handleEditorChange} - onDelete={handleOpenDeleteModal} - imageURL={imageURL} - /> - <hr /> - <MonthlyNews - title={title} - content={content} - onSave={handleSaveMonthlyNews} - onCancel={handleCancel} - handleChange={handleEditorChange} - onDelete={handleOpenDeleteModal} - /> - <hr /> - <Poll - question={question} - link={link} - onSave={handleSavePoll} - onCancel={handleCancel} - handleChange={handleEditorChange} - onDelete={handleOpenDeleteModal} - /> - </div> - )} - {warningModal && ( - <Modal> - <> - <div className="modal-text"> - Etes-vous sûr de vouloir supprimer{' '} - {toDelete === 'monthlyInfo' - ? 'cette info mensuelle ' - : toDelete === 'monthlyNews' - ? 'cette news mensuelle' - : 'ce sondage'}{' '} - ? - </div> - <div className="buttons"> - <button - className="btnCancel" - onClick={() => setwarningModal(false)} - > - Annuler - </button> - <button className="btnValid" onClick={handleConfirmAlert}> - Continuer - </button> - </div> - </> - </Modal> - )} - </> - ) -} - -export default Editing +import React, { useCallback, useContext, useEffect, useState } from 'react' +import DateSelector from '../DateSelector/DateSelector' +import { NewsletterService } from '../../services/newsletter.service' +import { UserContext, UserContextProps } from '../../hooks/userContext' +import { IMonthlyNews } from '../../models/monthlyNews.model' +import { IMonthlyInfo } from '../../models/monthlyInfo.model' +import { IPoll } from '../../models/poll.model' +import Poll from '../Poll/Poll' +import MonthlyInfo from '../MonthlyInfo/MonthlyInfo' +import MonthlyNews from '../MonthlyNews/MonthlyNews' +import Loader from '../Loader/Loader' +import Modal from '../Modal/Modal' +import './editing.scss' + +export type ContentItems = 'monthlyInfo' | 'monthlyNews' | 'poll' | '' + +const Editing: React.FC = () => { + // Fonctional rule : + // Display next month after the 3rd of the current month + const getCurrentNewsletterDate = (): Date => { + let newsletterDate = new Date() + if (newsletterDate.getDate() >= 3) { + newsletterDate.setMonth(newsletterDate.getMonth() + 1) + } + return newsletterDate + } + + const [date, setDate] = useState<Date>(getCurrentNewsletterDate()) + const [info, setInfo] = useState<string>('') + const [title, setTitle] = useState<string>('') + const [imageURL, setImageURL] = useState<string>('') + const [content, setContent] = useState<string>('') + const [question, setQuestion] = useState<string>('') + const [link, setLink] = useState<string>('') + const [isTouched, setIsTouched] = useState<boolean>(false) + const [refreshData, setRefreshData] = useState(false) + const [isLoading, setisLoading] = useState<boolean>(false) + const [warningModal, setwarningModal] = useState<boolean>(false) + const [toDelete, settoDelete] = useState<ContentItems>('') + const { user }: Partial<UserContextProps> = useContext(UserContext) + const newsletterService = new NewsletterService() + + const handleSaveMonthlyInfo = async (): Promise<void> => { + if (user) { + const newsletterService = new NewsletterService() + await newsletterService.saveMonthlyInfo( + date, + info, + imageURL, + user.xsrftoken + ) + setIsTouched(false) + } + } + + const handleSaveMonthlyNews = async (): Promise<void> => { + if (user) { + const newsletterService = new NewsletterService() + await newsletterService.saveMonthlyNews( + date, + title, + content, + user.xsrftoken + ) + setIsTouched(false) + } + } + const handleSavePoll = async (): Promise<void> => { + if (user) { + await newsletterService.savePoll(date, question, link, user.xsrftoken) + setIsTouched(false) + } + } + const handleCancel = useCallback(() => { + setRefreshData(true) + }, []) + + const handleDeleteMonthlyInfo = async (): Promise<void> => { + if (user) { + await newsletterService.deleteMonthlyInfo(date, user.xsrftoken) + setRefreshData(true) + } + } + const handleDeleteMonthlyNews = async (): Promise<void> => { + if (user) { + await newsletterService.deleteMonthlyNews(date, user.xsrftoken) + setRefreshData(true) + } + } + const handleDeletePoll = async (): Promise<void> => { + if (user) { + await newsletterService.deletePoll(date, user.xsrftoken) + setRefreshData(true) + } + } + const handleOpenDeleteModal = (target: ContentItems) => { + settoDelete(target) + setwarningModal(true) + } + const handleConfirmAlert = () => { + if (toDelete === 'monthlyInfo') { + handleDeleteMonthlyInfo() + } + if (toDelete === 'monthlyNews') { + handleDeleteMonthlyNews() + } + if (toDelete === 'poll') { + handleDeletePoll() + } + setwarningModal(false) + } + + const isEmpty = (): boolean => { + if ( + (info !== '' || + title !== '' || + content !== '' || + question !== '' || + imageURL !== '' || + link !== '') && + isTouched + ) { + return false + } else return true + } + + const handleEditorChange = ( + value: string, + type: 'info' | 'title' | 'content' | 'question' | 'link' | 'image' + ): void => { + setIsTouched(true) + if (type === 'info') { + setInfo(value) + } + if (type === 'title') { + setTitle(value) + } + if (type === 'content') { + setContent(value) + } + if (type === 'question') { + setQuestion(value) + } + if (type === 'link') { + setLink(value) + } + if (type === 'image') { + setImageURL(value) + } + } + const resetFields = useCallback(() => { + setImageURL('') + setInfo('') + setTitle('') + setContent('') + setLink('') + setQuestion('') + }, []) + + useEffect(() => { + let subscribed = true + resetFields() + setisLoading(true) + async function getCurrentMonthlyNews() { + if (user) { + const newsletterService = new NewsletterService() + const montlhyInfo: IMonthlyInfo | null = + await newsletterService.getSingleMonthlyInfo(date, user.xsrftoken) + const montlhyNews: IMonthlyNews | null = + await newsletterService.getSingleMonthlyNews(date, user.xsrftoken) + const poll: IPoll | null = await newsletterService.getSinglePoll( + date, + user.xsrftoken + ) + if (montlhyInfo) { + setInfo(montlhyInfo.info) + setImageURL(montlhyInfo.image) + setIsTouched(false) + } + if (montlhyNews) { + setTitle(montlhyNews.title) + setContent(montlhyNews.content) + setIsTouched(false) + } + if (poll) { + setLink(poll.link) + setQuestion(poll.question) + setIsTouched(false) + } + } + setisLoading(false) + } + if (subscribed) { + getCurrentMonthlyNews() + } + return () => { + subscribed = false + setRefreshData(false) + } + }, [date, user, refreshData, resetFields]) + + return ( + <> + <div className="header"> + <p className="title pagetitle">Édition de la newsletter</p> + <DateSelector date={date} setDate={setDate} isEmpty={isEmpty} /> + </div> + {isLoading ? ( + <Loader /> + ) : ( + <div className="content"> + <MonthlyInfo + info={info} + onSave={handleSaveMonthlyInfo} + onCancel={handleCancel} + handleChange={handleEditorChange} + onDelete={handleOpenDeleteModal} + imageURL={imageURL} + /> + <hr /> + <MonthlyNews + title={title} + content={content} + onSave={handleSaveMonthlyNews} + onCancel={handleCancel} + handleChange={handleEditorChange} + onDelete={handleOpenDeleteModal} + /> + <hr /> + <Poll + question={question} + link={link} + onSave={handleSavePoll} + onCancel={handleCancel} + handleChange={handleEditorChange} + onDelete={handleOpenDeleteModal} + /> + </div> + )} + {warningModal && ( + <Modal> + <> + <div className="modal-text"> + Etes-vous sûr de vouloir supprimer{' '} + {toDelete === 'monthlyInfo' + ? 'cette info mensuelle ' + : toDelete === 'monthlyNews' + ? 'cette news mensuelle' + : 'ce sondage'}{' '} + ? + </div> + <div className="buttons"> + <button + className="btnCancel" + onClick={() => setwarningModal(false)} + > + Annuler + </button> + <button className="btnValid" onClick={handleConfirmAlert}> + Continuer + </button> + </div> + </> + </Modal> + )} + </> + ) +} + +export default Editing diff --git a/src/components/ImagePicker/ImagePicker.tsx b/src/components/ImagePicker/ImagePicker.tsx index fa93461a..7362ea59 100644 --- a/src/components/ImagePicker/ImagePicker.tsx +++ b/src/components/ImagePicker/ImagePicker.tsx @@ -49,7 +49,7 @@ const ImagePicker: React.FC<ImagePickerProps> = ({ user.xsrftoken ) //Split array depending on page numbers - setpageCount(Math.ceil(images.length / imagePerPage) - 1) + setpageCount(Math.ceil(images.length / imagePerPage)) const arraySplitted = [] while (images.length) { arraySplitted.push(images.splice(0, imagePerPage)) @@ -95,8 +95,8 @@ const ImagePicker: React.FC<ImagePickerProps> = ({ <div className="image-picker"> {imageNames && imageNames !== [] && - imageNames[currentPage] !== [] && - imageNames[currentPage].map((imageURL) => ( + imageNames[currentPage - 1] !== [] && + imageNames[currentPage - 1].map((imageURL) => ( <SingleImage imageURL={imageURL} key={imageURL} diff --git a/src/components/PartnersInfo/PartnersInfo.tsx b/src/components/PartnersInfo/PartnersInfo.tsx new file mode 100644 index 00000000..0988b3d7 --- /dev/null +++ b/src/components/PartnersInfo/PartnersInfo.tsx @@ -0,0 +1,187 @@ +import React, { useCallback, useContext, useEffect, useState } from 'react' +import { IPartnersInfo } from '../../models/partnersInfo.model' +import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css' +import './partnersInfo.scss' +import { PartnersInfoService } from '../../services/partnersInfo.service' +import { UserContext, UserContextProps } from '../../hooks/userContext' +import Loader from '../Loader/Loader' +import { CheckboxType } from '../../enum/checkboxType.enum' + +const PartnersInfo: React.FC = () => { + const [refreshData, setRefreshData] = useState(false) + const [isLoading, setIsLoading] = useState<boolean>(false) + const [partnersInfo, setPartnersInfo] = useState<IPartnersInfo>({ + grdf_failure: false, + enedis_failure: false, + egl_failure: false, + notification_activated: false, + }) + const { user }: Partial<UserContextProps> = useContext(UserContext) + + const handleCheckboxChange = (value: boolean, type: CheckboxType): void => { + switch (type) { + case CheckboxType.GRDF: + setPartnersInfo((prevPartnersInfo) => ({ + ...prevPartnersInfo, + grdf_failure: value, + })) + break + case CheckboxType.ENEDIS: + setPartnersInfo((prevPartnersInfo) => ({ + ...prevPartnersInfo, + enedis_failure: value, + })) + break + case CheckboxType.EGL: + setPartnersInfo((prevPartnersInfo) => ({ + ...prevPartnersInfo, + egl_failure: value, + })) + break + case CheckboxType.NOTIFICATION: + setPartnersInfo((prevPartnersInfo) => ({ + ...prevPartnersInfo, + notification_activated: value, + })) + break + default: + throw new Error('Unknown checkbox type') + } + } + + const handleCancel = useCallback(() => { + setRefreshData(true) + }, [setRefreshData]) + + const resetFields = useCallback(() => { + setPartnersInfo({ + grdf_failure: false, + enedis_failure: false, + egl_failure: false, + notification_activated: false, + }) + }, [setPartnersInfo]) + + useEffect(() => { + let subscribed = true + resetFields() + setIsLoading(true) + + async function getPartnersInfo() { + if (user) { + const partnersInfoService = new PartnersInfoService() + const partnersInfoResp: IPartnersInfo | null = + await partnersInfoService.getPartnersInfo() + if (partnersInfoResp) { + setPartnersInfo({ + grdf_failure: partnersInfoResp.grdf_failure, + enedis_failure: partnersInfoResp.enedis_failure, + egl_failure: partnersInfoResp.egl_failure, + notification_activated: partnersInfoResp.notification_activated, + }) + } + } + setIsLoading(false) + } + if (subscribed) { + getPartnersInfo() + } + return () => { + subscribed = false + setRefreshData(false) + } + }, [user, refreshData, setPartnersInfo, resetFields]) + + const handleSave = async (): Promise<void> => { + if (user) { + const partnersInfoService = new PartnersInfoService() + await partnersInfoService.savePartnersInfo(partnersInfo, user.xsrftoken) + } + } + + return ( + <> + {isLoading ? ( + <Loader /> + ) : ( + <div className="partnersInfo"> + <h2>État des services des partenaires</h2> + <div> + <p className="title">Affichage de la pop-up dans Ecolyo</p> + <div className="switch_div"> + Pop-up active + <input + type="checkbox" + id="switch_notification" + onChange={(event) => { + handleCheckboxChange( + event.currentTarget.checked, + CheckboxType.NOTIFICATION + ) + }} + checked={partnersInfo.notification_activated} + /> + <label htmlFor="switch_notification"></label> + </div> + <p className="title">Services concernés</p> + <div className="switch_div"> + Panne Enedis + <input + type="checkbox" + id="switch_enedis" + onChange={(event) => { + handleCheckboxChange( + event.currentTarget.checked, + CheckboxType.ENEDIS + ) + }} + checked={partnersInfo.enedis_failure} + /> + <label htmlFor="switch_enedis"></label> + </div> + <div className="switch_div"> + Panne EGL + <input + type="checkbox" + id="switch_egl" + onChange={(event) => { + handleCheckboxChange( + event.currentTarget.checked, + CheckboxType.EGL + ) + }} + checked={partnersInfo.egl_failure} + /> + <label htmlFor="switch_egl"></label> + </div> + <div className="switch_div"> + Panne GRDF + <input + type="checkbox" + id="switch_grdf" + onChange={(event) => { + handleCheckboxChange( + event.currentTarget.checked, + CheckboxType.GRDF + ) + }} + checked={partnersInfo.grdf_failure} + /> + <label htmlFor="switch_grdf"></label> + </div> + <div className="buttons"> + <button className="btnCancel" onClick={handleCancel}> + Annuler + </button> + <button className="btnValid" onClick={handleSave}> + Sauvegarder + </button> + </div> + </div> + </div> + )} + </> + ) +} + +export default PartnersInfo diff --git a/src/components/PartnersInfo/partnersInfo.scss b/src/components/PartnersInfo/partnersInfo.scss new file mode 100644 index 00000000..27de6e11 --- /dev/null +++ b/src/components/PartnersInfo/partnersInfo.scss @@ -0,0 +1,59 @@ +.partnersInfo { + margin: 2rem 0; + .title { + margin: 1rem 0; + } + h2 { + margin-bottom: 1rem; + } + + .switch_div { + display: inline-block; + padding: 1rem 1rem; + min-width: 135px; + } + + input[type='checkbox'] { + width: 0; + height: 0; + visibility: hidden; + margin-bottom: 15px; + } + + label { + display: block; + width: 50px; + height: 20px; + background-color: grey; + border-radius: 15px; + position: relative; + cursor: pointer; + transition: 0.5s; + box-shadow: 0 0 20px #80808050; + } + + label::after { + content: ''; + width: 17px; + height: 17px; + background-color: #e8f5f7; + position: absolute; + border-radius: 13px; + top: 2px; + left: 2px; + transition: 0.5s; + } + + input:checked + label:after { + left: calc(100% - 3px); + transform: translateX(-100%); + } + + input:checked + label { + background-color: #e3b82a; + } + + label:active:after { + width: 34px; + } +} diff --git a/src/components/Settings/Settings.tsx b/src/components/Settings/Settings.tsx index 30cfca08..444d3842 100644 --- a/src/components/Settings/Settings.tsx +++ b/src/components/Settings/Settings.tsx @@ -1,7 +1,17 @@ import React from 'react' +import PartnersInfo from '../PartnersInfo/PartnersInfo' const Settings: React.FC = () => { - return <div>A venir</div> -} + return ( + <> + <div className="header"> + <p className="title pagetitle">Paramètres de l'appli</p> + </div> + <div className="content"> + <PartnersInfo /> + </div> + </> + ) +} export default Settings diff --git a/src/enum/checkboxType.enum.ts b/src/enum/checkboxType.enum.ts new file mode 100644 index 00000000..6363fcef --- /dev/null +++ b/src/enum/checkboxType.enum.ts @@ -0,0 +1,6 @@ +export enum CheckboxType { + NOTIFICATION = 0, + GRDF = 1, + ENEDIS = 2, + EGL = 3, +} diff --git a/src/hooks/useFindUser.ts b/src/hooks/useFindUser.ts index 3c853bca..b76d2a11 100644 --- a/src/hooks/useFindUser.ts +++ b/src/hooks/useFindUser.ts @@ -1,6 +1,7 @@ import { useState, useEffect } from 'react' import axios from 'axios' import { User } from '../models/user.model' +import { toast } from 'react-toastify' const useFindUser = () => { const [user, setUser] = useState<User | null>(null) @@ -8,10 +9,14 @@ const useFindUser = () => { useEffect(() => { async function findUser() { - const { data } = await axios.get(`/api/common/WhoAmI`) - if (data) { - setUser(data) - setLoading(false) + try { + const { data } = await axios.get(`/api/common/WhoAmI`) + if (data) { + setUser(data) + setLoading(false) + } + } catch (error) { + toast.error('Access denied, please login') } } findUser() diff --git a/src/models/partnersInfo.model.ts b/src/models/partnersInfo.model.ts new file mode 100644 index 00000000..3d073d3e --- /dev/null +++ b/src/models/partnersInfo.model.ts @@ -0,0 +1,6 @@ +export interface IPartnersInfo { + grdf_failure: boolean + enedis_failure: boolean + egl_failure: boolean + notification_activated: boolean +} diff --git a/src/services/newsletter.service.ts b/src/services/newsletter.service.ts index d0f4515a..7a27ccca 100644 --- a/src/services/newsletter.service.ts +++ b/src/services/newsletter.service.ts @@ -19,7 +19,7 @@ export class NewsletterService { await axios.put( `/api/admin/monthlyInfo`, { - month: date.getMonth(), + month: date.getMonth() + 1, year: date.getFullYear(), info: info, image: image, @@ -31,23 +31,30 @@ export class NewsletterService { } ) toast.success('Monthly info succesfully saved !') - } catch (e) { - toast.error('Failed to create monthly info') + } catch (e: any) { + if (e.response.status === 403) { + toast.error( + "Unauthorized : You don't have the rights to do this operation" + ) + } else { + toast.error('Failed to create monthly info') + } console.error(e) } } /** * Gets the information for selected month + * @param date + * @param token */ public getSingleMonthlyInfo = async ( - year: number, - month: number, + date: Date, token: string ): Promise<IMonthlyInfo | null> => { try { const { data } = await axios.get( - `/api/admin/monthlyInfo/${year}/${month}`, + `/api/admin/monthlyInfo/${date.getFullYear()}/${date.getMonth() + 1}`, { headers: { 'XSRF-TOKEN': token, @@ -55,7 +62,7 @@ export class NewsletterService { } ) return data as IMonthlyInfo - } catch (e) { + } catch (e: any) { console.error('error', e) return null } @@ -63,24 +70,31 @@ export class NewsletterService { /** * Deletes a Monthly Info for selected month - * @param year - * @param month + * @param date * @param token */ public deleteMonthlyInfo = async ( - year: number, - month: number, + date: Date, token: string ): Promise<void> => { try { - await axios.delete(`/api/admin/monthlyInfo/${year}/${month}`, { - headers: { - 'XSRF-TOKEN': token, - }, - }) + await axios.delete( + `/api/admin/monthlyInfo/${date.getFullYear()}/${date.getMonth() + 1}`, + { + headers: { + 'XSRF-TOKEN': token, + }, + } + ) toast.success('Monthly info succesfully deleted !') - } catch (e) { - toast.error('Failed to delete monthly info') + } catch (e: any) { + if (e.response.status === 403) { + toast.error( + "Unauthorized : You don't have the rights to do this operation" + ) + } else { + toast.error('Failed to delete monthly info') + } console.error(e) } } @@ -101,7 +115,7 @@ export class NewsletterService { await axios.put( `/api/admin/monthlyNews`, { - month: date.getMonth(), + month: date.getMonth() + 1, year: date.getFullYear(), title: title, content: content, @@ -113,23 +127,30 @@ export class NewsletterService { } ) toast.success('Monthly news succesfully saved !') - } catch (e) { - toast.error('Failed to create monthly news') + } catch (e: any) { + if (e.response.status === 403) { + toast.error( + "Unauthorized : You don't have the rights to do this operation" + ) + } else { + toast.error('Failed to save monthly news') + } console.error(e) } } /** * Gets a news title and content for selected month + * @param date + * @param token */ public getSingleMonthlyNews = async ( - year: number, - month: number, + date: Date, token: string ): Promise<IMonthlyNews | null> => { try { const { data } = await axios.get( - `/api/admin/monthlyNews/${year}/${month}`, + `/api/admin/monthlyNews/${date.getFullYear()}/${date.getMonth() + 1}`, { headers: { 'XSRF-TOKEN': token, @@ -145,24 +166,31 @@ export class NewsletterService { /** * Deletes a Monthly News for selected month - * @param year - * @param month + * @param date * @param token */ public deleteMonthlyNews = async ( - year: number, - month: number, + date: Date, token: string ): Promise<void> => { try { - await axios.delete(`/api/admin/monthlyNews/${year}/${month}`, { - headers: { - 'XSRF-TOKEN': token, - }, - }) + await axios.delete( + `/api/admin/monthlyNews/${date.getFullYear()}/${date.getMonth() + 1}`, + { + headers: { + 'XSRF-TOKEN': token, + }, + } + ) toast.success('Monthly news succesfully deleted !') - } catch (e) { - toast.error('Failed to delete monthly news') + } catch (e: any) { + if (e.response.status === 403) { + toast.error( + "Unauthorized : You don't have the rights to do this operation" + ) + } else { + toast.error('Failed to delete monthly news') + } console.error(e) } } @@ -183,7 +211,7 @@ export class NewsletterService { await axios.put( `/api/admin/poll`, { - month: date.getMonth(), + month: date.getMonth() + 1, year: date.getFullYear(), link: link, question: question, @@ -195,26 +223,36 @@ export class NewsletterService { } ) toast.success('Poll successfully saved !') - } catch (e) { - toast.error('Failed to create poll') + } catch (e: any) { + if (e.response.status === 403) { + toast.error( + "Unauthorized : You don't have the rights to do this operation" + ) + } else { + toast.error('Failed to create poll') + } console.error(e) } } /** * Gets a poll with question and link for selected month + * @param date + * @param token */ public getSinglePoll = async ( - year: number, - month: number, + date: Date, token: string ): Promise<IPoll | null> => { try { - const { data } = await axios.get(`/api/admin/poll/${year}/${month}`, { - headers: { - 'XSRF-TOKEN': token, - }, - }) + const { data } = await axios.get( + `/api/admin/poll/${date.getFullYear()}/${date.getMonth() + 1}`, + { + headers: { + 'XSRF-TOKEN': token, + }, + } + ) return data as IPoll } catch (e) { console.error('error', e) @@ -224,24 +262,28 @@ export class NewsletterService { /** * Deletes a poll for selected month - * @param month - * @param year + * @param date * @param token */ - public deletePoll = async ( - year: number, - month: number, - token: string - ): Promise<void> => { + public deletePoll = async (date: Date, token: string): Promise<void> => { try { - await axios.delete(`/api/admin/poll/${year}/${month}`, { - headers: { - 'XSRF-TOKEN': token, - }, - }) + await axios.delete( + `/api/admin/poll/${date.getFullYear()}/${date.getMonth() + 1}`, + { + headers: { + 'XSRF-TOKEN': token, + }, + } + ) toast.success('Poll succesfully deleted !') - } catch (e) { - toast.error('Failed to delete poll') + } catch (e: any) { + if (e.response.status === 403) { + toast.error( + "Unauthorized : You don't have the rights to do this operation" + ) + } else { + toast.error('Failed to delete poll') + } console.error(e) } } @@ -258,7 +300,7 @@ export class NewsletterService { }) if (imageNames && imageNames !== null) { const imageURLs = imageNames.map((image: string) => { - return `/assets/ecogeste/${image}` + return `/assets/ecogesture/${image}` }) return imageURLs } diff --git a/src/services/partnersInfo.service.ts b/src/services/partnersInfo.service.ts new file mode 100644 index 00000000..0b930759 --- /dev/null +++ b/src/services/partnersInfo.service.ts @@ -0,0 +1,48 @@ +import axios from 'axios' +import { IPartnersInfo } from '../models/partnersInfo.model' +import { toast } from 'react-toastify' +export class PartnersInfoService { + /** + * Save the partnersInfo + * @param partnersInfo + * @param token + */ + public savePartnersInfo = async ( + partnersInfo: IPartnersInfo, + token: string + ): Promise<void> => { + try { + await axios.put( + `/api/admin/partnersInfo`, + { + grdf_failure: partnersInfo.grdf_failure, + enedis_failure: partnersInfo.enedis_failure, + egl_failure: partnersInfo.egl_failure, + notification_activated: partnersInfo.notification_activated, + }, + { + headers: { + 'XSRF-TOKEN': token, + }, + } + ) + toast.success('Partners info succesfully saved !') + } catch (e) { + toast.error('Failed to save partners info') + console.error(e) + } + } + + /** + * Gets the partners information + */ + public getPartnersInfo = async (): Promise<IPartnersInfo | null> => { + try { + const { data } = await axios.get(`/api/common/partnersInfo`) + return data as IPartnersInfo + } catch (e) { + console.error('error', e) + return null + } + } +} diff --git a/src/styles/index.scss b/src/styles/index.scss index b8ed46d6..42a35b1f 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -2,7 +2,6 @@ @import 'config/colors'; @import 'config/typography'; @import 'config/layout'; -@import 'config/layout'; @import 'toast'; * { -- GitLab