From f3251f0f03b86a9713cc2ebf2bbc0584f8ce5379 Mon Sep 17 00:00:00 2001 From: Maxime Lalo Date: Thu, 27 Jul 2023 15:18:11 +0200 Subject: [PATCH] :sparkles: Notification when user super admin --- .../SuperAdmin/LiveVotes/LiveVotes.ts | 11 +++- .../Api/LeCoffreApi/SuperAdmin/Votes/Votes.ts | 44 +++++++++++++ .../UserInformations/classes.module.scss | 4 ++ .../Layouts/Users/UserInformations/index.tsx | 66 ++++++++++++++++--- 4 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 src/front/Api/LeCoffreApi/SuperAdmin/Votes/Votes.ts diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes.ts b/src/front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes.ts index dfbb54e1..394e1b93 100644 --- a/src/front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes.ts +++ b/src/front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes.ts @@ -1,4 +1,4 @@ -import { Appointment, Vote } from "le-coffre-resources/dist/SuperAdmin"; +import { Appointment } from "le-coffre-resources/dist/SuperAdmin"; import BaseSuperAdmin from "../BaseSuperAdmin"; @@ -13,6 +13,11 @@ export type IPostLiveVotesParams = { appointment: Appointment; }; +export type LiveVote = { + uid: string; + appointment: Appointment; +}; + export default class LiveVotes extends BaseSuperAdmin { private static instance: LiveVotes; private readonly baseURl = this.namespaceUrl.concat("/live-votes"); @@ -32,10 +37,10 @@ export default class LiveVotes extends BaseSuperAdmin { /** * @description : Create a LiveVotes */ - public async post(body: IPostLiveVotesParams): Promise { + public async post(body: IPostLiveVotesParams): Promise { const url = new URL(this.baseURl); try { - return await this.postRequest(url, body); + return await this.postRequest(url, body); } catch (err) { this.onError(err); return Promise.reject(err); diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/Votes/Votes.ts b/src/front/Api/LeCoffreApi/SuperAdmin/Votes/Votes.ts new file mode 100644 index 00000000..34907702 --- /dev/null +++ b/src/front/Api/LeCoffreApi/SuperAdmin/Votes/Votes.ts @@ -0,0 +1,44 @@ +import { Vote } from "le-coffre-resources/dist/SuperAdmin"; + +import BaseSuperAdmin from "../BaseSuperAdmin"; + +// TODO Type get query params -> Where + inclue + orderby +export interface IGetVotessparams { + where?: {}; + include?: {}; + select?: {}; +} + +export type IDeleteVotesParams = { + uid: Vote["uid"]; +}; + +export default class Votes extends BaseSuperAdmin { + private static instance: Votes; + private readonly baseURl = this.namespaceUrl.concat("/votes"); + + private constructor() { + super(); + } + + public static getInstance() { + if (!this.instance) { + return new this(); + } else { + return this.instance; + } + } + + /** + * @description : Create a Votes + */ + public async delete(body: IDeleteVotesParams): Promise { + const url = new URL(this.baseURl + "/" + body.uid); + try { + return await this.deleteRequest(url, body); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Components/Layouts/Users/UserInformations/classes.module.scss b/src/front/Components/Layouts/Users/UserInformations/classes.module.scss index 2bac3ec5..6dd2a010 100644 --- a/src/front/Components/Layouts/Users/UserInformations/classes.module.scss +++ b/src/front/Components/Layouts/Users/UserInformations/classes.module.scss @@ -79,3 +79,7 @@ } } } + +.remove-my-vote { + margin-top: 16px; +} diff --git a/src/front/Components/Layouts/Users/UserInformations/index.tsx b/src/front/Components/Layouts/Users/UserInformations/index.tsx index f0cdd1a2..6a8c174d 100644 --- a/src/front/Components/Layouts/Users/UserInformations/index.tsx +++ b/src/front/Components/Layouts/Users/UserInformations/index.tsx @@ -1,12 +1,17 @@ import WarningIcon from "@Assets/images/warning.png"; import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles"; +import Roles from "@Front/Api/LeCoffreApi/Admin/Roles/Roles"; import LiveVotes from "@Front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes"; import Users from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users"; +import Votes from "@Front/Api/LeCoffreApi/SuperAdmin/Votes/Votes"; +import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField"; import Confirm from "@Front/Components/DesignSystem/Modal/Confirm"; import Switch from "@Front/Components/DesignSystem/Switch"; import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography"; import DefaultUserDashboard from "@Front/Components/LayoutTemplates/DefaultUserDashboard"; +import JwtService from "@Front/Services/JwtService/JwtService"; +import Toasts from "@Front/Stores/Toasts"; import User, { Appointment, Vote } from "le-coffre-resources/dist/SuperAdmin"; import { EAppointmentStatus, EVote } from "le-coffre-resources/dist/SuperAdmin/Appointment"; import Image from "next/image"; @@ -45,15 +50,17 @@ export default function UserInformations(props: IProps) { role: true, appointment: { include: { - votes: true, + votes: { + include: { + voter: true, + }, + }, }, }, votes: true, }, }); if (!user) return; - - console.log(user); const roles = await OfficeRoles.getInstance().get(); if (!roles) return; setAvailableRoles(roles.map((role) => ({ value: role.uid, label: role.name }))); @@ -88,9 +95,23 @@ export default function UserInformations(props: IProps) { const handleAdminModalAccepted = useCallback(async () => { if (!userSelected) return; if (adminModalType === "add") { - // add super admin + const adminRole = await Roles.getInstance().getOne({ + where: { + name: "admin", + }, + }); + + if (!adminRole) return; + await Users.getInstance().put( + userSelected?.uid as string, + User.hydrate({ + uid: userSelected?.uid as string, + office_role: undefined, + role: adminRole, + }), + ); } else { - // remove super admin + // retirer rôle admin } setIsAdminModalOpened(false); }, [userSelected, adminModalType]); @@ -124,7 +145,13 @@ export default function UserInformations(props: IProps) { }), }); - const votes = await LiveVotes.getInstance().post(vote); + const liveVote = await LiveVotes.getInstance().post(vote); + + if (liveVote.appointment.votes?.length === 3) { + Toasts.getInstance().open({ + title: `Le titre de super-administrateur a été attribué à ${userSelected.contact?.first_name} ${userSelected.contact?.last_name} `, + }); + } await getUser(); setIsSuperAdminModalOpened(false); }, [userSelected, currentAppointment, superAdminModalType, getUser]); @@ -135,6 +162,22 @@ export default function UserInformations(props: IProps) { setIsSuperAdminChecked(userSelected.role?.name === "super-admin"); setIsAdminChecked(userSelected.role?.name === "admin" && !userSelected.office_role); }, [userSelected]); + + const userHasVoted = useCallback(() => { + if (!currentAppointment) return false; + const user = JwtService.getInstance().decodeJwt(); + return currentAppointment.votes?.find((vote) => vote.voter?.uid === user?.userId) !== undefined; + }, [currentAppointment]); + + const deleteMyVote = useCallback(async () => { + if (!currentAppointment) return; + const user = JwtService.getInstance().decodeJwt(); + const vote = currentAppointment.votes?.find((vote) => vote.voter?.uid === user?.userId); + if (!vote) return; + await Votes.getInstance().delete({ uid: vote.uid }); + await getUser(); + }, [currentAppointment, getUser]); + return (
@@ -207,14 +250,21 @@ export default function UserInformations(props: IProps) {
{currentAppointment.choice === EVote.NOMINATE - ? `Vous avez voté pour attribuer le titre de Super Admin. Il manque ${ + ? `Un ou des collaborateurs souhaitent attribuer le titre de Super Admin à ce collaborateur. Il manque ${ 3 - currentAppointment.votes?.length! } vote(s) pour que le collaborateur se voit attribuer le titre.` - : `Vous avez voté pour retirer le titre de Super Admin. Il manque ${ + : `Un ou des collaborateurs souhaitent retirer le titre de Super Admin à ce collaborateur. Il manque ${ 3 - currentAppointment.votes?.length! } vote(s) pour que le collaborateur se voit retirer le titre.`}
+ {userHasVoted() && ( +
+ +
+ )}
)}