diff --git a/package-lock.json b/package-lock.json index 459b2227cce39d19951c37da3eba4458035b75f7..269508a006a04983c49c570f73acc87423f2e5ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ }, "devDependencies": { "@svgr/webpack": "^8.1.0", + "@tailwindcss/forms": "^0.5.7", "eslint": "^8", "eslint-config-next": "14.2.3", "postcss": "^8", @@ -2813,6 +2814,18 @@ "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" } }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", + "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", + "dev": true, + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + } + }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -5836,6 +5849,15 @@ "node": ">=8.6" } }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/package.json b/package.json index f9e94e36ed36bfa864f43a911327d1743842b629..f52a15c2119037727944b3bb0740a1bd569872de 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ }, "devDependencies": { "@svgr/webpack": "^8.1.0", + "@tailwindcss/forms": "^0.5.7", "eslint": "^8", "eslint-config-next": "14.2.3", "postcss": "^8", diff --git a/src/app/(dashboard)/privilege/PrivilegesFilter.jsx b/src/app/(dashboard)/privilege/PrivilegesFilter.jsx index 306083f4772e2bb142a0606b921f2693ab3ef2b3..d251f0ec25a7bdee631202c022a730d0e4513a0a 100644 --- a/src/app/(dashboard)/privilege/PrivilegesFilter.jsx +++ b/src/app/(dashboard)/privilege/PrivilegesFilter.jsx @@ -19,7 +19,7 @@ const PrivilegesFilter = memo(function page({ setFilter, filter }) {
- diff --git a/src/app/(dashboard)/privilege/page.jsx b/src/app/(dashboard)/privilege/page.jsx index f7e796676219363d84f60122ce4bc01bdf8e059e..9871dcd85bb6fe8046516c70299611247719d960 100644 --- a/src/app/(dashboard)/privilege/page.jsx +++ b/src/app/(dashboard)/privilege/page.jsx @@ -36,7 +36,7 @@ const Privilege = () => {

Liste des habilitations

- diff --git a/src/app/(dashboard)/role/CreateRoleForm.jsx b/src/app/(dashboard)/role/CreateRoleForm.jsx index 3ba4a859863b9c1f5d662cd800fb10c3c48d5b10..2e5e4ce45f48e60d523d34ec97ae2ea056d8847e 100644 --- a/src/app/(dashboard)/role/CreateRoleForm.jsx +++ b/src/app/(dashboard)/role/CreateRoleForm.jsx @@ -2,13 +2,13 @@ import Loader from '@/components/Loader/Loader' import React, { useState, useRef, useEffect, useMemo } from 'react' import fetchRequest from '@/app/lib/fetchRequest' import { useNotification } from '@/context/NotificationContext' -import CancelIcon from "@/static/image/svg/cancel.svg" const CreateRoleForm = ({ appendRole, setIsOpen }) => { const [isLoading, setIsLoading] = useState(false) const [roleName, setRoleName] = useState("") const [privileges, setPrivileges] = useState(null) - const [selectedPrivileges, setSelectedPrivileges] = useState([]) + const [checkedValues, setCheckedValues] = useState([]); const { toggleNotification } = useNotification() + const [selectAll, setSelectAll] = useState(false); useEffect(() => { const getPrivileges = async () => { const { data, errors, isSuccess } = await fetchRequest("/privileges") @@ -35,12 +35,12 @@ const CreateRoleForm = ({ appendRole, setIsOpen }) => { setIsLoading(true) const { data, errors, isSuccess, status } = await fetchRequest("/roles/", { method: "POST", - body: JSON.stringify({ name: roleName, privileges: selectedPrivileges.map((element) => element.id) }) + body: JSON.stringify({ name: roleName, privileges: checkedValues }) }) if (isSuccess) { setIsLoading(false) inputRef.current.value = "" - setSelectedPrivileges([]) + setCheckedValues([]) setRoleName("") appendRole(data) toggleNotification({ @@ -93,46 +93,63 @@ const CreateRoleForm = ({ appendRole, setIsOpen }) => { console.log(errors) } } - const handlePrivilegeClick = (privilege) => { - if (selectedPrivileges.find((element) => element.id === privilege.id)) { - setSelectedPrivileges(selectedPrivileges.filter((element) => element.id !== privilege.id)) + + + const handleCheckboxChange = (event) => { + const { value, checked } = event.target; + if (value === "selectAll") { + setSelectAll(checked); + if (checked) { + setCheckedValues(privileges.map(element => element.id)); + } else { + setCheckedValues([]); + } } else { - setSelectedPrivileges([...selectedPrivileges, privilege]) + const updatedValues = checked + ? [...checkedValues, value] + : checkedValues.filter(val => val != value); + + setCheckedValues(updatedValues); + setSelectAll(updatedValues.length === privileges.length); } - } - const selectAll = () => { - if (privileges.every((element) => selectedPrivileges.find((priv) => priv.id === element.id))) - setSelectedPrivileges([]) - else setSelectedPrivileges(privileges) - } - var isAllSelected = useMemo(() => privileges ? privileges.every((element) => selectedPrivileges.find((priv) => priv.id === element.id)) : false, [selectedPrivileges, privileges]) + }; + return (
-
- setIsOpen(false)} className="h-8 w-8 cursor-pointer absolute top-2 right-2 fill-neutral-600" /> - {(privileges) ?
-

Ajout de Rôle

-
- +
+ {(privileges) ? +

Ajouter rôle

+
+
-
-
- -
{!isAllSelected ? "Sélectionner tout" : "désélectionner"}
+
+
+
-
- {privileges.length !== 0 ? privileges?.map((privilege) => { - const isSelected = selectedPrivileges.find((element) => element.id === privilege.id) !== undefined - return
handlePrivilegeClick(privilege)} key={privilege.id} className={`${!isSelected ? 'text-neutral-400 hover:border-neutral-400 hover:text-neutral-500 border-neutral-300 bg-neutral-100' : 'text-indigo-500 hover:border-indigo-500 hover:text-indigo-500 border-indigo-400 bg-indigo-100'} will-change-contents h-6 text-sm flex items-center justify-center duration-150 delay-75 cursor-pointer text-semibold leading-[0] border-2 py-0.5 rounded-full w-fit px-2`}>{privilege.name}
- }) :
-

Pas encore des habilitations

-
} +
+ + +
+
+ {privileges.length !== 0 + ? privileges?.map((privilege) => { + return
+ element == privilege.id) != undefined} type='checkbox' onChange={handleCheckboxChange} className='form-checkbox rounded-sm border-2 border-[#323232] focus:ring-0 focus:ring-transparent cursor-pointer h-4 w-4 text-[#323232]' name={"privilege_" + privilege.id} id={"privilege_" + privilege.id} /> + +
+ }) + :
+

Pas encore des habilitations

+
}
-
- +
:
} diff --git a/src/app/(dashboard)/role/RolesFilter.jsx b/src/app/(dashboard)/role/RolesFilter.jsx index 25fc2cdb4fc812581f4ba9188a88e559155d4658..59a3d7fe93c76ef4b7c8056e1b16fbe7ac0546f5 100644 --- a/src/app/(dashboard)/role/RolesFilter.jsx +++ b/src/app/(dashboard)/role/RolesFilter.jsx @@ -77,7 +77,7 @@ const RolesFilter = memo(function Page({ setFilter, filter }) {
- diff --git a/src/app/(dashboard)/role/UpdateRoleForm.jsx b/src/app/(dashboard)/role/UpdateRoleForm.jsx index 4b35eadf0d90ee4e0aa60d40c983f0542eebfde3..c52bd74e9a13cd2643d5ad51c834fc7352570b2b 100644 --- a/src/app/(dashboard)/role/UpdateRoleForm.jsx +++ b/src/app/(dashboard)/role/UpdateRoleForm.jsx @@ -1,17 +1,19 @@ import { useNotification } from '@/context/NotificationContext' -import React, { useState, useRef, useEffect, useMemo } from 'react' +import React, { useState, useRef, useEffect } from 'react' import fetchRequest from '@/app/lib/fetchRequest' import Loader from '@/components/Loader/Loader' -import CancelIcon from "@/static/image/svg/cancel.svg" import { isArray } from '../../lib/TypesHelper' const UpdateRoleForm = ({ setRoleToUpdate, setRoles, roles, privileges: rolePrivileges, name, id }) => { const { toggleNotification } = useNotification() const [loadingStatus, setLoadingStatus] = useState(false) const [roleName, setRoleName] = useState(name) const [privileges, setPrivileges] = useState(null) - const [selectedPrivileges, setSelectedPrivileges] = useState(isArray(rolePrivileges) ? rolePrivileges : []) + const [checkedValues, setCheckedValues] = useState(isArray(rolePrivileges) ? rolePrivileges.map(element => element.id) : []); + const [selectAll, setSelectAll] = useState(false); const inputRef = useRef(null) - console.log("les priv de role ", rolePrivileges) + useEffect(() => { + setSelectAll(isArray(checkedValues) && privileges ? checkedValues.length === privileges.length : false) + }, [privileges]) useEffect(() => { const getPrivileges = async () => { const { data, errors, isSuccess } = await fetchRequest("/privileges") @@ -34,9 +36,8 @@ const UpdateRoleForm = ({ setRoleToUpdate, setRoles, roles, privileges: rolePriv setLoadingStatus(true) const { isSuccess, errors, data, status } = await fetchRequest(`/roles/${id}/`, { method: "PATCH", - body: JSON.stringify({ name: roleName, privileges: selectedPrivileges.filter((element) => privileges.find((prvElement) => prvElement.id === element.id)).map((element) => element.id) }) + body: JSON.stringify({ name: roleName, privileges: checkedValues }) }) - console.log(data) setLoadingStatus(false) if (isSuccess) { setRoles((roles) => roles.map((element) => element.id === id ? data : element)) @@ -92,46 +93,60 @@ const UpdateRoleForm = ({ setRoleToUpdate, setRoles, roles, privileges: rolePriv const handleRoleNameChange = (event) => { setRoleName(event.target.value) } - const handlePrivilegeClick = (privilege) => { - if (selectedPrivileges.find((element) => element.id === privilege.id)) { - setSelectedPrivileges(selectedPrivileges.filter((element) => element.id !== privilege.id)) + const handleCheckboxChange = (event) => { + const { value, checked } = event.target; + if (value === "selectAll") { + setSelectAll(checked); + if (checked) { + setCheckedValues(privileges.map(element => element.id)); + } else { + setCheckedValues([]); + } } else { - setSelectedPrivileges([...selectedPrivileges, privilege]) + const updatedValues = checked + ? [...checkedValues, value] + : checkedValues.filter(val => val != value); + + setCheckedValues(updatedValues); + setSelectAll(updatedValues.length === privileges.length); } - } - const selectAll = () => { - if (privileges.every((element) => selectedPrivileges.find((priv) => priv.id === element.id))) - setSelectedPrivileges([]) - else setSelectedPrivileges(privileges) - } - var isAllSelected = useMemo(() => privileges ? privileges.every((element) => selectedPrivileges.find((priv) => priv.id === element.id)) : false, [selectedPrivileges, privileges]) + }; return (
-
- setRoleToUpdate(null)} className="h-8 w-8 cursor-pointer absolute top-2 right-2 fill-neutral-600" /> - {(privileges) ?
-

Modification de Rôle

-
+
+ {(privileges) ? +

Modifier rôle

+
-
-
- -
{!isAllSelected ? "Sélectionner tout" : "désélectionner"}
+
+
+
-
- {privileges.length !== 0 ? privileges?.map((privilege) => { - const isSelected = selectedPrivileges.find((element) => element.id === privilege.id) !== undefined - return
handlePrivilegeClick(privilege)} key={privilege.id} className={`${!isSelected ? 'text-neutral-400 hover:border-neutral-400 hover:text-neutral-500 border-neutral-300 bg-neutral-100' : 'text-indigo-500 hover:border-indigo-500 hover:text-indigo-500 border-indigo-400 bg-indigo-100'} will-change-contents h-6 text-sm flex items-center justify-center duration-150 delay-75 cursor-pointer text-semibold leading-[0] border-2 py-0.5 rounded-full w-fit px-2`}>{privilege.name}
- }) :
-

Pas encore des habilitations

-
} +
+ + +
+
+ {privileges.length !== 0 + ? privileges?.map((privilege) => { + return
+ element == privilege.id) != undefined} type='checkbox' onChange={handleCheckboxChange} className='form-checkbox rounded-sm border-2 border-[#323232] focus:ring-0 focus:ring-transparent cursor-pointer h-4 w-4 text-[#323232]' name={"privilege_" + privilege.id} id={"privilege_" + privilege.id} /> + +
+ }) + :
+

Pas encore des habilitations

+
}
-
- +
:
} diff --git a/src/app/(dashboard)/role/page.jsx b/src/app/(dashboard)/role/page.jsx index ef605d2fcec0715882d3950f05286bb9e117af89..36a38100057c79810d080933df0ac0378c21e711 100644 --- a/src/app/(dashboard)/role/page.jsx +++ b/src/app/(dashboard)/role/page.jsx @@ -50,7 +50,7 @@ const Role = () => { {roleToUpdate && }

Liste des Rôles

- diff --git a/src/app/(dashboard)/user/CreateUserForm.jsx b/src/app/(dashboard)/user/CreateUserForm.jsx index d4089e84c7325393c666a1bacc4135f6459361c0..a7d15dd8a235f754bb088cda37979c8e5a6e1d0e 100644 --- a/src/app/(dashboard)/user/CreateUserForm.jsx +++ b/src/app/(dashboard)/user/CreateUserForm.jsx @@ -159,33 +159,33 @@ const CreateUserForm = ({ setIsOpen, appendUser }) => { return (
- setIsOpen(false)} className="h-8 w-8 cursor-pointer md:absolute fixed top-2 right-2 fill-neutral-600" /> - {(roles && projects) ?
-

Ajout d'utilisateur

-
+ {(roles && projects) ? +

Ajouter utilisateur

+
- +

{errors.last_name}

- +

{errors.first_name}

-
- - +
+ +

{errors.email}

-
- +
+ +

-
+
- +
{projects.length !== 0 ? @@ -234,11 +234,12 @@ const CreateUserForm = ({ setIsOpen, appendUser }) => { :

Pas encore des projets

} +

-
+
- +
{roles.length !== 0 ? @@ -258,9 +259,12 @@ const CreateUserForm = ({ setIsOpen, appendUser }) => {
}
-
- +
:
} diff --git a/src/app/(dashboard)/user/UpdateUserForm.jsx b/src/app/(dashboard)/user/UpdateUserForm.jsx index ff36c1ed52db07dccc39ea4e249953bbca91c3d5..54ce18090737f65b8201bc09ad9f100298156ed6 100644 --- a/src/app/(dashboard)/user/UpdateUserForm.jsx +++ b/src/app/(dashboard)/user/UpdateUserForm.jsx @@ -134,29 +134,28 @@ const UpdateUserForm = ({ setUserToUpdate, userToUpdate, setUsers }) => { return (
- setUserToUpdate(null)} className="h-8 w-8 cursor-pointer md:absolute fixed top-2 right-2 fill-neutral-600" /> - {(roles && projects) ?
-

Modification d'utilisateur

-
+ {(roles && projects) ? +

Modifier d'utilisateur

+
- +

{errors.last_name}

- +

{errors.first_name}

-
- - +
+ +

{errors.email}

-
+
- +
{projects.length !== 0 ? @@ -206,11 +205,12 @@ const UpdateUserForm = ({ setUserToUpdate, userToUpdate, setUsers }) => { :

Pas encore des projets

} +

-
+
- +
{roles.length !== 0 ? @@ -230,9 +230,12 @@ const UpdateUserForm = ({ setUserToUpdate, userToUpdate, setUsers }) => {
}
-
- +
:
} diff --git a/src/app/(dashboard)/user/UsersFilter.jsx b/src/app/(dashboard)/user/UsersFilter.jsx index ac52b93c9d7a9528a8a5e086f6f606b7389c7949..c284fe734a390def8d4c8830e7d9e9c4f310bc35 100644 --- a/src/app/(dashboard)/user/UsersFilter.jsx +++ b/src/app/(dashboard)/user/UsersFilter.jsx @@ -31,7 +31,7 @@ const UsersFilter = memo(function page({ setFilter, filter }) {
- diff --git a/src/app/(dashboard)/user/page.jsx b/src/app/(dashboard)/user/page.jsx index 726ea0d09011af2575115c7f413516a8e64ed851..e1c84e4fec8aff86f38f5388c9963037cec96e49 100644 --- a/src/app/(dashboard)/user/page.jsx +++ b/src/app/(dashboard)/user/page.jsx @@ -62,7 +62,7 @@ const UserPage = () => { {userToUpdate && }

Liste des utilisateurs

- diff --git a/tailwind.config.js b/tailwind.config.js index bb1243c2439aa40da55d352ec149d19dba4b43b2..e19d38dec3956d02876f7f805070b340c9bbc890 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -52,5 +52,5 @@ module.exports = { lg: '976px', xl: '1440px', }, - plugins: [require('@tailwindcss/aspect-ratio')], + plugins: [require('@tailwindcss/aspect-ratio'), require('@tailwindcss/forms')({ strategy: "class" })], };