diff --git a/package-lock.json b/package-lock.json index 4632a1db..fbfd6fde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "eslint-config-next": "13.2.4", "form-data": "^4.0.0", "jwt-decode": "^3.1.2", - "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.58", + "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.66", "next": "13.2.4", "prettier": "^2.8.7", "react": "18.2.0", @@ -328,9 +328,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.1.tgz", - "integrity": "sha512-O7x6dMstWLn2ktjcoiNLDkAGG2EjveHL+Vvc+n0fXumkJYAcSqcVYKtwDU+hDZ0uDUsnUagSYaZrOLAYE8un1A==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -441,22 +441,22 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.1.tgz", - "integrity": "sha512-mIa1WmDmNr1LoupV1Rbxt9bTFKMbIn10RHG1bnZ/FJCkAYpuU/D4n+R+ttiycgcZNngU++zyh/OQeJblzbQPzg==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.2.tgz", + "integrity": "sha512-x+c/MgDL1t/IIy5lDbMlrDouFG5DYZbl3DP4dbbuhlpPFBnE9glYwmJEee/orVHQpOPwLxCAIWQs+2DKSaBVWQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" } }, "node_modules/@mui/material": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.1.tgz", - "integrity": "sha512-WtsgYuageTunLfxH3Ri+o1RuQTFImtRHxMcVNyD0Hhd2/znjW6KODNz0XfjvLRnNCAynBxZNiflcoIBW40h9PQ==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.2.tgz", + "integrity": "sha512-TgNR4/YRL11RifsnMWNhITNCkGJYVz20SCvVJBBoU5Y/KhUNSSJxjDpEB8VrnY+sUsV0NigLCkHZJglfsiS3Pw==", "dependencies": { "@babel/runtime": "^7.22.6", "@mui/base": "5.0.0-beta.8", - "@mui/core-downloads-tracker": "^5.14.1", + "@mui/core-downloads-tracker": "^5.14.2", "@mui/system": "^5.14.1", "@mui/types": "^7.2.4", "@mui/utils": "^5.14.1", @@ -2386,9 +2386,9 @@ } }, "node_modules/execa": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", - "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.1", @@ -3340,7 +3340,7 @@ } }, "node_modules/le-coffre-resources": { - "resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#5c506e8b49401240b8decee77f9b7e34694f490a", + "resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#e7916d516fe434c93ef13e765d8d63a7ce3c56b2", "license": "MIT", "dependencies": { "class-transformer": "^0.5.1", @@ -3361,9 +3361,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.10.37", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.37.tgz", - "integrity": "sha512-Z10PCaOCiAxbUxLyR31DNeeNugSVP6iv/m7UrSKS5JHziEMApJtgku4e9Q69pzzSC9LnQiM09sqsGf2ticZnMw==" + "version": "1.10.38", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.38.tgz", + "integrity": "sha512-4NjVXVUmpZ9Zsqq6FXa2+MKI+KAI3tOqA0pxXgXGluhpj4ge5didmbWJpMBqGB3AVGv1SnEtKdGTbxjSEG1kCQ==" }, "node_modules/lines-and-columns": { "version": "1.2.4", @@ -4847,9 +4847,9 @@ } }, "node_modules/tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" }, "node_modules/tsutils": { "version": "3.21.0", diff --git a/package.json b/package.json index 44aac912..a2f6f2f1 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "eslint-config-next": "13.2.4", "form-data": "^4.0.0", "jwt-decode": "^3.1.2", - "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.58", + "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.66", "next": "13.2.4", "prettier": "^2.8.7", "react": "18.2.0", diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes.ts b/src/front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes.ts new file mode 100644 index 00000000..394e1b93 --- /dev/null +++ b/src/front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes.ts @@ -0,0 +1,49 @@ +import { Appointment } from "le-coffre-resources/dist/SuperAdmin"; + +import BaseSuperAdmin from "../BaseSuperAdmin"; + +// TODO Type get query params -> Where + inclue + orderby +export interface IGetLiveVotessparams { + where?: {}; + include?: {}; + select?: {}; +} + +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"); + + private constructor() { + super(); + } + + public static getInstance() { + if (!this.instance) { + return new this(); + } else { + return this.instance; + } + } + + /** + * @description : Create a LiveVotes + */ + public async post(body: IPostLiveVotesParams): Promise { + const url = new URL(this.baseURl); + try { + 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/Assets/images/background.png b/src/front/Assets/images/background.png new file mode 100644 index 00000000..93e37c90 Binary files /dev/null and b/src/front/Assets/images/background.png differ diff --git a/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx b/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx index 857c731c..f9b5dcfa 100644 --- a/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx +++ b/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx @@ -37,6 +37,46 @@ export default class BurgerModal extends React.Component { text="Collaborateurs" routesActive={[Module.getInstance().get().modules.pages.Collaborators.props.path]} /> + + + + + +
diff --git a/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx b/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx index b871b131..72500903 100644 --- a/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx +++ b/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx @@ -58,7 +58,6 @@ export default class ProfileModal extends React.Component { Module.getInstance().get().modules.pages.Offices.pages.OfficesInformations.props.path, ]} /> -
diff --git a/src/front/Components/DesignSystem/Typography/classes.module.scss b/src/front/Components/DesignSystem/Typography/classes.module.scss index 186404af..0efa8539 100644 --- a/src/front/Components/DesignSystem/Typography/classes.module.scss +++ b/src/front/Components/DesignSystem/Typography/classes.module.scss @@ -3,6 +3,7 @@ .root { color: $black; + vertical-align: center; font-family: "Inter", sans-serif; &.H1-60 { font-style: normal; diff --git a/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/index.tsx b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/index.tsx index 97a2e073..85fd9422 100644 --- a/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/index.tsx +++ b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/index.tsx @@ -34,7 +34,7 @@ export default function DocumentTypeListContainer(props: IProps) { (block: IBlock) => { props.onCloseLeftSide && props.onCloseLeftSide(); console.log("Block selected :", block); - const redirectPath = Module.getInstance().get().modules.pages.DocumentTypes.pages.Edit.props.path; + const redirectPath = Module.getInstance().get().modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path; router.push(redirectPath.replace("[uid]", block.id)); }, [props, router], diff --git a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/classes.module.scss b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/classes.module.scss index d04c1ba8..745a1691 100644 --- a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/classes.module.scss +++ b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/classes.module.scss @@ -38,6 +38,7 @@ } .second-line { margin-top: 32px; + max-width: 426px; } .third-line { margin-top: 32px; diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/classes.module.scss b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/classes.module.scss index 72fe71da..b81e9055 100644 --- a/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/classes.module.scss +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/classes.module.scss @@ -4,7 +4,7 @@ .header { display: flex; justify-content: space-between; - align-items: flex-end; + align-items: flex-start; @media (max-width: $screen-l) { flex-direction: column; diff --git a/src/front/Components/Layouts/DeedTypes/index.tsx b/src/front/Components/Layouts/DeedTypes/index.tsx index e169d5c4..319c5bbd 100644 --- a/src/front/Components/Layouts/DeedTypes/index.tsx +++ b/src/front/Components/Layouts/DeedTypes/index.tsx @@ -15,7 +15,7 @@ export default class DeedTypes extends BasePage { Paramétrage des listes de pièces
- Sélectionnez une liste de pièces + Sélectionnez un type d'acte
diff --git a/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/index.tsx b/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/index.tsx index 439dbbf3..f1f3c3cc 100644 --- a/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/index.tsx +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/index.tsx @@ -5,6 +5,7 @@ import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField"; import TextField from "@Front/Components/DesignSystem/Form/TextField"; import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; import DefaultDocumentTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDocumentTypesDashboard"; +import Module from "@Front/Config/Module"; import { validateOrReject } from "class-validator"; import { DocumentType } from "le-coffre-resources/dist/Admin"; import { useRouter } from "next/router"; @@ -39,12 +40,19 @@ export default function DocumentTypesEdit() { }); await validateOrReject(documentToUpdate, { groups: ["updateDocumentType"] }); const documentTypeUpdated = await DocumentTypes.getInstance().put(documentTypeUid as string, documentToUpdate); - console.log(documentTypeUpdated); + router.push( + Module.getInstance() + .get() + .modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace( + "[uid]", + documentTypeUpdated.uid ?? "", + ), + ); } catch (e) { console.log(e); } }, - [documentTypeUid], + [documentTypeUid, router], ); return ( diff --git a/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/classes.module.scss b/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/classes.module.scss index 72fe71da..c471a213 100644 --- a/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/classes.module.scss +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/classes.module.scss @@ -1,91 +1,39 @@ @import "@Themes/constants.scss"; .root { - .header { + .document-infos { display: flex; + align-items: flex-start; justify-content: space-between; - align-items: flex-end; - - @media (max-width: $screen-l) { - flex-direction: column; - align-items: flex-start; - gap: 24px; - } - } - - .subtitle { - margin-top: 32px; - } - - .deed-type-container { - margin-top: 32px; - display: flex; - gap: 100px; - justify-content: space-between; + gap: 24px; padding: 24px; + margin-top: 32px; background-color: var(--grey-soft); - @media (max-width: $screen-l) { - gap: 80px; - } - - @media (max-width: $screen-m) { + .left { + display: flex; flex-direction: column; gap: 32px; - } - - .infos { - display: flex; - gap: 100px; - flex: 1; + justify-content: space-between; @media (max-width: $screen-l) { - flex-direction: column; + display: grid; + grid-template-columns: repeat(2, 1fr); gap: 32px; } - .box { - .box-title { - margin-bottom: 8px; - opacity: 0.4; - } + @media (max-width: $screen-s) { + grid-template-columns: repeat(1, 1fr); } - .middle-box { - flex: 1; + .document-infos-row { + display: flex; + flex-direction: column; + gap: 12px; } } - .pencil { - align-self: center; - - @media (max-width: $screen-m) { - align-self: flex-start; - } + .right { } } - - .documents-container { - margin-top: 32px; - padding: 32px 16px; - - border: 1px solid var(--grey); - - .container-title { - } - - .documents { - margin-top: 32px; - } - - .button-container { - margin-top: 32px; - } - } - - .delete-container { - display: flex; - justify-content: center; - margin-top: 32px; - } } diff --git a/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/index.tsx b/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/index.tsx index 8a000e92..2ada9aa3 100644 --- a/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/index.tsx +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/index.tsx @@ -1,89 +1,72 @@ -import ChevronIcon from "@Assets/Icons/chevron.svg"; import PenICon from "@Assets/Icons/pen.svg"; import DocumentTypes from "@Front/Api/LeCoffreApi/Admin/DocumentTypes/DocumentTypes"; -import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; -import Form from "@Front/Components/DesignSystem/Form"; import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography"; import DefaultDocumentTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDocumentTypesDashboard"; import Module from "@Front/Config/Module"; -import classNames from "classnames"; import { DocumentType } from "le-coffre-resources/dist/Admin"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/router"; -import { useCallback, useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import classes from "./classes.module.scss"; -type IProps = {}; -export default function DocumentTypesInformations(props: IProps) { +export default function DocumentTypesInformations() { const router = useRouter(); let { documentTypeUid } = router.query; - const [documentTypeSelected, setDocumentTypeSelected] = useState(null); + const [documentSelected, setDocumentSelected] = useState(null); useEffect(() => { - async function getDocumentType() { + async function getDocument() { if (!documentTypeUid) return; - const documentType = await DocumentTypes.getInstance().getByUid(documentTypeUid as string); - setDocumentTypeSelected(documentType); + const document = await DocumentTypes.getInstance().getByUid(documentTypeUid as string, { + _count: true, + }); + if (!document) return; + setDocumentSelected(document); } - getDocumentType(); + getDocument(); }, [documentTypeUid]); - const onSubmitHandler = useCallback(async (e: React.FormEvent | null, values: { [key: string]: string }) => {}, []); - return ( - +
-
- Paramétrage des listes de pièces - +
+ Paramétrage des documents
-
- {documentTypeSelected?.name} -
-
-
-
- - Nom du type d'acte +
+
+
+ + Nom du document - {documentTypeSelected?.name} + {documentSelected?.name}
-
- - Description +
+ + Description visible par les collaborateurs de l'office + {documentSelected?.private_description} +
+
+ + Description visible par les clients de l'office + + {documentSelected?.public_description}
-
+
- éditer le type d'acte + edit informations
-
-
-
- Documents paramétrés -
-
- -
-
-
-
- -
); diff --git a/src/front/Components/Layouts/Login/index.tsx b/src/front/Components/Layouts/Login/index.tsx index b4c10d64..977c4138 100644 --- a/src/front/Components/Layouts/Login/index.tsx +++ b/src/front/Components/Layouts/Login/index.tsx @@ -18,7 +18,7 @@ export default function Login() { const redirectUserOnConnection = useCallback(() => { async function getUser() { try { - await UserStore.instance.connect(process.env["NEXT_PUBLIC_ADMIN_ID"] as string); + await UserStore.instance.connect("jelkvelknvlkn"); await JwtService.getInstance().checkJwt(); router.push(Module.getInstance().get().modules.pages.Folder.props.path); } catch (e) { diff --git a/src/front/Components/Layouts/Offices/OfficeInformations/index.tsx b/src/front/Components/Layouts/Offices/OfficeInformations/index.tsx index 9c55a60e..56495989 100644 --- a/src/front/Components/Layouts/Offices/OfficeInformations/index.tsx +++ b/src/front/Components/Layouts/Offices/OfficeInformations/index.tsx @@ -47,31 +47,31 @@ export default function OfficeInformations(props: IProps) {
- + Nom {user.contact?.last_name}
- + Prénom {user.contact?.first_name}
- - E-mail pro + + E-mail {user.contact?.email}
- - Numéro de téléphone + + Téléphone {user.contact?.phone_number}
- + Rôle {user.office_role ? user.office_role?.name : user.role?.name} @@ -118,19 +118,19 @@ export default function OfficeInformations(props: IProps) {
- + Nom - + Prénom - - E-mail pro + + E-mail - - Numéro de téléphone + + Téléphone - + Rôle
@@ -155,19 +155,19 @@ export default function OfficeInformations(props: IProps) {
- + Nom - + Prénom - - E-mail pro + + E-mail - - Numéro de téléphone + + Téléphone - + Rôle
diff --git a/src/front/Components/Layouts/SelectFolder/classes.module.scss b/src/front/Components/Layouts/SelectFolder/classes.module.scss new file mode 100644 index 00000000..504eff91 --- /dev/null +++ b/src/front/Components/Layouts/SelectFolder/classes.module.scss @@ -0,0 +1,28 @@ +.root { + position: relative; + .background-container { + width: 100%; + height: 100%; + position: absolute; + z-index: -1; + + > img { + width: 100%; + object-fit: cover; + } + } + .select-folder-container { + max-width: 530px; + padding: 80px 72px; + + display: flex; + flex-direction: column; + justify-content: center; + gap: 48px; + margin: auto; + background-color: white; + .title { + text-align: center; + } + } +} diff --git a/src/front/Components/Layouts/SelectFolder/index.tsx b/src/front/Components/Layouts/SelectFolder/index.tsx new file mode 100644 index 00000000..8596700f --- /dev/null +++ b/src/front/Components/Layouts/SelectFolder/index.tsx @@ -0,0 +1,61 @@ +import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate"; +import classes from "./classes.module.scss"; +import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; +import BlockList, { IBlock } from "@Front/Components/DesignSystem/BlockList"; +import { OfficeFolder } from "le-coffre-resources/dist/Customer"; +import { useCallback, useEffect, useState } from "react"; +import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders"; +import { useRouter } from "next/router"; +import Module from "@Front/Config/Module"; +import BackgroundImage from "@Assets/images/background.png"; +import Image from "next/image"; + +export default function SelectFolder() { + const [folders, setFolders] = useState([]); + const router = useRouter(); + + useEffect(() => { + async function getFolders() { + const folders = await Folders.getInstance().get({}); + setFolders(folders.slice(0, 3)); + } + + getFolders(); + }, []); + + const handleSelectBlock = useCallback( + (block: IBlock) => { + router.push( + Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", block.id), + ); + }, + [router], + ); + + return ( + +
+
+ background +
+
+
+ Vos dossiers +
+
+ { + return { + id: folder.uid!, + name: folder.name!, + selected: false, + }; + })} + /> +
+
+
+
+ ); +} 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 a50d01a1..6a8c174d 100644 --- a/src/front/Components/Layouts/Users/UserInformations/index.tsx +++ b/src/front/Components/Layouts/Users/UserInformations/index.tsx @@ -1,13 +1,19 @@ 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 from "le-coffre-resources/dist/Notary"; +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"; import { useRouter } from "next/router"; import { useCallback, useEffect, useState } from "react"; @@ -30,6 +36,46 @@ export default function UserInformations(props: IProps) { const [isAdminChecked, setIsAdminChecked] = useState(false); const [isAdminModalOpened, setIsAdminModalOpened] = useState(false); + const [currentAppointment, setCurrentAppointment] = useState(null); + + /** When page change, get the user of the page */ + + const getUser = useCallback(async () => { + if (!userUid) return; + const user = await Users.getInstance().getByUid(userUid as string, { + q: { + contact: true, + office_role: true, + office_membership: true, + role: true, + appointment: { + include: { + votes: { + include: { + voter: true, + }, + }, + }, + }, + votes: true, + }, + }); + if (!user) return; + const roles = await OfficeRoles.getInstance().get(); + if (!roles) return; + setAvailableRoles(roles.map((role) => ({ value: role.uid, label: role.name }))); + setUserSelected(user); + }, [userUid]); + + useEffect(() => { + getUser(); + }, [getUser, userUid]); + + useEffect(() => { + if (!userSelected) return; + setCurrentAppointment(userSelected?.appointment?.find((appointment) => appointment.status === EAppointmentStatus.OPEN) ?? null); + }, [userSelected]); + /** Functions for the admin modal */ const openAdminModal = () => { setIsAdminModalOpened(true); @@ -49,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]); @@ -74,21 +134,27 @@ export default function UserInformations(props: IProps) { const handleSuperAdminModalAccepted = useCallback(async () => { if (!userSelected) return; - if (superAdminModalType === "add") { + + let vote = Vote.hydrate({ + appointment: Appointment.hydrate({ + uid: currentAppointment?.uid ?? undefined, + targeted_user: User.hydrate({ + uid: userSelected.uid, + }), + choice: superAdminModalType === "add" ? EVote.NOMINATE : EVote.DISMISS, + }), + }); + + const liveVote = await LiveVotes.getInstance().post(vote); + + if (liveVote.appointment.votes?.length === 3) { Toasts.getInstance().open({ - title: "Vote attribué", - text: "Vous avez voté pour attribuer le titre de Super Admin à " + userSelected.contact?.first_name, + title: `Le titre de super-administrateur a été attribué à ${userSelected.contact?.first_name} ${userSelected.contact?.last_name} `, }); - // add super admin - } else { - Toasts.getInstance().open({ - title: "Vote attribué", - text: "Vous avez voté pour supprimer le titre de Super Admin à " + userSelected.contact?.first_name, - }); - // remove super admin } + await getUser(); setIsSuperAdminModalOpened(false); - }, [userSelected, superAdminModalType]); + }, [userSelected, currentAppointment, superAdminModalType, getUser]); /** Reset switch state when userSelect change */ useEffect(() => { @@ -97,28 +163,20 @@ export default function UserInformations(props: IProps) { setIsAdminChecked(userSelected.role?.name === "admin" && !userSelected.office_role); }, [userSelected]); - /** When page change, get the user of the page */ - useEffect(() => { - async function getUser() { - if (!userUid) return; - const user = await Users.getInstance().getByUid(userUid as string, { - q: { - contact: true, - office_role: true, - office_membership: true, - role: true, - }, - }); - if (!user) return; + 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 roles = await OfficeRoles.getInstance().get(); - if (!roles) return; - setAvailableRoles(roles.map((role) => ({ value: role.uid, label: role.name }))); - setUserSelected(user); - } - - getUser(); - }, [userUid]); + 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 ( @@ -180,22 +238,36 @@ export default function UserInformations(props: IProps) {
-
-
- warning -
-
-
- 1/3 + {currentAppointment && ( +
+
+ warning
-
- - Vous avez voté pour attribuer le titre de Super Admin. Il manque 2 votes pour que le - collaborateur se voit attribuer le titre. - +
+
+ {currentAppointment.votes?.length}/3 +
+
+ + {currentAppointment.choice === EVote.NOMINATE + ? `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.` + : `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() && ( +
+ +
+ )}
-
+ )}
@@ -221,9 +293,15 @@ export default function UserInformations(props: IProps) { onClose={closeAdminModal} onAccept={handleAdminModalAccepted} closeBtn - header={`Souhaitez-vous ${adminModalType === "add" ? "ajouter" : "retirer"} ${ - userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name - } aux administrateurs de son office ?`} + header={ + adminModalType === "add" + ? `Souhaitez-vous nommer ${ + userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name + } administrateur de son office ?` + : `Souhaitez-vous retirer le rôle administrateur de son office à ${ + userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name + } ?` + } confirmText={adminModalType === "add" ? "Ajouter" : "Retirer"} cancelText={"Annuler"}>
diff --git a/src/front/Config/Module/development.json b/src/front/Config/Module/development.json index 3dde562b..187d64de 100644 --- a/src/front/Config/Module/development.json +++ b/src/front/Config/Module/development.json @@ -109,6 +109,13 @@ } } } + }, + "Select": { + "enabled": true, + "props": { + "path": "/folders/select", + "labelKey": "select_folder" + } } } }, diff --git a/src/front/Config/Module/preprod.json b/src/front/Config/Module/preprod.json index 3dde562b..187d64de 100644 --- a/src/front/Config/Module/preprod.json +++ b/src/front/Config/Module/preprod.json @@ -109,6 +109,13 @@ } } } + }, + "Select": { + "enabled": true, + "props": { + "path": "/folders/select", + "labelKey": "select_folder" + } } } }, diff --git a/src/front/Config/Module/production.json b/src/front/Config/Module/production.json index 3dde562b..187d64de 100644 --- a/src/front/Config/Module/production.json +++ b/src/front/Config/Module/production.json @@ -109,6 +109,13 @@ } } } + }, + "Select": { + "enabled": true, + "props": { + "path": "/folders/select", + "labelKey": "select_folder" + } } } }, diff --git a/src/front/Config/Module/staging.json b/src/front/Config/Module/staging.json index 3dde562b..187d64de 100644 --- a/src/front/Config/Module/staging.json +++ b/src/front/Config/Module/staging.json @@ -109,6 +109,13 @@ } } } + }, + "Select": { + "enabled": true, + "props": { + "path": "/folders/select", + "labelKey": "select_folder" + } } } }, diff --git a/src/pages/folders/select/index.tsx b/src/pages/folders/select/index.tsx new file mode 100644 index 00000000..450bbf84 --- /dev/null +++ b/src/pages/folders/select/index.tsx @@ -0,0 +1,5 @@ +import SelectFolder from "@Front/Components/Layouts/SelectFolder"; + +export default function Route() { + return ; +}